fcall.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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 <u.h>
  10. #include <libc.h>
  11. #include <venti.h>
  12. Packet*
  13. vtfcallpack(VtFcall *f)
  14. {
  15. uint8_t buf[4];
  16. Packet *p;
  17. p = packetalloc();
  18. buf[0] = f->msgtype;
  19. buf[1] = f->tag;
  20. packetappend(p, buf, 2);
  21. switch(f->msgtype){
  22. default:
  23. werrstr("vtfcallpack: unknown packet type %d", f->msgtype);
  24. goto Err;
  25. case VtRerror:
  26. if(vtputstring(p, f->error) < 0)
  27. goto Err;
  28. break;
  29. case VtTping:
  30. break;
  31. case VtRping:
  32. break;
  33. case VtThello:
  34. if(vtputstring(p, f->version) < 0
  35. || vtputstring(p, f->uid) < 0)
  36. goto Err;
  37. buf[0] = f->strength;
  38. buf[1] = f->ncrypto;
  39. packetappend(p, buf, 2);
  40. packetappend(p, f->crypto, f->ncrypto);
  41. buf[0] = f->ncodec;
  42. packetappend(p, buf, 1);
  43. packetappend(p, f->codec, f->ncodec);
  44. break;
  45. case VtRhello:
  46. if(vtputstring(p, f->sid) < 0)
  47. goto Err;
  48. buf[0] = f->rcrypto;
  49. buf[1] = f->rcodec;
  50. packetappend(p, buf, 2);
  51. break;
  52. case VtTgoodbye:
  53. break;
  54. case VtTread:
  55. packetappend(p, f->score, VtScoreSize);
  56. buf[0] = vttodisktype(f->blocktype);
  57. if(~buf[0] == 0)
  58. goto Err;
  59. buf[1] = 0;
  60. buf[2] = f->count >> 8;
  61. buf[3] = f->count;
  62. packetappend(p, buf, 4);
  63. break;
  64. case VtRread:
  65. packetconcat(p, f->data);
  66. break;
  67. case VtTwrite:
  68. buf[0] = vttodisktype(f->blocktype);
  69. if(~buf[0] == 0)
  70. goto Err;
  71. buf[1] = 0;
  72. buf[2] = 0;
  73. buf[3] = 0;
  74. packetappend(p, buf, 4);
  75. packetconcat(p, f->data);
  76. break;
  77. case VtRwrite:
  78. packetappend(p, f->score, VtScoreSize);
  79. break;
  80. case VtTsync:
  81. break;
  82. case VtRsync:
  83. break;
  84. }
  85. return p;
  86. Err:
  87. packetfree(p);
  88. return nil;
  89. }
  90. int
  91. vtfcallunpack(VtFcall *f, Packet *p)
  92. {
  93. uint8_t buf[4];
  94. memset(f, 0, sizeof *f);
  95. if(packetconsume(p, buf, 2) < 0)
  96. return -1;
  97. f->msgtype = buf[0];
  98. f->tag = buf[1];
  99. switch(f->msgtype){
  100. default:
  101. werrstr("vtfcallunpack: unknown bad packet type %d", f->msgtype);
  102. vtfcallclear(f);
  103. return -1;
  104. case VtRerror:
  105. if(vtgetstring(p, &f->error) < 0)
  106. goto Err;
  107. break;
  108. case VtTping:
  109. break;
  110. case VtRping:
  111. break;
  112. case VtThello:
  113. if(vtgetstring(p, &f->version) < 0
  114. || vtgetstring(p, &f->uid) < 0
  115. || packetconsume(p, buf, 2) < 0)
  116. goto Err;
  117. f->strength = buf[0];
  118. f->ncrypto = buf[1];
  119. if(f->ncrypto){
  120. f->crypto = vtmalloc(f->ncrypto);
  121. if(packetconsume(p, buf, f->ncrypto) < 0)
  122. goto Err;
  123. }
  124. if(packetconsume(p, buf, 1) < 0)
  125. goto Err;
  126. f->ncodec = buf[0];
  127. if(f->ncodec){
  128. f->codec = vtmalloc(f->ncodec);
  129. if(packetconsume(p, buf, f->ncodec) < 0)
  130. goto Err;
  131. }
  132. break;
  133. case VtRhello:
  134. if(vtgetstring(p, &f->sid) < 0
  135. || packetconsume(p, buf, 2) < 0)
  136. goto Err;
  137. f->rcrypto = buf[0];
  138. f->rcodec = buf[1];
  139. break;
  140. case VtTgoodbye:
  141. break;
  142. case VtTread:
  143. if(packetconsume(p, f->score, VtScoreSize) < 0
  144. || packetconsume(p, buf, 4) < 0)
  145. goto Err;
  146. f->blocktype = vtfromdisktype(buf[0]);
  147. if(~f->blocktype == 0)
  148. goto Err;
  149. f->count = (buf[2] << 8) | buf[3];
  150. break;
  151. case VtRread:
  152. f->data = packetalloc();
  153. packetconcat(f->data, p);
  154. break;
  155. case VtTwrite:
  156. if(packetconsume(p, buf, 4) < 0)
  157. goto Err;
  158. f->blocktype = vtfromdisktype(buf[0]);
  159. if(~f->blocktype == 0)
  160. goto Err;
  161. f->data = packetalloc();
  162. packetconcat(f->data, p);
  163. break;
  164. case VtRwrite:
  165. if(packetconsume(p, f->score, VtScoreSize) < 0)
  166. goto Err;
  167. break;
  168. case VtTsync:
  169. break;
  170. case VtRsync:
  171. break;
  172. }
  173. if(packetsize(p) != 0)
  174. goto Err;
  175. return 0;
  176. Err:
  177. werrstr("bad packet");
  178. vtfcallclear(f);
  179. return -1;
  180. }
  181. void
  182. vtfcallclear(VtFcall *f)
  183. {
  184. vtfree(f->error);
  185. f->error = nil;
  186. vtfree(f->uid);
  187. f->uid = nil;
  188. vtfree(f->sid);
  189. f->sid = nil;
  190. vtfree(f->version);
  191. f->version = nil;
  192. vtfree(f->crypto);
  193. f->crypto = nil;
  194. vtfree(f->codec);
  195. f->codec = nil;
  196. vtfree(f->auth);
  197. f->auth = nil;
  198. packetfree(f->data);
  199. f->data = nil;
  200. }