auth_rpc.c (2685B)
1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include <9pclient.h> 5 #include "authlocal.h" 6 7 static struct { 8 char *verb; 9 int val; 10 } tab[] = { 11 "ok", ARok, 12 "done", ARdone, 13 "error", ARerror, 14 "needkey", ARneedkey, 15 "badkey", ARbadkey, 16 "phase", ARphase, 17 "toosmall", ARtoosmall, 18 "error", ARerror, 19 }; 20 21 static long 22 rpcread(AuthRpc *rpc, void *buf, int buflen) 23 { 24 if (rpc->afd >= 0) 25 return read(rpc->afd, buf, buflen); 26 else 27 return fsread(rpc->afid, buf, buflen); 28 } 29 30 static long 31 rpcwrite(AuthRpc *rpc, void *buf, int buflen) 32 { 33 if (rpc->afd >= 0) 34 return write(rpc->afd, buf, buflen); 35 else 36 return fswrite(rpc->afid, buf, buflen); 37 } 38 39 static int 40 classify(char *buf, uint n, AuthRpc *rpc) 41 { 42 int i, len; 43 44 for(i=0; i<nelem(tab); i++){ 45 len = strlen(tab[i].verb); 46 if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){ 47 if(n==len){ 48 rpc->narg = 0; 49 rpc->arg = ""; 50 }else{ 51 rpc->narg = n - (len+1); 52 rpc->arg = (char*)buf+len+1; 53 } 54 return tab[i].val; 55 } 56 } 57 werrstr("malformed rpc response: %s", buf); 58 return ARrpcfailure; 59 } 60 61 AuthRpc* 62 auth_allocrpc(void) 63 { 64 AuthRpc *rpc; 65 66 rpc = mallocz(sizeof(*rpc), 1); 67 if(rpc == nil) 68 return nil; 69 rpc->afd = open("/mnt/factotum/rpc", ORDWR); 70 if(rpc->afd < 0){ 71 rpc->afid = nsopen("factotum", nil, "rpc", ORDWR); 72 if(rpc->afid == nil){ 73 free(rpc); 74 return nil; 75 } 76 } 77 return rpc; 78 } 79 80 void 81 auth_freerpc(AuthRpc *rpc) 82 { 83 if(rpc == nil) 84 return; 85 if(rpc->afd >= 0) 86 close(rpc->afd); 87 if(rpc->afid != nil) 88 fsclose(rpc->afid); 89 free(rpc); 90 } 91 92 uint 93 auth_rpc(AuthRpc *rpc, char *verb, void *a, int na) 94 { 95 int l, n, type; 96 char *f[4]; 97 98 l = strlen(verb); 99 if(na+l+1 > AuthRpcMax){ 100 werrstr("rpc too big"); 101 return ARtoobig; 102 } 103 104 memmove(rpc->obuf, verb, l); 105 rpc->obuf[l] = ' '; 106 memmove(rpc->obuf+l+1, a, na); 107 if((n=rpcwrite(rpc, rpc->obuf, l+1+na)) != l+1+na){ 108 if(n >= 0) 109 werrstr("auth_rpc short write"); 110 return ARrpcfailure; 111 } 112 113 if((n=rpcread(rpc, rpc->ibuf, AuthRpcMax)) < 0) 114 return ARrpcfailure; 115 rpc->ibuf[n] = '\0'; 116 117 /* 118 * Set error string for good default behavior. 119 */ 120 switch(type = classify(rpc->ibuf, n, rpc)){ 121 default: 122 werrstr("unknown rpc type %d (bug in auth_rpc.c)", type); 123 break; 124 case ARok: 125 break; 126 case ARrpcfailure: 127 break; 128 case ARerror: 129 if(rpc->narg == 0) 130 werrstr("unspecified rpc error"); 131 else 132 werrstr("%s", rpc->arg); 133 break; 134 case ARneedkey: 135 werrstr("needkey %s", rpc->arg); 136 break; 137 case ARbadkey: 138 if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2) 139 werrstr("badkey %s", rpc->arg); 140 else 141 werrstr("badkey %s", f[1]); 142 break; 143 case ARphase: 144 werrstr("phase error %s", rpc->arg); 145 break; 146 } 147 return type; 148 }