Example #1
0
/* ask for a key */
int
convneedkey(Conv *c, Attr *a)
{
	/*
	 * Piggyback key requests in the usual RPC channel.
	 * Wait for the next RPC and then send a key request
	 * in response.  The keys get added out-of-band (via the
	 * ctl file), so assume the key has been added when the
	 * next request comes in.
	 *
	 * The convgetrpc seems dodgy, because we might be in
	 * the middle of an rpc, and what about the one that comes
	 * in later?  It's all actually okay: convgetrpc is idempotent
	 * until rpcrespond is called, so if we're in the middle of an rpc,
	 * the first convgetrpc is a no-op, the rpcrespond sends back
	 * the needkey, and then the client repeats the rpc we're in
	 * the middle of.  Otherwise, if we're not in the middle of an
	 * rpc, the first convgetrpc waits for one, we respond needkey,
	 * and then the second convgetrpc waits for another.  Because
	 * there is no second response, eventually the caller will get
	 * around to asking for an rpc itself, at which point the already
	 * gotten rpc will be returned again.
	 */
	if(convgetrpc(c, -1) == nil)
		return -1;
	if(conv->proto!=nil && c->proto->keyprompt!=nil)
		a = addattrs(parseattr(c->proto->keyprompt), a);
	flog("convneedkey %A", a);
	rpcrespond(c, "needkey %A", a);
	if(convgetrpc(c, -1) == nil)
		return -1;
	flog("convneedkey returning");
	return 0;
}
Example #2
0
/*
	info ::= num | num '=' attr* defn
 */
static Type*
parseinfo(char *desc, char **pp)
{
	int n1, n2;
	Type *t;
	char *attr;

	n1 = n2 = 0;
	parsenum(desc, &n1, &n2, &desc);
	t = typebynum(n1, n2);
	if(*desc != '='){
		*pp = desc;
		return t;
	}
	desc++;
	if(fstack)
		fstack->list = mktl(t, fstack->list);
	while(parseattr(desc, &attr, &desc) >= 0){
		if(*attr == 's')
			t->xsizeof = atoi(attr+1)/8;
	}
	return parsedefn(desc, t, pp);
}