9 convalloc(char *sysuser)
13 c = mallocz(sizeof(Conv), 1);
19 c->sysuser = estrdup(sysuser);
21 c->rpcwait = chancreate(sizeof(void*), 0);
22 c->keywait = chancreate(sizeof(void*), 0);
23 strcpy(c->err, "protocol has not started");
34 nbsendp(c->rpcwait, 0);
56 nbsendp(c->rpcwait, 0);
74 for(p=conv; p && p->next!=c; p=p->next)
77 print("cannot find conv in list\n");
88 convgetrpc(Conv *c, int want)
95 if(c->rpc.op == RpcUnknown){
101 if(c->rpc.op == RpcUnknown)
104 if(want < 0 || c->rpc.op == want)
106 rpcrespond(c, "phase in state '%s' want '%s'", c->state, rpcname[want]);
108 return nil; /* not reached */
111 /* read until the done function tells us that's enough */
113 convreadfn(Conv *c, int (*done)(void*, int), char **ps)
120 r = convgetrpc(c, RpcWrite);
123 n = (*done)(r->data, r->count);
126 rpcrespond(c, "toosmall %d", n);
129 s = emalloc(r->count+1);
130 memmove(s, r->data, r->count);
138 * read until we get a non-zero write. assumes remote side
139 * knows something about the protocol (is not auth_proxy).
140 * the remote side typically won't bother with the zero-length
141 * write to find out the length -- the loop is there only so the
142 * test program can call auth_proxy on both sides of a pipe
143 * to play a conversation.
146 convreadm(Conv *c, char **ps)
152 r = convgetrpc(c, RpcWrite);
157 rpcrespond(c, "toosmall %d", AuthRpcMax);
159 s = emalloc(r->count+1);
160 memmove(s, r->data, r->count);
167 /* read exactly count bytes */
169 convread(Conv *c, void *data, int count)
174 r = convgetrpc(c, RpcWrite);
177 if(r->count == count)
180 rpcrespond(c, "toosmall %d", count);
182 rpcrespond(c, "error too much data; want %d got %d", count, r->count);
184 memmove(data, r->data, count);
189 /* write exactly count bytes */
191 convwrite(Conv *c, void *data, int count)
196 r = convgetrpc(c, RpcRead);
201 rpcrespondn(c, "ok", data, count);
205 /* print to the conversation */
207 convprint(Conv *c, char *fmt, ...)
214 s = vsmprint(fmt, arg);
218 ret = convwrite(c, s, strlen(s));
225 convneedkey(Conv *c, Attr *a)
228 * Piggyback key requests in the usual RPC channel.
229 * Wait for the next RPC and then send a key request
230 * in response. The keys get added out-of-band (via the
231 * ctl file), so assume the key has been added when the
232 * next request comes in.
234 if(convgetrpc(c, -1) == nil)
236 rpcrespond(c, "needkey %A", a);
237 if(convgetrpc(c, -1) == nil)
242 /* ask for a replacement for a bad key*/
244 convbadkey(Conv *c, Key *k, char *msg, Attr *a)
246 if(convgetrpc(c, -1) == nil)
248 rpcrespond(c, "badkey %A %N\n%s\n%A",
249 k->attr, k->privattr, msg, a);
250 if(convgetrpc(c, -1) == nil)