URI:
       tauth_rpc.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tauth_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 }