confirm.c 3.5 KB

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