From mboxrd@z Thu Jan 1 00:00:00 1970 From: Sam To: <9fans@cse.psu.edu> Subject: Re: [9fans] how to avoid a memset() optimization In-Reply-To: <53a650f30ccb9218b76af22fb32a1bc1@plan9.bell-labs.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=ISO-8859-1 Content-Transfer-Encoding: 8BIT Date: Mon, 6 Jan 2003 11:02:16 -0500 Topicbox-Message-UUID: 3c08faba-eacb-11e9-9e20-41e7f4b1d025 ooh, a challenge. Nothing pleases me more than proving myself wrong. be back in a few. ;) btw - i don't fear the goto. I use it a lot in small loop situations to avoid empty for loops and such. I'll play with this function and see what I find. ;) Cheers, Sam On Mon, 6 Jan 2003, Russ Cox wrote: > > you just need a marker to see how far you got. (I'm not even sure > > what the context of this message is, but every time i see the goto > > solution to this I have to say something). ;) > > the goto seems much clearer to me. > also easier to edit. what happens when > you have to lock A½? you have to rewrite > all your case statements! > > g% grep goto /sys/games/lib/fortunes |sed 1q > If you want to go somewhere, goto is the best way to get there. K Thompson > g% > > also you can't always write the code in your if-style, > but you can always use a goto. for example, you can't > rewrite this without goto (or at least, if you do, it ends > up a lot less clear or a lot more duplicated): > > static int > p9skclient(Conv *c) > { > char *user; > char cchal[CHALLEN]; > uchar secret[8]; > char buf[MAXAUTH]; > int speakfor, ret; > Attr *a; > Authenticator au; > Key *k; > Ticket t; > Ticketreq tr; > > ret = -1; > a = nil; > k = nil; > > /* p9sk1: send client challenge */ > if(c->proto == &p9sk1){ > c->state = "write challenge"; > memrandom(cchal, CHALLEN); > if(convwrite(c, cchal, CHALLEN) < 0) > goto out; > } > > /* read ticket request */ > c->state = "read tickreq"; > if(convread(c, buf, TICKREQLEN) < 0) > goto out; > convM2TR(buf, &tr); > > /* p9sk2: use server challenge as client challenge */ > if(c->proto == &p9sk2) > memmove(cchal, tr.chal, CHALLEN); > > /* > * find a key. > * > * if the user is the factotum owner, any key will do. > * if not, then if we have a speakfor key, > * we will only vouch for the user's local identity. > * > * this logic is duplicated in p9any.c > */ > user = strfindattr(c->attr, "user"); > a = delattr(copyattr(c->attr), "role"); > a = addattr(a, "proto=p9sk1"); > > if(strcmp(c->sysuser, owner) == 0){ > speakfor = 0; > a = addattr(a, "proto=p9sk1 user? dom=%q", tr.authdom); > }else if(user==nil || strcmp(c->sysuser, user)==0){ > speakfor = 1; > a = delattr(a, "user"); > a = addattr(a, "proto=p9sk1 user? dom=%q role=speakfor", tr.authdom); > }else{ > werrstr("will not authenticate for %q as %q", c->sysuser, user); > goto out; > } > > for(;;){ > c->state = "find key"; > k = keyfetch(c, "%A", a); > if(k == nil) > goto out; > > /* relay ticket request to auth server, get tickets */ > strcpy(tr.hostid, strfindattr(k->attr, "user")); > if(speakfor) > strcpy(tr.uid, c->sysuser); > else > strcpy(tr.uid, tr.hostid); > > c->state = "get tickets"; > if(gettickets(&tr, buf, k) < 0) > goto out; > > convM2T(buf, &t, k->priv); > if(t.num == AuthTc) > break; > > /* we don't agree with the auth server about the key; try again */ > c->state = "replace key"; > if((k = keyreplace(c, k, "key mismatch with auth server")) == nil){ > werrstr("key mismatch with auth server"); > goto out; > } > } > > /* send second ticket and authenticator to server */ > c->state = "write ticket+auth"; > memmove(buf, buf+TICKETLEN, TICKETLEN); > au.num = AuthAc; > memmove(au.chal, tr.chal, CHALLEN); > au.id = 0; > convA2M(&au, buf+TICKETLEN, t.key); > if(convwrite(c, buf, TICKETLEN+AUTHENTLEN) < 0) > goto out; > > /* read authenticator from server */ > c->state = "read auth"; > if(convread(c, buf, AUTHENTLEN) < 0) > goto out; > convM2A(buf, &au, t.key); > if(au.num != AuthAs || memcmp(au.chal, cchal, CHALLEN) != 0 || au.id != 0){ > werrstr("server lies through his teeth"); > goto out; > } > > /* success */ > c->attr = addcap(c->attr, c->sysuser, &t); > des56to64((uchar*)t.key, secret); > c->attr = addattr(c->attr, "secret=%.8H", secret); > ret = 0; > > out: > freeattr(a); > keyclose(k); > return ret; > } >