From b0052da73b49af8280ef00ec91dc7402d2fd6c70 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 5 Apr 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-04-05 --- bitsy/etherwavelan.c | 2 +- ip/devip.c | 42 +++++++-- ip/ip.h | 17 ++++ ip/iproute.c | 17 ++-- pc/etherwavelan.c | 13 ++- pc/trap.c | 13 +-- pc/vgas3.c | 13 ++- port/devtls.c | 220 ++++++++++++++++++++++++------------------- port/parse.c | 13 ++- port/portdat.h | 1 - 10 files changed, 220 insertions(+), 131 deletions(-) diff --git a/bitsy/etherwavelan.c b/bitsy/etherwavelan.c index d5f618c30ae7afd34b307fe680ae65a3fd2e89f1..01851a578bf1e5f9246128f9430e34830bad6a63 100644 --- a/bitsy/etherwavelan.c +++ b/bitsy/etherwavelan.c @@ -948,7 +948,7 @@ ifstat(Ether* ether, void* a, long n, ulong offset) ltv.len = 4; if (w_inltv(ctlr, <v)) print("#l%d: unable to read base station mac addr\n", ether->ctlrno); - l += snprint(p+l, READSTR-l, "Base station: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", + l += snprint(p+l, READSTR-l, "Base station: %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", ltv.addr[0], ltv.addr[1], ltv.addr[2], ltv.addr[3], ltv.addr[4], ltv.addr[5]); } PRINTSTAT("Net name: %s\n", ltv_inname(ctlr, WTyp_WantName)); diff --git a/ip/devip.c b/ip/devip.c index c664792297c12d5dc29dbd7cb17936691076385c..41869e94df281ac57f6fb0958f17015afb3c2ca5 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -66,6 +66,8 @@ ip3gen(Chan *c, int i, Dir *dp) char *p; cv = ipfs[c->dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)]; + if(cv->owner[0] == 0) + memmove(cv->owner, eve, NAMELEN); switch(i) { default: return -1; @@ -282,6 +284,24 @@ ipgetfs(int dev) return ipfs[dev]; } +IPaux* +newipaux(char *owner, char *tag) +{ + IPaux *a; + int n; + + a = smalloc(sizeof(*a)); + memmove(a->owner, owner, NAMELEN); + memset(a->tag, ' ', sizeof(a->tag)); + n = strlen(tag); + if(n > sizeof(a->tag)) + n = sizeof(a->tag); + memmove(a->tag, tag, n); + return a; +} + +#define ATTACHER(c) (((IPaux*)((c)->aux))->owner) + static Chan* ipattach(char* spec) { @@ -297,13 +317,19 @@ ipattach(char* spec) c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; c->dev = dev; + c->aux = newipaux(commonuser(), "none"); + return c; } static Chan* ipclone(Chan* c, Chan* nc) { - return devclone(c, nc); + IPaux *a = c->aux; + + nc = devclone(c, nc); + nc->aux = newipaux(a->owner, a->tag); + return nc; } static int @@ -359,7 +385,6 @@ ipopen(Chan* c, int omode) netlogopen(f); break; case Qiproute: - memmove(c->tag, "none", sizeof(c->tag)); break; case Qtopdir: case Qprotodir: @@ -380,7 +405,7 @@ ipopen(Chan* c, int omode) qunlock(p); nexterror(); } - cv = Fsprotoclone(p, commonuser()); + cv = Fsprotoclone(p, ATTACHER(c)); qunlock(p); poperror(); if(cv == nil) { @@ -402,7 +427,7 @@ ipopen(Chan* c, int omode) nexterror(); } if((perm & (cv->perm>>6)) != perm) { - if(strcmp(commonuser(), cv->owner) != 0) + if(strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); if((perm & cv->perm) != perm) error(Eperm); @@ -410,7 +435,7 @@ ipopen(Chan* c, int omode) } cv->inuse++; if(cv->inuse == 1){ - memmove(cv->owner, commonuser(), NAMELEN); + memmove(cv->owner, ATTACHER(c), NAMELEN); cv->perm = 0660; } qunlock(cv); @@ -420,7 +445,7 @@ ipopen(Chan* c, int omode) case Qlisten: cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)]; if((perm & (cv->perm>>6)) != perm) { - if(strcmp(commonuser(), cv->owner) != 0) + if(strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); if((perm & cv->perm) != perm) error(Eperm); @@ -450,7 +475,7 @@ ipopen(Chan* c, int omode) if(nc != nil){ cv->incall = nc->next; c->qid = (Qid){QID(PROTO(c->qid), nc->x, Qctl), 0}; - memmove(cv->owner, commonuser(), NAMELEN); + memmove(nc->owner, ATTACHER(c), NAMELEN); } qunlock(cv); @@ -499,7 +524,7 @@ ipwstat(Chan *c, char *dp) p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; - if(!iseve() && strcmp(commonuser(), cv->owner) != 0) + if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); if(d.uid[0]){ strncpy(cv->owner, d.uid, sizeof(cv->owner)); @@ -558,6 +583,7 @@ ipclose(Chan* c) if(c->flag & COPEN) closeconv(f->p[PROTO(c->qid)]->conv[CONV(c->qid)]); } + free(c->aux); } enum diff --git a/ip/ip.h b/ip/ip.h index 5c2a8f0df6b2445b5fd287d9c6465a0a2011e88e..32373503a75a8b26a8609a7122d91fe052ceaa8c 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -3,6 +3,7 @@ typedef struct Fs Fs; typedef union Hwaddr Hwaddr; typedef struct Ifcconv Ifcconv; typedef struct IP IP; +typedef struct IPaux IPaux; typedef struct Ipself Ipself; typedef struct Ipselftab Ipselftab; typedef struct Iplink Iplink; @@ -417,6 +418,22 @@ extern void routetype(int, char*); extern void ipwalkroutes(Fs*, Routewalk*); extern void convroute(Route*, uchar*, uchar*, uchar*, char*, int*); +/* + * devip.c + */ + +/* + * Hanging off every ip channel's ->aux is the following structure. + * It maintains the state used by devip and iproute. + */ +struct IPaux +{ + char owner[NAMELEN]; /* the user that did the attach */ + char tag[4]; +}; + +extern IPaux* newipaux(char*, char*); + /* * arp.c */ diff --git a/ip/iproute.c b/ip/iproute.c index 18e92b7e9225042b6edd701f880dc0983c4f4339..bdbe5e691b51085fd895705b75d6391dcc984f30 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -760,6 +760,7 @@ routewrite(Fs *f, Chan *c, char *p, int n) uchar addr[IPaddrlen]; uchar mask[IPaddrlen]; uchar gate[IPaddrlen]; + IPaux *a, *na; cb = parsecmd(p, n); if(waserror()){ @@ -797,8 +798,10 @@ routewrite(Fs *f, Chan *c, char *p, int n) parseipmask(mask, cb->f[2]); parseip(gate, cb->f[3]); tag = "none"; - if(c != nil) - tag = c->tag; + 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 @@ -807,12 +810,10 @@ routewrite(Fs *f, Chan *c, char *p, int n) if(cb->nf < 2) error(Ebadarg); - h = strlen(cb->f[1]); - if(h > sizeof(c->tag)) - h = sizeof(c->tag); - strncpy(c->tag, cb->f[1], h); - if(h < 4) - memset(c->tag+h, ' ', sizeof(c->tag)-h); + a = c->aux; + na = newipaux(a->owner, cb->f[1]); + c->aux = na; + free(a); } poperror(); diff --git a/pc/etherwavelan.c b/pc/etherwavelan.c index 1bf40286860a1eaaeb9947593760b3830a22117d..5a3db40593448ffb191cc3cc86c00f0fc7091f22 100644 --- a/pc/etherwavelan.c +++ b/pc/etherwavelan.c @@ -114,6 +114,7 @@ enum WTyp_Prom = 0xfc85, WTyp_Keys = 0xfcb0, WTyp_TxKey = 0xfcb1, + WTyp_StationID = 0xfd20, WTyp_CurName = 0xfd41, WTyp_BaseID = 0xfd42, // ID of the currently connected-to base station WTyp_CurTxRate = 0xfd44, // Current TX rate @@ -942,8 +943,14 @@ ifstat(Ether* ether, void* a, long n, ulong offset) if(i == 3) PRINTSTAT("SSID name: %s\n", ltv_inname(ctlr, WTyp_NetName)); else { + Wltv ltv; PRINTSTAT("Current name: %s\n", ltv_inname(ctlr, WTyp_CurName)); -// PRINTSTAT("Base station: %s\n", ltv_inname(ctlr, WTyp_BaseID)); + ltv.type = WTyp_BaseID; + ltv.len = 4; + if (w_inltv(ctlr, <v)) + print("#l%d: unable to read base station mac addr\n", ether->ctlrno); + l += snprint(p+l, READSTR-l, "Base station: %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", + ltv.addr[0], ltv.addr[1], ltv.addr[2], ltv.addr[3], ltv.addr[4], ltv.addr[5]); } PRINTSTAT("Net name: %s\n", ltv_inname(ctlr, WTyp_WantName)); PRINTSTAT("Node name: %s\n", ltv_inname(ctlr, WTyp_NodeName)); @@ -1192,8 +1199,8 @@ reset(Ether* ether) DEBUG("no wavelan found\n"); goto abort; } -// DEBUG("#l%d: port=0x%lx irq=%ld\n", -// ether->ctlrno, ether->port, ether->irq); + // DEBUG("#l%d: port=0x%lx irq=%ld\n", + // ether->ctlrno, ether->port, ether->irq); w_intdis(ctlr); if (w_cmd(ctlr,WCmdIni,0)){ diff --git a/pc/trap.c b/pc/trap.c index be0c7b9e880fb691a754e78b4a3d4e875208fbd8..81dbfc0b2db4ead8e9a7088b904f623703d301e9 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -390,15 +390,12 @@ _dumpstack(Ureg *ureg) v = *(ulong*)l; if(KTZERO < v && v < (ulong)&etext){ /* - * Pick off general CALL (0xE8) and CALL indirect - * through AX (0xFFD0). + * we could Pick off general CALL (((uchar*)v)[-5] == 0xE8) + * and CALL indirect through AX (((uchar*)v)[-2] == 0xFF && ((uchar*)v)[-2] == 0xD0), + * but this is too clever and misses faulting address. */ - p = (uchar*)v; - if(*(p-5) == 0xE8 - || (*(p-2) == 0xFF && *(p-1) == 0xD0)){ - print("%.8lux=%.8lux ", l, v); - i++; - } + print("%.8lux=%.8lux ", l, v); + i++; } if(i == 4){ i = 0; diff --git a/pc/vgas3.c b/pc/vgas3.c index 91d2e383ba7e83172a99be5ffd3c7c39a9f98faa..505e1231f1ddbacfc0ace61f9e1c1a1834e4a9a6 100644 --- a/pc/vgas3.c +++ b/pc/vgas3.c @@ -100,7 +100,18 @@ s3linear(VGAscr* scr, int* size, int* align) mmiosize = 0; mmiobase = 0; mmioname = nil; - if(p = pcimatch(nil, PCIS3, 0)){ + + /* + * S3 makes cards other than display controllers, so + * look for the first S3 display controller (device class 3) + * and not one of their sound cards. + */ + p = nil; + while(p = pcimatch(p, PCIS3, 0)){ + if(p->ccrb == 0x03) + break; + } + if(p != nil){ for(i=0; imem); i++){ if(p->mem[i].size >= *size && ((p->mem[i].bar & ~0x0F) & (*align-1)) == 0) diff --git a/port/devtls.c b/port/devtls.c index a1ed1fce2501fa82d0a75dfbdd4ac26d06256386..a0e9278af05578a27507a3f0e05797dc337b775c 100644 --- a/port/devtls.c +++ b/port/devtls.c @@ -15,6 +15,10 @@ typedef struct Secret Secret; enum { MaxRecLen = 1<<14, /* max payload length of a record layer message */ + MaxCipherRecLen = MaxRecLen + 2048, + +//ZZZ + Maxdstate = 64, RecHdrLen = 5, TLSVersion = 0x0301, SSL3Version = 0x0300, @@ -102,17 +106,20 @@ struct TlsRec void (*packMac)(Secret*, uchar*, uchar*, uchar*, uchar*, int, uchar*); /* input side -- protected by in.q */ - OneWay in; - Queue *handq; /* queue of handshake messages */ - Block *processed; /* next bunch of application data */ - Block *unprocessed; /* data read from c but not parsed into records */ + OneWay in; + Block *processed; /* next bunch of application data */ + Block *unprocessed; /* data read from c but not parsed into records */ + + Lock hqlock; + int hqref; + Queue *handq; /* queue of handshake messages */ /* output side */ - OneWay out; + OneWay out; /* protections */ - char user[NAMELEN]; - int perm; + char user[NAMELEN]; + int perm; }; typedef struct TlsErrs TlsErrs; @@ -183,13 +190,6 @@ static TlsRec** dstate; static char *encalgs; static char *hashalgs; -enum -{ -//ZZZ - Maxdmsg= 1<<16, - Maxdstate= 64 -}; - enum{ Qtopdir = 1, /* top level directory */ Qprotodir, @@ -351,27 +351,6 @@ tlsstat(Chan *c, char *db) devstat(c, db, 0, 0, tlsgen); } -static void -closedown(Chan *c, TlsRec *tr) -{ - lock(&dslock); - if(--tr->ref > 0) { - unlock(&dslock); - return; - } - dstate[CONV(c->qid)] = nil; - unlock(&dslock); - - tlshangup(tr); - if(tr->c) - cclose(tr->c); - free(tr->in.sec); - free(tr->in.new); - free(tr->out.sec); - free(tr->out.new); - free(tr); -} - static Chan* tlsopen(Chan *c, int omode) { @@ -421,29 +400,29 @@ tlsopen(Chan *c, int omode) dsnew(c, pp); else { if((perm & (tr->perm>>6)) != perm - && (strcmp(up->user, tr->user) != 0 - || (perm & tr->perm) != perm)) + && (strcmp(up->user, tr->user) != 0 + || (perm & tr->perm) != perm)) error(Eperm); - + if(t == Qhand){ + if(waserror()){ + unlock(&tr->hqlock); + nexterror(); + } + lock(&tr->hqlock); + if(tr->handq != nil) + error(Einuse); +//ZZZ what is the correct buffering here? + tr->handq = qopen(2 * MaxRecLen, 0, nil, nil); + if(tr->handq == nil) + error("can't allocate handshake queue"); + tr->hqref = 1; + unlock(&tr->hqlock); + poperror(); + } tr->ref++; } unlock(&dslock); poperror(); - if(t == Qhand){ - if(waserror()){ - qunlock(&tr->in.io); - closedown(c, tr); - } - qlock(&tr->in.io); - if(tr->handq != nil) - error(Einuse); -//ZZZ what is the correct buffering here? - tr->handq = qopen(2 * MaxRecLen, 0, nil, nil); - if(tr->handq == nil) - error("can't allocate handshake queue"); - qunlock(&tr->in.io); - poperror(); - } break; case Qencalgs: case Qhashalgs: @@ -471,10 +450,22 @@ tlswstat(Chan *c, char *dp) if(strcmp(tr->user, up->user) != 0) error(Eperm); +//ZZZ propagate chown to tr->datafd? memmove(tr->user, d.uid, NAMELEN); tr->perm = d.mode; } +static void +dechandq(TlsRec *tr) +{ + lock(&tr->hqlock); + if(--tr->hqref == 0 && tr->handq != nil){ + qfree(tr->handq); + tr->handq = nil; + } + unlock(&tr->hqlock); +} + static void tlsclose(Chan *c) { @@ -493,15 +484,25 @@ tlsclose(Chan *c) if(tr == nil) break; - if(t == Qhand){ - qlock(&tr->in.io); - if(tr->handq != nil){ - qfree(tr->handq); - tr->handq = nil; - } - qunlock(&tr->in.io); + if(t == Qhand) + dechandq(tr); + + lock(&dslock); + if(--tr->ref > 0) { + unlock(&dslock); + return; } - closedown(c, tr); + dstate[CONV(c->qid)] = nil; + unlock(&dslock); + + tlshangup(tr); + if(tr->c) + cclose(tr->c); + free(tr->in.sec); + free(tr->in.new); + free(tr->out.sec); + free(tr->out.new); + free(tr); break; } } @@ -524,7 +525,7 @@ ensure(TlsRec *s, Block **l, int n) } while(sofar < n){ - bl = devtab[s->c->type]->bread(s->c, Maxdmsg, 0); + bl = devtab[s->c->type]->bread(s->c, MaxCipherRecLen + RecHdrLen, 0); if(bl == 0) error(Ehungup); *l = bl; @@ -704,6 +705,7 @@ tlsrecread(TlsRec *tr) (*tr->packMac)(in->sec, in->sec->mackey, seq, header, p, len, hmac); if(memcmp(hmac, p+len, in->sec->maclen) != 0) rcvError(tr, EBadRecordMac, "record mac mismatch"); + b->wp -= in->sec->maclen; } qunlock(&in->seclock); poperror(); @@ -733,13 +735,19 @@ tlsrecread(TlsRec *tr) rcvError(tr, EDecodeError, "invalid alert"); if(p[0] == 1) { if(p[1] == ECloseNotify) { - rcvError(tr, ECloseNotify, "remote close"); tlsSetState(tr, SRemoteClosed); +// handclose(tr, "remote close"); + error("remote close"); } /* - * ignore EUserCancelled, it's meaningless - * need to handle ENoRenegotiation + * propate messages to handshaker + * EUserCancelled ENoRenegotiation +ZZZ better comment, better thoughts about this */ +// if(p[1] == ENoRenegotiation) +// handclose(tr, "no renegotiation"); +// if(p[1] == EUserCancelled) +// handclose(tr, "user cancelled"); } else { rcvAlert(tr, p[1]); } @@ -752,9 +760,13 @@ tlsrecread(TlsRec *tr) * if there isn't any handshaker, ignore the request, * but notify the other side we are doing so. */ + lock(&tr->hqlock); if(tr->handq != nil){ + tr->hqref++; + unlock(&tr->hqlock); qbwrite(tr->handq, b); b = nil; + dechandq(tr); }else if(tr->verset && tr->version != SSL3Version) sendAlert(tr, ENoRenegotiation); break; @@ -801,7 +813,7 @@ tlsbread(Chan *c, long n, ulong offset) } qlock(&tr->in.io); if(TYPE(c->qid) == Qdata){ -//ZZZ race setting state +//ZZZ race on state if(tr->state != SOpen) error(Ebadusefd); while(tr->processed == nil) @@ -812,7 +824,7 @@ tlsbread(Chan *c, long n, ulong offset) qunlock(&tr->in.io); poperror(); }else{ -//ZZZ race setting state +//ZZZ race on state while(tr->state == SHandshake && !qcanread(tr->handq)) tlsrecread(tr); qunlock(&tr->in.io); @@ -906,7 +918,7 @@ tlsrecwrite(TlsRec *tr, int type, Block *b) while(bb != nil){ //ZZZ race on state - if(tr->state != SHandshake && tr->state != SOpen) + if(tr->state != SHandshake && tr->state != SOpen && tr->state != SRemoteClosed) error(Ebadusefd); /* @@ -949,7 +961,7 @@ tlsrecwrite(TlsRec *tr, int type, Block *b) put64(seq, out->seq); out->seq++; (*tr->packMac)(out->sec, out->sec->mackey, seq, p, p + RecHdrLen, n, nb->wp); - b->wp += maclen; + nb->wp += maclen; n += maclen; /* update length */ @@ -958,6 +970,14 @@ tlsrecwrite(TlsRec *tr, int type, Block *b) /* encrypt */ rc4(&out->sec->rc4, p+RecHdrLen, n); } + if(type == RChangeCipherSpec){ + if(out->new == nil) + error("change cipher without a new cipher"); + free(out->sec); + out->sec = out->new; + out->new = nil; + out->seq = 0; + } qunlock(&out->seclock); poperror(); @@ -987,13 +1007,10 @@ tlsbwrite(Chan *c, Block *b, ulong offset) default: return devbwrite(c, b, offset); case Qhand: -//ZZZ race setting state -// if(tr->state != SHandshake && tr->state != SOpen) -// error(Ebadusefd); tlsrecwrite(tr, RHandshake, b); break; case Qdata: -//ZZZ race setting state +//ZZZ race on state if(tr->state != SOpen) error(Ebadusefd); tlsrecwrite(tr, RApplication, b); @@ -1172,7 +1189,14 @@ tlswrite(Chan *c, void *a, long n, vlong off) }else if(strcmp(cb->f[0], "opened") == 0){ if(cb->nf != 1) error("usage: opened"); - tlsSetState(tr, SOpen); + lock(&tr->statelk); + if(tr->state != SHandshake && tr->state != SOpen){ + unlock(&tr->statelk); +//ZZZ bad error message + error("can't set open state"); + } + tr->state = SOpen; + unlock(&tr->statelk); }else if(strcmp(cb->f[0], "alert") == 0){ if(cb->nf != 2) error("usage: alert n"); @@ -1195,24 +1219,19 @@ tlswrite(Chan *c, void *a, long n, vlong off) if(tr->out.new == nil) error("can't change cipher spec without setting secret"); - toc = tr->out.new; - tr->out.new = nil; - -//ZZZ minor race; worth fixing? qunlock(&tr->in.seclock); qunlock(&tr->out.seclock); poperror(); free(cb); poperror(); - + + /* + * the real work is done as the message is written + * so the stream is encrypted in sync. + */ b = allocb(1); *b->wp++ = 1; tlsrecwrite(tr, RChangeCipherSpec, b); - - qlock(&tr->out.seclock); - free(tr->out.sec); - tr->out.sec = toc; - qunlock(&tr->out.seclock); return n; }else if(strcmp(cb->f[0], "secret") == 0){ if(cb->nf != 5) @@ -1379,24 +1398,26 @@ sendAlert(TlsRec *tr, int err) tlsSetState(tr, SError); } +/* + * got a fatal alert message + */ static void rcvAlert(TlsRec *tr, int err) { char *s; - int i, fatal; + int i; s = "unknown error"; - fatal = 1; for(i=0; i < nelem(tlserrs); i++){ if(tlserrs[i].err == err){ s = tlserrs[i].msg; - fatal = tlserrs[i].fatal; break; } } //ZZZ need to kill session if fatal error - if(fatal) - tlsSetState(tr, SError); +// handclose(tr, err); + tlshangup(tr); + tlsSetState(tr, SError); error(s); } @@ -1424,21 +1445,24 @@ tlsSetState(TlsRec *tr, int newstate) /* hand up a digest connection */ static void -tlshangup(TlsRec *s) +tlshangup(TlsRec *tr) { Block *b; - qlock(&s->in.io); - for(b = s->processed; b; b = s->processed){ - s->processed = b->next; + qlock(&tr->in.io); + for(b = tr->processed; b; b = tr->processed){ + tr->processed = b->next; freeb(b); } - if(s->unprocessed != nil){ - freeb(s->unprocessed); - s->unprocessed = nil; + if(tr->unprocessed != nil){ + freeb(tr->unprocessed); + tr->unprocessed = nil; } - s->state = SClosed; - qunlock(&s->in.io); + qunlock(&tr->in.io); + + tlsrecwrite(tr, RAlert, ECloseNotify); + + tlsSetState(tr, SClosed); } static TlsRec* diff --git a/port/parse.c b/port/parse.c index 637bd314ae674e6e32c2844404efc1c18cf712ed..b4e3d2f92368a3e37113fdf0a8b4a8de0a1b3734 100644 --- a/port/parse.c +++ b/port/parse.c @@ -13,17 +13,24 @@ parsecmd(char *p, int n) { Cmdbuf *volatile cb; - cb = smalloc(sizeof(*cb)); + if(up != nil) + cb = smalloc(sizeof(*cb)); + else{ + cb = malloc(sizeof(*cb)); + if(cb == nil) + return nil; + } if(n > sizeof(cb->buf)-1) n = sizeof(cb->buf)-1; - if(waserror()){ + if(up != nil && waserror()){ free(cb); nexterror(); } memmove(cb->buf, p, n); - poperror(); + if(up != nil) + poperror(); if(n > 0 && cb->buf[n-1] == '\n') n--; diff --git a/port/portdat.h b/port/portdat.h index eeba31aec8eed3d6c59850df08de2fb285cb5f3c..a4c0a2e44fa37260d0fdd15d5b424ebdea90c994 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -159,7 +159,6 @@ struct Chan Qid pgrpid; /* for #p/notepg */ Mnt* mntptr; /* for devmnt */ ulong mid; /* for ns in devproc */ - char tag[4]; /* for iproute */ }; Chan* mchan; /* channel to mounted server */ Qid mqid; /* qid of root of mount point */