plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

confirm.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 }