URI:
       tfcall.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
       ---
       tfcall.c (4206B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <venti.h>
            4 
            5 Packet*
            6 vtfcallpack(VtFcall *f)
            7 {
            8         uchar buf[10];
            9         Packet *p;
           10 
           11         p = packetalloc();
           12 
           13         buf[0] = f->msgtype;
           14         buf[1] = f->tag;
           15         packetappend(p, buf, 2);
           16 
           17         switch(f->msgtype){
           18         default:
           19                 werrstr("vtfcallpack: unknown packet type %d", f->msgtype);
           20                 goto Err;
           21 
           22         case VtRerror:
           23                 if(vtputstring(p, f->error) < 0)
           24                         goto Err;
           25                 break;
           26 
           27         case VtTping:
           28                 break;
           29 
           30         case VtRping:
           31                 break;
           32 
           33         case VtThello:
           34                 if(vtputstring(p, f->version) < 0
           35                 || vtputstring(p, f->uid) < 0)
           36                         goto Err;
           37                 buf[0] = f->strength;
           38                 buf[1] = f->ncrypto;
           39                 packetappend(p, buf, 2);
           40                 packetappend(p, f->crypto, f->ncrypto);
           41                 buf[0] = f->ncodec;
           42                 packetappend(p, buf, 1);
           43                 packetappend(p, f->codec, f->ncodec);
           44                 break;
           45 
           46         case VtRhello:
           47                 if(vtputstring(p, f->sid) < 0)
           48                         goto Err;
           49                 buf[0] = f->rcrypto;
           50                 buf[1] = f->rcodec;
           51                 packetappend(p, buf, 2);
           52                 break;
           53 
           54         case VtTgoodbye:
           55                 break;
           56 
           57         case VtTread:
           58                 packetappend(p, f->score, VtScoreSize);
           59                 buf[0] = vttodisktype(f->blocktype);
           60                 if(~buf[0] == 0)
           61                         goto Err;
           62                 buf[1] = 0;
           63                 if(f->count >= (1<<16)) {
           64                         buf[2] = f->count >> 24;
           65                         buf[3] = f->count >> 16;
           66                         buf[4] = f->count >> 8;
           67                         buf[5] = f->count;
           68                         packetappend(p, buf, 6);
           69                 } else {
           70                         buf[2] = f->count >> 8;
           71                         buf[3] = f->count;
           72                         packetappend(p, buf, 4);
           73                 }
           74                 break;
           75 
           76         case VtRread:
           77                 packetconcat(p, f->data);
           78                 break;
           79 
           80         case VtTwrite:
           81                 buf[0] = vttodisktype(f->blocktype);
           82                 if(~buf[0] == 0)
           83                         goto Err;
           84                 buf[1] = 0;
           85                 buf[2] = 0;
           86                 buf[3] = 0;
           87                 packetappend(p, buf, 4);
           88                 packetconcat(p, f->data);
           89                 break;
           90 
           91         case VtRwrite:
           92                 packetappend(p, f->score, VtScoreSize);
           93                 break;
           94 
           95         case VtTsync:
           96                 break;
           97 
           98         case VtRsync:
           99                 break;
          100         }
          101 
          102         return p;
          103 
          104 Err:
          105         packetfree(p);
          106         return nil;
          107 }
          108 
          109 int
          110 vtfcallunpack(VtFcall *f, Packet *p)
          111 {
          112         uchar buf[4];
          113 
          114         memset(f, 0, sizeof *f);
          115 
          116         if(packetconsume(p, buf, 2) < 0)
          117                 return -1;
          118 
          119         f->msgtype = buf[0];
          120         f->tag = buf[1];
          121 
          122         switch(f->msgtype){
          123         default:
          124                 werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype);
          125                 vtfcallclear(f);
          126                 return -1;
          127 
          128         case VtRerror:
          129                 if(vtgetstring(p, &f->error) < 0)
          130                         goto Err;
          131                 break;
          132 
          133         case VtTping:
          134                 break;
          135 
          136         case VtRping:
          137                 break;
          138 
          139         case VtThello:
          140                 if(vtgetstring(p, &f->version) < 0
          141                 || vtgetstring(p, &f->uid) < 0
          142                 || packetconsume(p, buf, 2) < 0)
          143                         goto Err;
          144                 f->strength = buf[0];
          145                 f->ncrypto = buf[1];
          146                 if(f->ncrypto){
          147                         f->crypto = vtmalloc(f->ncrypto);
          148                         if(packetconsume(p, buf, f->ncrypto) < 0)
          149                                 goto Err;
          150                 }
          151                 if(packetconsume(p, buf, 1) < 0)
          152                         goto Err;
          153                 f->ncodec = buf[0];
          154                 if(f->ncodec){
          155                         f->codec = vtmalloc(f->ncodec);
          156                         if(packetconsume(p, buf, f->ncodec) < 0)
          157                                 goto Err;
          158                 }
          159                 break;
          160 
          161         case VtRhello:
          162                 if(vtgetstring(p, &f->sid) < 0
          163                 || packetconsume(p, buf, 2) < 0)
          164                         goto Err;
          165                 f->rcrypto = buf[0];
          166                 f->rcodec = buf[1];
          167                 break;
          168 
          169         case VtTgoodbye:
          170                 break;
          171 
          172         case VtTread:
          173                 if(packetconsume(p, f->score, VtScoreSize) < 0
          174                 || packetconsume(p, buf, 2) < 0)
          175                         goto Err;
          176                 f->blocktype = vtfromdisktype(buf[0]);
          177                 if(~f->blocktype == 0)
          178                         goto Err;
          179                 switch(packetsize(p)) {
          180                 default:
          181                         goto Err;
          182                 case 2:
          183                         if(packetconsume(p, buf, 2) < 0)
          184                                 goto Err;
          185                         f->count = (buf[0] << 8) | buf[1];
          186                         break;
          187                 case 4:
          188                         if(packetconsume(p, buf, 4) < 0)
          189                                 goto Err;
          190                         f->count = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
          191                         break;
          192                 }
          193                 break;
          194 
          195         case VtRread:
          196                 f->data = packetalloc();
          197                 packetconcat(f->data, p);
          198                 break;
          199 
          200         case VtTwrite:
          201                 if(packetconsume(p, buf, 4) < 0)
          202                         goto Err;
          203                 f->blocktype = vtfromdisktype(buf[0]);
          204                 if(~f->blocktype == 0)
          205                         goto Err;
          206                 f->data = packetalloc();
          207                 packetconcat(f->data, p);
          208                 break;
          209 
          210         case VtRwrite:
          211                 if(packetconsume(p, f->score, VtScoreSize) < 0)
          212                         goto Err;
          213                 break;
          214 
          215         case VtTsync:
          216                 break;
          217 
          218         case VtRsync:
          219                 break;
          220         }
          221 
          222         if(packetsize(p) != 0)
          223                 goto Err;
          224 
          225         return 0;
          226 
          227 Err:
          228         werrstr("bad packet");
          229         vtfcallclear(f);
          230         return -1;
          231 }
          232 
          233 void
          234 vtfcallclear(VtFcall *f)
          235 {
          236         vtfree(f->error);
          237         f->error = nil;
          238         vtfree(f->uid);
          239         f->uid = nil;
          240         vtfree(f->sid);
          241         f->sid = nil;
          242         vtfree(f->version);
          243         f->version = nil;
          244         vtfree(f->crypto);
          245         f->crypto = nil;
          246         vtfree(f->codec);
          247         f->codec = nil;
          248         vtfree(f->auth);
          249         f->auth = nil;
          250         packetfree(f->data);
          251         f->data = nil;
          252 }