fcallfmt.c 5.6 KB

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