URI:
       tclient.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
       ---
       tclient.c (3366B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <venti.h>
            4 
            5 int ventidoublechecksha1 = 1;
            6 
            7 static int
            8 vtfcallrpc(VtConn *z, VtFcall *ou, VtFcall *in)
            9 {
           10         Packet *p;
           11 
           12         p = vtfcallpack(ou);
           13         if(p == nil)
           14                 return -1;
           15         if((p = _vtrpc(z, p, ou)) == nil)
           16                 return -1;
           17         if(vtfcallunpack(in, p) < 0){
           18                 packetfree(p);
           19                 return -1;
           20         }
           21         if(chattyventi)
           22                 fprint(2, "%s <- %F\n", argv0, in);
           23         if(in->msgtype == VtRerror){
           24                 werrstr(in->error);
           25                 vtfcallclear(in);
           26                 packetfree(p);
           27                 return -1;
           28         }
           29         if(in->msgtype != ou->msgtype+1){
           30                 werrstr("type mismatch: sent %c%d got %c%d",
           31                         "TR"[ou->msgtype&1], ou->msgtype>>1,
           32                         "TR"[in->msgtype&1], in->msgtype>>1);
           33                 vtfcallclear(in);
           34                 packetfree(p);
           35                 return -1;
           36         }
           37         packetfree(p);
           38         return 0;
           39 }
           40 
           41 int
           42 vthello(VtConn *z)
           43 {
           44         VtFcall tx, rx;
           45 
           46         memset(&tx, 0, sizeof tx);
           47         tx.msgtype = VtThello;
           48         tx.version = z->version;
           49         tx.uid = z->uid;
           50         if(tx.uid == nil)
           51                 tx.uid = "anonymous";
           52         if(vtfcallrpc(z, &tx, &rx) < 0)
           53                 return -1;
           54         z->sid = rx.sid;
           55         rx.sid = 0;
           56         vtfcallclear(&rx);
           57         return 0;
           58 }
           59 
           60 Packet*
           61 vtreadpacket(VtConn *z, uchar score[VtScoreSize], uint type, int n)
           62 {
           63         VtFcall tx, rx;
           64 
           65         if(memcmp(score, vtzeroscore, VtScoreSize) == 0)
           66                 return packetalloc();
           67 
           68         if(z == nil){
           69                 werrstr("not connected");
           70                 return nil;
           71         }
           72 
           73         if(z->version[1] == '2' && n >= (1<<16)) {
           74                 werrstr("read count too large for protocol");
           75                 return nil;
           76         }
           77         memset(&tx, 0, sizeof tx);
           78         tx.msgtype = VtTread;
           79         tx.blocktype = type;
           80         tx.count = n;
           81         memmove(tx.score, score, VtScoreSize);
           82         if(vtfcallrpc(z, &tx, &rx) < 0)
           83                 return nil;
           84         if(packetsize(rx.data) > n){
           85                 werrstr("read returned too much data");
           86                 packetfree(rx.data);
           87                 return nil;
           88         }
           89         if(ventidoublechecksha1){
           90                 packetsha1(rx.data, tx.score);
           91                 if(memcmp(score, tx.score, VtScoreSize) != 0){
           92                         werrstr("read asked for %V got %V", score, tx.score);
           93                         packetfree(rx.data);
           94                         return nil;
           95                 }
           96         }
           97         return rx.data;
           98 }
           99 
          100 int
          101 vtread(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
          102 {
          103         int nn;
          104         Packet *p;
          105 
          106         if((p = vtreadpacket(z, score, type, n)) == nil)
          107                 return -1;
          108         nn = packetsize(p);
          109         if(packetconsume(p, buf, nn) < 0)
          110                 abort();
          111         packetfree(p);
          112         return nn;
          113 }
          114 
          115 int
          116 vtwritepacket(VtConn *z, uchar score[VtScoreSize], uint type, Packet *p)
          117 {
          118         VtFcall tx, rx;
          119 
          120         if(packetsize(p) == 0){
          121                 memmove(score, vtzeroscore, VtScoreSize);
          122                 return 0;
          123         }
          124         tx.msgtype = VtTwrite;
          125         tx.blocktype = type;
          126         tx.data = p;
          127         if(ventidoublechecksha1)
          128                 packetsha1(p, score);
          129         if(vtfcallrpc(z, &tx, &rx) < 0)
          130                 return -1;
          131         if(ventidoublechecksha1){
          132                 if(memcmp(score, rx.score, VtScoreSize) != 0){
          133                         werrstr("sha1 hash mismatch: want %V got %V", score, rx.score);
          134                         return -1;
          135                 }
          136         }else
          137                 memmove(score, rx.score, VtScoreSize);
          138         return 0;
          139 }
          140 
          141 int
          142 vtwrite(VtConn *z, uchar score[VtScoreSize], uint type, uchar *buf, int n)
          143 {
          144         Packet *p;
          145         int nn;
          146 
          147         p = packetforeign(buf, n, 0, nil);
          148         nn = vtwritepacket(z, score, type, p);
          149         packetfree(p);
          150         return nn;
          151 }
          152 
          153 int
          154 vtsync(VtConn *z)
          155 {
          156         VtFcall tx, rx;
          157 
          158         tx.msgtype = VtTsync;
          159         return vtfcallrpc(z, &tx, &rx);
          160 }
          161 
          162 int
          163 vtping(VtConn *z)
          164 {
          165         VtFcall tx, rx;
          166 
          167         tx.msgtype = VtTping;
          168         return vtfcallrpc(z, &tx, &rx);
          169 }
          170 
          171 int
          172 vtconnect(VtConn *z)
          173 {
          174         if(vtversion(z) < 0)
          175                 return -1;
          176         if(vthello(z) < 0)
          177                 return -1;
          178         return 0;
          179 }
          180 
          181 int
          182 vtgoodbye(VtConn *z)
          183 {
          184         VtFcall tx, rx;
          185 
          186         tx.msgtype = VtTgoodbye;
          187         vtfcallrpc(z, &tx, &rx);        /* always fails: no VtRgoodbye */
          188         return 0;
          189 }