From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <53a650f30ccb9218b76af22fb32a1bc1@plan9.bell-labs.com> To: 9fans@cse.psu.edu Subject: Re: [9fans] how to avoid a memset() optimization From: "Russ Cox" In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit Date: Mon, 6 Jan 2003 10:49:14 -0500 Topicbox-Message-UUID: 3bc929bc-eacb-11e9-9e20-41e7f4b1d025 > 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; }