URI:
       tversion.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
       ---
       tversion.c (2181B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <venti.h>
            4 
            5 static char *okvers[] = {
            6         "04",
            7         "02",
            8         nil,
            9 };
           10 
           11 /*
           12 static char EBigString[] = "string too long";
           13 static char EBigPacket[] = "packet too long";
           14 static char ENullString[] = "missing string";
           15 */
           16 static char EBadVersion[] = "bad format in version string";
           17 
           18 static int
           19 vtreadversion(VtConn *z, char *q, char *v, int nv)
           20 {
           21         int n;
           22 
           23         for(;;){
           24                 if(nv <= 1){
           25                         werrstr("version too long");
           26                         return -1;
           27                 }
           28                 n = read(z->infd, v, 1);
           29                 if(n <= 0){
           30                         if(n == 0)
           31                                 werrstr("unexpected eof");
           32                         return -1;
           33                 }
           34                 if(*v == '\n'){
           35                         *v = 0;
           36                         break;
           37                 }
           38                 if((uchar)*v < ' ' || (uchar)*v > 0x7f || (*q && *v != *q)){
           39                         werrstr(EBadVersion);
           40                         return -1;
           41                 }
           42                 v++;
           43                 nv--;
           44                 if(*q)
           45                         q++;
           46         }
           47         return 0;
           48 }
           49 
           50 int
           51 vtversion(VtConn *z)
           52 {
           53         char buf[VtMaxStringSize], *p, *ep, *prefix, *pp;
           54         int i;
           55 
           56         qlock(&z->lk);
           57         if(z->state != VtStateAlloc){
           58                 werrstr("bad session state");
           59                 qunlock(&z->lk);
           60                 return -1;
           61         }
           62 
           63         qlock(&z->inlk);
           64         qlock(&z->outlk);
           65 
           66         p = buf;
           67         ep = buf + sizeof buf;
           68         prefix = "venti-";
           69         p = seprint(p, ep, "%s", prefix);
           70         p += strlen(p);
           71         for(i=0; okvers[i]; i++)
           72                 p = seprint(p, ep, "%s%s", i ? ":" : "", okvers[i]);
           73         p = seprint(p, ep, "-libventi\n");
           74         assert(p-buf < sizeof buf);
           75 
           76         if(write(z->outfd, buf, p-buf) != p-buf)
           77                 goto Err;
           78         vtdebug(z, "version string out: %s", buf);
           79 
           80         if(vtreadversion(z, prefix, buf, sizeof buf) < 0)
           81                 goto Err;
           82         vtdebug(z, "version string in: %s", buf);
           83 
           84         p = buf+strlen(prefix);
           85         for(; *p; p=pp){
           86                 if(*p == ':' || *p == '-')
           87                         p++;
           88                 pp = strpbrk(p, ":-");
           89                 if(pp == nil)
           90                         pp = p+strlen(p);
           91                 for(i=0; okvers[i]; i++)
           92                         if(strlen(okvers[i]) == pp-p && memcmp(okvers[i], p, pp-p) == 0){
           93                                 *pp = 0;
           94                                 z->version = vtstrdup(p);
           95                                 goto Okay;
           96                         }
           97         }
           98         werrstr("unable to negotiate version");
           99         goto Err;
          100 
          101 Okay:
          102         z->state = VtStateConnected;
          103         qunlock(&z->inlk);
          104         qunlock(&z->outlk);
          105         qunlock(&z->lk);
          106         return 0;
          107 
          108 Err:
          109         werrstr("vtversion: %r");
          110         if(z->infd >= 0)
          111                 close(z->infd);
          112         if(z->outfd >= 0 && z->outfd != z->infd)
          113                 close(z->outfd);
          114         z->infd = -1;
          115         z->outfd = -1;
          116         z->state = VtStateClosed;
          117         qunlock(&z->inlk);
          118         qunlock(&z->outlk);
          119         qunlock(&z->lk);
          120         return -1;
          121 }