fcallconv.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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 perm %M mode %d", tag, fid, (ulong)f->perm, f->mode);
  75. break;
  76. case Rcreate:
  77. sprint(buf, "Rcreate tag %ud qid " QIDFMT " iounit %ud ", tag,
  78. f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
  79. break;
  80. case Tread: /* 116 */
  81. sprint(buf, "Tread tag %ud fid %d offset %lld count %ud",
  82. tag, fid, f->offset, f->count);
  83. break;
  84. case Rread:
  85. n = sprint(buf, "Rread tag %ud count %ud ", tag, f->count);
  86. dumpsome(buf+n, f->data, f->count);
  87. break;
  88. case Twrite: /* 118 */
  89. n = sprint(buf, "Twrite tag %ud fid %d offset %lld count %ud ",
  90. tag, fid, f->offset, f->count);
  91. dumpsome(buf+n, f->data, f->count);
  92. break;
  93. case Rwrite:
  94. sprint(buf, "Rwrite tag %ud count %ud", tag, f->count);
  95. break;
  96. case Tclunk: /* 120 */
  97. sprint(buf, "Tclunk tag %ud fid %ud", tag, fid);
  98. break;
  99. case Rclunk:
  100. sprint(buf, "Rclunk tag %ud", tag);
  101. break;
  102. case Tremove: /* 122 */
  103. sprint(buf, "Tremove tag %ud fid %ud", tag, fid);
  104. break;
  105. case Rremove:
  106. sprint(buf, "Rremove tag %ud", tag);
  107. break;
  108. case Tstat: /* 124 */
  109. sprint(buf, "Tstat tag %ud fid %ud", tag, fid);
  110. break;
  111. case Rstat:
  112. n = sprint(buf, "Rstat tag %ud ", tag);
  113. if(f->nstat > sizeof tmp)
  114. sprint(buf+n, " stat(%d bytes)", f->nstat);
  115. else{
  116. d = (Dir*)tmp;
  117. (old9p?convM2Dold:convM2D)(f->stat, f->nstat, d, (char*)(d+1));
  118. sprint(buf+n, " stat ");
  119. fdirconv(buf+n+6, d);
  120. }
  121. break;
  122. case Twstat: /* 126 */
  123. n = sprint(buf, "Twstat tag %ud fid %ud", tag, fid);
  124. if(f->nstat > sizeof tmp)
  125. sprint(buf+n, " stat(%d bytes)", f->nstat);
  126. else{
  127. d = (Dir*)tmp;
  128. (old9p?convM2Dold:convM2D)(f->stat, f->nstat, d, (char*)(d+1));
  129. sprint(buf+n, " stat ");
  130. fdirconv(buf+n+6, d);
  131. }
  132. break;
  133. case Rwstat:
  134. sprint(buf, "Rwstat tag %ud", tag);
  135. break;
  136. default:
  137. sprint(buf, "unknown type %d", type);
  138. }
  139. strconv(buf, f1);
  140. return(sizeof(Fcall*));
  141. }
  142. static char*
  143. qidtype(char *s, uchar t)
  144. {
  145. char *p;
  146. p = s;
  147. if(t & QTDIR)
  148. *p++ = 'd';
  149. if(t & QTAPPEND)
  150. *p++ = 'a';
  151. if(t & QTEXCL)
  152. *p++ = 'l';
  153. if(t & QTMOUNT)
  154. *p++ = 'm';
  155. if(t & QTAUTH)
  156. *p++ = 'A';
  157. *p = '\0';
  158. return s;
  159. }
  160. int
  161. dirconv(va_list *arg, Fconv *f)
  162. {
  163. char buf[160];
  164. fdirconv(buf, va_arg(*arg, Dir*));
  165. strconv(buf, f);
  166. return(sizeof(Dir*));
  167. }
  168. static void
  169. fdirconv(char *buf, Dir *d)
  170. {
  171. char tmp[16];
  172. sprint(buf, "'%s' '%s' '%s' '%s' "
  173. "q " QIDFMT " m %#luo "
  174. "at %ld mt %ld l %lld "
  175. "t %d d %d",
  176. d->name, d->uid, d->gid, d->muid,
  177. d->qid.path, d->qid.vers, qidtype(tmp, d->qid.type), d->mode,
  178. d->atime, d->mtime, d->length,
  179. d->type, d->dev);
  180. }
  181. /*
  182. * dump out count (or DUMPL, if count is bigger) bytes from
  183. * buf to ans, as a string if they are all printable,
  184. * else as a series of hex bytes
  185. */
  186. #define DUMPL 64
  187. static uint
  188. dumpsome(char *ans, char *buf, long count)
  189. {
  190. int i, printable;
  191. char *p;
  192. printable = 1;
  193. if(count > DUMPL)
  194. count = DUMPL;
  195. for(i=0; i<count && printable; i++)
  196. if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
  197. printable = 0;
  198. p = ans;
  199. *p++ = '\'';
  200. if(printable){
  201. memmove(p, buf, count);
  202. p += count;
  203. }else{
  204. for(i=0; i<count; i++){
  205. if(i>0 && i%4==0)
  206. *p++ = ' ';
  207. sprint(p, "%2.2ux", (uchar)buf[i]);
  208. p += 2;
  209. }
  210. }
  211. *p++ = '\'';
  212. *p = 0;
  213. return p - ans;
  214. }