URI:
       tconfirm.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
       ---
       tconfirm.c (3542B)
       ---
            1 #include "std.h"
            2 #include "dat.h"
            3 
            4 Logbuf confbuf;
            5 
            6 void
            7 confirmread(Req *r)
            8 {
            9         lbread(&confbuf, r);
           10 }
           11 
           12 void
           13 confirmflush(Req *r)
           14 {
           15         lbflush(&confbuf, r);
           16 }
           17 
           18 int
           19 confirmwrite(char *s)
           20 {
           21         char *t, *ans;
           22         int allow;
           23         ulong tag;
           24         Attr *a;
           25         Conv *c;
           26 
           27         a = _parseattr(s);
           28         if(a == nil){
           29                 werrstr("bad attr");
           30                 return -1;
           31         }
           32         if((t = _strfindattr(a, "tag")) == nil){
           33                 flog("bad confirm write: no tag");
           34                 werrstr("no tag");
           35                 return -1;
           36         }
           37         tag = strtoul(t, 0, 0);
           38         if((ans = _strfindattr(a, "answer")) == nil){
           39                 flog("bad confirm write: no answer");
           40                 werrstr("no answer");
           41                 return -1;
           42         }
           43         if(strcmp(ans, "yes") == 0)
           44                 allow = 1;
           45         else if(strcmp(ans, "no") == 0)
           46                 allow = 0;
           47         else{
           48                 flog("bad confirm write: bad answer");
           49                 werrstr("bad answer");
           50                 return -1;
           51         }
           52         for(c=conv; c; c=c->next){
           53                 if(tag == c->tag){
           54                         nbsendul(c->keywait, allow);
           55                         break;
           56                 }
           57         }
           58         if(c == nil){
           59                 werrstr("tag not found");
           60                 return -1;
           61         }
           62         return 0;
           63 }
           64 
           65 int
           66 confirmkey(Conv *c, Key *k)
           67 {
           68         int ret;
           69 
           70         if(*confirminuse == 0)
           71                 return -1;
           72 
           73         lbappend(&confbuf, "confirm tag=%lud %A %N", c->tag, k->attr, k->privattr);
           74         flog("confirm %A %N", k->attr, k->privattr);
           75         c->state = "keyconfirm";
           76         ret = recvul(c->keywait);
           77         flog("confirm=%d %A %N", ret, k->attr, k->privattr);
           78         return ret;
           79 }
           80 
           81 Logbuf needkeybuf;
           82 
           83 void
           84 needkeyread(Req *r)
           85 {
           86         lbread(&needkeybuf, r);
           87 }
           88 
           89 void
           90 needkeyflush(Req *r)
           91 {
           92         lbflush(&needkeybuf, r);
           93 }
           94 
           95 int
           96 needkeywrite(char *s)
           97 {
           98         char *t;
           99         ulong tag;
          100         Attr *a;
          101         Conv *c;
          102 
          103         a = _parseattr(s);
          104         if(a == nil){
          105                 werrstr("empty write");
          106                 return -1;
          107         }
          108         if((t = _strfindattr(a, "tag")) == nil){
          109                 werrstr("no tag");
          110                 freeattr(a);
          111                 return -1;
          112         }
          113         tag = strtoul(t, 0, 0);
          114         for(c=conv; c; c=c->next)
          115                 if(c->tag == tag){
          116                         nbsendul(c->keywait, 0);
          117                         break;
          118                 }
          119         if(c == nil){
          120                 werrstr("tag not found");
          121                 freeattr(a);
          122                 return -1;
          123         }
          124         freeattr(a);
          125         return 0;
          126 }
          127 
          128 int
          129 needkey(Conv *c, Attr *a)
          130 {
          131         ulong u;
          132 
          133         if(c == nil || *needkeyinuse == 0)
          134                 return -1;
          135 
          136         lbappend(&needkeybuf, "needkey tag=%lud %A", c->tag, a);
          137         flog("needkey %A", a);
          138 
          139         // Note: This code used to "return nbrecvul(c->keywait)."
          140         // In Jan 2020 we changed nbrecvul to match Plan 9 and
          141         // the man page and return 0 on "no data available" instead
          142         // of -1. This new code with an explicit nbrecv preserves the
          143         // code's old semantics, distinguishing a sent 0 from "no data".
          144         // That said, this code seems to return -1 unconditionally:
          145         // the c->keywait channel is unbuffered, and the only sending
          146         // to it is done with an nbsendul, which won't block waiting for
          147         // a receiver. So there is no sender for nbrecv to find here.
          148         if(nbrecv(c->keywait, &u) < 0)
          149                 return -1;
          150         return u;
          151 }
          152 
          153 int
          154 badkey(Conv *c, Key *k, char *msg, Attr *a)
          155 {
          156         ulong u;
          157 
          158         if(c == nil || *needkeyinuse == 0)
          159                 return -1;
          160 
          161         lbappend(&needkeybuf, "badkey tag=%lud %A %N\n%s\n%A",
          162                 c->tag, k->attr, k->privattr, msg, a);
          163         flog("badkey %A / %N / %s / %A",
          164                 k->attr, k->privattr, msg, a);
          165 
          166         // Note: This code used to "return nbrecvul(c->keywait)."
          167         // In Jan 2020 we changed nbrecvul to match Plan 9 and
          168         // the man page and return 0 on "no data available" instead
          169         // of -1. This new code with an explicit nbrecv preserves the
          170         // code's old semantics, distinguishing a sent 0 from "no data".
          171         // That said, this code seems to return -1 unconditionally:
          172         // the c->keywait channel is unbuffered, and the only sending
          173         // to it is done with an nbsendul, which won't block waiting for
          174         // a receiver. So there is no sender for nbrecv to find here.
          175         if(nbrecv(c->keywait, &u) < 0)
          176                 return -1;
          177         return u;
          178 }