fcall.c 3.7 KB

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