125 lines · 2.4 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <auth.h>#include "authlocal.h" static struct {	char *verb;	int val;} tab[] = {	"ok",			ARok,	"done",		ARdone,	"error",		ARerror,	"needkey",	ARneedkey,	"badkey",		ARbadkey,	"phase",		ARphase,	"toosmall",	ARtoosmall,	"error",		ARerror,}; static intclassify(char *buf, uint n, AuthRpc *rpc){	int i, len; 	for(i=0; i<nelem(tab); i++){		len = strlen(tab[i].verb);		if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){			if(n==len){				rpc->narg = 0;				rpc->arg = "";			}else{				rpc->narg = n - (len+1);				rpc->arg = (char*)buf+len+1;			}			return tab[i].val;		}	}	werrstr("malformed rpc response: %s", buf);	return ARrpcfailure;} AuthRpc*auth_allocrpc(int afd){	AuthRpc *rpc; 	rpc = mallocz(sizeof(*rpc), 1);	if(rpc == nil)		return nil;	rpc->afd = afd;	return rpc;} voidauth_freerpc(AuthRpc *rpc){	free(rpc);} uintauth_rpc(AuthRpc *rpc, char *verb, void *a, int na){	int l, n, type;	char *f[4]; 	l = strlen(verb);	if(na+l+1 > AuthRpcMax){		werrstr("rpc too big");		return ARtoobig;	} 	memmove(rpc->obuf, verb, l);	rpc->obuf[l] = ' ';	memmove(rpc->obuf+l+1, a, na);	if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){		if(n >= 0)			werrstr("auth_rpc short write");		return ARrpcfailure;	} 	if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)		return ARrpcfailure;	rpc->ibuf[n] = '\0'; 	/*	 * Set error string for good default behavior.	 */	switch(type = classify(rpc->ibuf, n, rpc)){	default:		werrstr("unknown rpc type %d (bug in auth_rpc.c)", type);		break;	case ARok:		break;	case ARrpcfailure:		break;	case ARerror:		if(rpc->narg == 0)			werrstr("unspecified rpc error");		else			werrstr("%s", rpc->arg);		break;	case ARneedkey:		werrstr("needkey %s", rpc->arg);		break;	case ARbadkey:		if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2)			werrstr("badkey %s", rpc->arg);		else			werrstr("badkey %s", f[1]);		break;	case ARphase:		werrstr("phase error %s", rpc->arg);		break;	}	return type;}