1 #include "dat.h"
2
3 Logbuf confbuf;
4
5 Req *cusewait; /* requests waiting for confirmation */
6 Req **cuselast = &cusewait;
7
8 void
confirmread(Req * r)9 confirmread(Req *r)
10 {
11 logbufread(&confbuf, r);
12 }
13
14 void
confirmflush(Req * r)15 confirmflush(Req *r)
16 {
17 Req **l;
18
19 for(l=&cusewait; *l; l=&(*l)->aux){
20 if(*l == r){
21 *l = r->aux;
22 if(r->aux == nil)
23 cuselast = l;
24 closereq(r);
25 break;
26 }
27 }
28 logbufflush(&confbuf, r);
29 }
30
31 static int
hastag(Fsstate * fss,int tag,int * tagoff)32 hastag(Fsstate *fss, int tag, int *tagoff)
33 {
34 int i;
35
36 for(i=0; i<fss->nconf; i++)
37 if(fss->conf[i].tag == tag){
38 *tagoff = i;
39 return 1;
40 }
41 return 0;
42 }
43
44 int
confirmwrite(char * s)45 confirmwrite(char *s)
46 {
47 char *t, *ans;
48 int allow, tagoff;
49 ulong tag;
50 Attr *a;
51 Fsstate *fss;
52 Req *r, **l;
53
54 a = _parseattr(s);
55 if(a == nil){
56 werrstr("empty write");
57 return -1;
58 }
59 if((t = _strfindattr(a, "tag")) == nil){
60 werrstr("no tag");
61 return -1;
62 }
63 tag = strtoul(t, 0, 0);
64 if((ans = _strfindattr(a, "answer")) == nil){
65 werrstr("no answer");
66 return -1;
67 }
68 if(strcmp(ans, "yes") == 0)
69 allow = 1;
70 else if(strcmp(ans, "no") == 0)
71 allow = 0;
72 else{
73 werrstr("bad answer");
74 return -1;
75 }
76 r = nil;
77 tagoff = -1;
78 for(l=&cusewait; *l; l=&(*l)->aux){
79 r = *l;
80 if(hastag(r->fid->aux, tag, &tagoff)){
81 *l = r->aux;
82 if(r->aux == nil)
83 cuselast = l;
84 break;
85 }
86 }
87 if(r == nil || tagoff == -1){
88 werrstr("tag not found");
89 return -1;
90 }
91 fss = r->fid->aux;
92 fss->conf[tagoff].canuse = allow;
93 rpcread(r);
94 return 0;
95 }
96
97 void
confirmqueue(Req * r,Fsstate * fss)98 confirmqueue(Req *r, Fsstate *fss)
99 {
100 int i, n;
101 char msg[1024];
102
103 if(*confirminuse == 0){
104 respond(r, "confirm is closed");
105 return;
106 }
107
108 n = 0;
109 for(i=0; i<fss->nconf; i++)
110 if(fss->conf[i].canuse == -1){
111 n++;
112 snprint(msg, sizeof msg, "confirm tag=%lud %A", fss->conf[i].tag, fss->conf[i].key->attr);
113 logbufappend(&confbuf, msg);
114 }
115 if(n == 0){
116 respond(r, "no confirmations to wait for (bug)");
117 return;
118 }
119 *cuselast = r;
120 r->aux = nil;
121 cuselast = &r->aux;
122 }
123
124 /* Yes, I am unhappy that the code below is a copy of the code above. */
125
126 Logbuf needkeybuf;
127 Req *needwait; /* requests that need keys */
128 Req **needlast = &needwait;
129
130 void
needkeyread(Req * r)131 needkeyread(Req *r)
132 {
133 logbufread(&needkeybuf, r);
134 }
135
136 void
needkeyflush(Req * r)137 needkeyflush(Req *r)
138 {
139 Req **l;
140
141 for(l=&needwait; *l; l=&(*l)->aux){
142 if(*l == r){
143 *l = r->aux;
144 if(r->aux == nil)
145 needlast = l;
146 closereq(r);
147 break;
148 }
149 }
150 logbufflush(&needkeybuf, r);
151 }
152
153 int
needkeywrite(char * s)154 needkeywrite(char *s)
155 {
156 char *t;
157 ulong tag;
158 Attr *a;
159 Req *r, **l;
160
161 a = _parseattr(s);
162 if(a == nil){
163 werrstr("empty write");
164 return -1;
165 }
166 if((t = _strfindattr(a, "tag")) == nil){
167 werrstr("no tag");
168 return -1;
169 }
170 tag = strtoul(t, 0, 0);
171 r = nil;
172 for(l=&needwait; *l; l=&(*l)->aux){
173 r = *l;
174 if(r->tag == tag){
175 *l = r->aux;
176 if(r->aux == nil)
177 needlast = l;
178 break;
179 }
180 }
181 if(r == nil){
182 werrstr("tag not found");
183 return -1;
184 }
185 rpcread(r);
186 return 0;
187 }
188
189 int
needkeyqueue(Req * r,Fsstate * fss)190 needkeyqueue(Req *r, Fsstate *fss)
191 {
192 char msg[1024];
193
194 if(*needkeyinuse == 0)
195 return -1;
196
197 snprint(msg, sizeof msg, "needkey tag=%lud %s", r->tag, fss->keyinfo);
198 logbufappend(&needkeybuf, msg);
199 *needlast = r;
200 r->aux = nil;
201 needlast = &r->aux;
202 return 0;
203 }
204
205