fcallconv.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include <plan9.h>
  2. #include <fcall.h>
  3. #include <oldfcall.h>
  4. extern int old9p;
  5. static uint dumpsome(char*, char*, long);
  6. static void fdirconv(char*, Dir*);
  7. static char *qidtype(char*, uchar);
  8. #define QIDFMT "(%.16llux %lud %s)"
  9. int
  10. fcallconv(va_list *arg, Fconv *f1)
  11. {
  12. Fcall *f;
  13. int fid, type, tag, n, i;
  14. char buf[512], tmp[200];
  15. Dir *d;
  16. Qid *q;
  17. f = va_arg(*arg, Fcall*);
  18. type = f->type;
  19. fid = f->fid;
  20. tag = f->tag;
  21. switch(type){
  22. case Tversion: /* 100 */
  23. sprint(buf, "Tversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
  24. break;
  25. case Rversion:
  26. sprint(buf, "Rversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
  27. break;
  28. case Tauth: /* 102 */
  29. sprint(buf, "Tauth tag %ud afid %d uname %s aname %s", tag,
  30. f->afid, f->uname, f->aname);
  31. break;
  32. case Rauth:
  33. sprint(buf, "Rauth tag %ud qid " QIDFMT, tag,
  34. f->aqid.path, f->aqid.vers, qidtype(tmp, f->aqid.type));
  35. break;
  36. case Tattach: /* 104 */
  37. sprint(buf, "Tattach tag %ud fid %d afid %d uname %s aname %s", tag,
  38. fid, f->afid, f->uname, f->aname);
  39. break;
  40. case Rattach:
  41. sprint(buf, "Rattach tag %ud qid " QIDFMT, tag,
  42. f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type));
  43. break;
  44. case Rerror: /* 107; 106 (Terror) illegal */
  45. sprint(buf, "Rerror tag %ud ename %s", tag, f->ename);
  46. break;
  47. case Tflush: /* 108 */
  48. sprint(buf, "Tflush tag %ud oldtag %ud", tag, f->oldtag);
  49. break;
  50. case Rflush:
  51. sprint(buf, "Rflush tag %ud", tag);
  52. break;
  53. case Twalk: /* 110 */
  54. n = sprint(buf, "Twalk tag %ud fid %d newfid %d nwname %d ", tag, fid, f->newfid, f->nwname);
  55. for(i=0; i<f->nwname; i++)
  56. n += sprint(buf+n, "%d:%s ", i, f->wname[i]);
  57. break;
  58. case Rwalk:
  59. n = sprint(buf, "Rwalk tag %ud nwqid %ud ", tag, f->nwqid);
  60. for(i=0; i<f->nwqid; i++){
  61. q = &f->wqid[i];
  62. n += sprint(buf+n, "%d:" QIDFMT " ", i,
  63. q->path, q->vers, qidtype(tmp, q->type));
  64. }
  65. break;
  66. case Topen: /* 112 */
  67. sprint(buf, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode);
  68. break;
  69. case Ropen:
  70. sprint(buf, "Ropen tag %ud qid " QIDFMT " iounit %ud ", tag,
  71. f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
  72. break;
  73. case Tcreate: /* 114 */
  74. sprint(buf, "Tcreate tag %ud fid %ud name %s perm %M mode %d",
  75. tag, fid, f->name, (ulong)f->perm, f->mode);
  76. break;
  77. case Rcreate:
  78. sprint(buf, "Rcreate tag %ud qid " QIDFMT " iounit %ud ", tag,
  79. f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
  80. break;
  81. case Tread: /* 116 */
  82. sprint(buf, "Tread tag %ud fid %d offset %lld count %ud",
  83. tag, fid, f->offset, f->count);
  84. break;
  85. case Rread:
  86. n = sprint(buf, "Rread tag %ud count %ud ", tag, f->count);
  87. dumpsome(buf+n, f->data, f->count);
  88. break;
  89. case Twrite: /* 118 */
  90. n = sprint(buf, "Twrite tag %ud fid %d offset %lld count %ud ",
  91. tag, fid, f->offset, f->count);
  92. dumpsome(buf+n, f->data, f->count);
  93. break;
  94. case Rwrite:
  95. sprint(buf, "Rwrite tag %ud count %ud", tag, f->count);
  96. break;
  97. case Tclunk: /* 120 */
  98. sprint(buf, "Tclunk tag %ud fid %ud", tag, fid);
  99. break;
  100. case Rclunk:
  101. sprint(buf, "Rclunk tag %ud", tag);
  102. break;
  103. case Tremove: /* 122 */
  104. sprint(buf, "Tremove tag %ud fid %ud", tag, fid);
  105. break;
  106. case Rremove:
  107. sprint(buf, "Rremove tag %ud", tag);
  108. break;
  109. case Tstat: /* 124 */
  110. sprint(buf, "Tstat tag %ud fid %ud", tag, fid);
  111. break;
  112. case Rstat:
  113. n = sprint(buf, "Rstat tag %ud ", tag);
  114. if(f->nstat > sizeof tmp)
  115. sprint(buf+n, " stat(%d bytes)", f->nstat);
  116. else{
  117. d = (Dir*)tmp;
  118. (old9p?convM2Dold:convM2D)(f->stat, f->nstat, d, (char*)(d+1));
  119. sprint(buf+n, " stat ");
  120. fdirconv(buf+n+6, d);
  121. }
  122. break;
  123. case Twstat: /* 126 */
  124. n = sprint(buf, "Twstat tag %ud fid %ud", tag, fid);
  125. if(f->nstat > sizeof tmp)
  126. sprint(buf+n, " stat(%d bytes)", f->nstat);
  127. else{
  128. d = (Dir*)tmp;
  129. (old9p?convM2Dold:convM2D)(f->stat, f->nstat, d, (char*)(d+1));
  130. sprint(buf+n, " stat ");
  131. fdirconv(buf+n+6, d);
  132. }
  133. break;
  134. case Rwstat:
  135. sprint(buf, "Rwstat tag %ud", tag);
  136. break;
  137. default:
  138. sprint(buf, "unknown type %d", type);
  139. }
  140. strconv(buf, f1);
  141. return(sizeof(Fcall*));
  142. }
  143. static char*
  144. qidtype(char *s, uchar t)
  145. {
  146. char *p;
  147. p = s;
  148. if(t & QTDIR)
  149. *p++ = 'd';
  150. if(t & QTAPPEND)
  151. *p++ = 'a';
  152. if(t & QTEXCL)
  153. *p++ = 'l';
  154. if(t & QTMOUNT)
  155. *p++ = 'm';
  156. if(t & QTAUTH)
  157. *p++ = 'A';
  158. *p = '\0';
  159. return s;
  160. }
  161. int
  162. dirconv(va_list *arg, Fconv *f)
  163. {
  164. char buf[160];
  165. fdirconv(buf, va_arg(*arg, Dir*));
  166. strconv(buf, f);
  167. return(sizeof(Dir*));
  168. }
  169. static void
  170. fdirconv(char *buf, Dir *d)
  171. {
  172. char tmp[16];
  173. sprint(buf, "'%s' '%s' '%s' '%s' "
  174. "q " QIDFMT " m %#luo "
  175. "at %ld mt %ld l %lld "
  176. "t %d d %d",
  177. d->name, d->uid, d->gid, d->muid,
  178. d->qid.path, d->qid.vers, qidtype(tmp, d->qid.type), d->mode,
  179. d->atime, d->mtime, d->length,
  180. d->type, d->dev);
  181. }
  182. /*
  183. * dump out count (or DUMPL, if count is bigger) bytes from
  184. * buf to ans, as a string if they are all printable,
  185. * else as a series of hex bytes
  186. */
  187. #define DUMPL 64
  188. static uint
  189. dumpsome(char *ans, char *buf, long count)
  190. {
  191. int i, printable;
  192. char *p;
  193. printable = 1;
  194. if(count > DUMPL)
  195. count = DUMPL;
  196. for(i=0; i<count && printable; i++)
  197. if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
  198. printable = 0;
  199. p = ans;
  200. *p++ = '\'';
  201. if(printable){
  202. memmove(p, buf, count);
  203. p += count;
  204. }else{
  205. for(i=0; i<count; i++){
  206. if(i>0 && i%4==0)
  207. *p++ = ' ';
  208. sprint(p, "%2.2ux", (uchar)buf[i]);
  209. p += 2;
  210. }
  211. }
  212. *p++ = '\'';
  213. *p = 0;
  214. return p - ans;
  215. }