fcprint.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /*
  2. * linux/fs/9p/fcprint.c
  3. *
  4. * Print 9P call.
  5. *
  6. * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2
  10. * as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to:
  19. * Free Software Foundation
  20. * 51 Franklin Street, Fifth Floor
  21. * Boston, MA 02111-1301 USA
  22. *
  23. */
  24. #include <linux/module.h>
  25. #include <linux/errno.h>
  26. #include <linux/fs.h>
  27. #include <linux/idr.h>
  28. #include "debug.h"
  29. #include "v9fs.h"
  30. #include "9p.h"
  31. #include "mux.h"
  32. static int
  33. v9fs_printqid(char *buf, int buflen, struct v9fs_qid *q)
  34. {
  35. int n;
  36. char b[10];
  37. n = 0;
  38. if (q->type & V9FS_QTDIR)
  39. b[n++] = 'd';
  40. if (q->type & V9FS_QTAPPEND)
  41. b[n++] = 'a';
  42. if (q->type & V9FS_QTAUTH)
  43. b[n++] = 'A';
  44. if (q->type & V9FS_QTEXCL)
  45. b[n++] = 'l';
  46. if (q->type & V9FS_QTTMP)
  47. b[n++] = 't';
  48. if (q->type & V9FS_QTSYMLINK)
  49. b[n++] = 'L';
  50. b[n] = '\0';
  51. return scnprintf(buf, buflen, "(%.16llx %x %s)", (long long int) q->path,
  52. q->version, b);
  53. }
  54. static int
  55. v9fs_printperm(char *buf, int buflen, int perm)
  56. {
  57. int n;
  58. char b[15];
  59. n = 0;
  60. if (perm & V9FS_DMDIR)
  61. b[n++] = 'd';
  62. if (perm & V9FS_DMAPPEND)
  63. b[n++] = 'a';
  64. if (perm & V9FS_DMAUTH)
  65. b[n++] = 'A';
  66. if (perm & V9FS_DMEXCL)
  67. b[n++] = 'l';
  68. if (perm & V9FS_DMTMP)
  69. b[n++] = 't';
  70. if (perm & V9FS_DMDEVICE)
  71. b[n++] = 'D';
  72. if (perm & V9FS_DMSOCKET)
  73. b[n++] = 'S';
  74. if (perm & V9FS_DMNAMEDPIPE)
  75. b[n++] = 'P';
  76. if (perm & V9FS_DMSYMLINK)
  77. b[n++] = 'L';
  78. b[n] = '\0';
  79. return scnprintf(buf, buflen, "%s%03o", b, perm&077);
  80. }
  81. static int
  82. v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended)
  83. {
  84. int n;
  85. n = scnprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len,
  86. st->name.str, st->uid.len, st->uid.str);
  87. if (extended)
  88. n += scnprintf(buf+n, buflen-n, "(%d)", st->n_uid);
  89. n += scnprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str);
  90. if (extended)
  91. n += scnprintf(buf+n, buflen-n, "(%d)", st->n_gid);
  92. n += scnprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str);
  93. if (extended)
  94. n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid);
  95. n += scnprintf(buf+n, buflen-n, " q ");
  96. n += v9fs_printqid(buf+n, buflen-n, &st->qid);
  97. n += scnprintf(buf+n, buflen-n, " m ");
  98. n += v9fs_printperm(buf+n, buflen-n, st->mode);
  99. n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld",
  100. st->atime, st->mtime, (long long int) st->length);
  101. if (extended)
  102. n += scnprintf(buf+n, buflen-n, " ext '%.*s'",
  103. st->extension.len, st->extension.str);
  104. return n;
  105. }
  106. static int
  107. v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen)
  108. {
  109. int i, n;
  110. i = n = 0;
  111. while (i < datalen) {
  112. n += scnprintf(buf + n, buflen - n, "%02x", data[i]);
  113. if (i%4 == 3)
  114. n += scnprintf(buf + n, buflen - n, " ");
  115. if (i%32 == 31)
  116. n += scnprintf(buf + n, buflen - n, "\n");
  117. i++;
  118. }
  119. n += scnprintf(buf + n, buflen - n, "\n");
  120. return n;
  121. }
  122. static int
  123. v9fs_printdata(char *buf, int buflen, u8 *data, int datalen)
  124. {
  125. return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16);
  126. }
  127. int
  128. v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended)
  129. {
  130. int i, ret, type, tag;
  131. if (!fc)
  132. return scnprintf(buf, buflen, "<NULL>");
  133. type = fc->id;
  134. tag = fc->tag;
  135. ret = 0;
  136. switch (type) {
  137. case TVERSION:
  138. ret += scnprintf(buf+ret, buflen-ret,
  139. "Tversion tag %u msize %u version '%.*s'", tag,
  140. fc->params.tversion.msize, fc->params.tversion.version.len,
  141. fc->params.tversion.version.str);
  142. break;
  143. case RVERSION:
  144. ret += scnprintf(buf+ret, buflen-ret,
  145. "Rversion tag %u msize %u version '%.*s'", tag,
  146. fc->params.rversion.msize, fc->params.rversion.version.len,
  147. fc->params.rversion.version.str);
  148. break;
  149. case TAUTH:
  150. ret += scnprintf(buf+ret, buflen-ret,
  151. "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag,
  152. fc->params.tauth.afid, fc->params.tauth.uname.len,
  153. fc->params.tauth.uname.str, fc->params.tauth.aname.len,
  154. fc->params.tauth.aname.str);
  155. break;
  156. case RAUTH:
  157. ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag);
  158. v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid);
  159. break;
  160. case TATTACH:
  161. ret += scnprintf(buf+ret, buflen-ret,
  162. "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'",
  163. tag, fc->params.tattach.fid, fc->params.tattach.afid,
  164. fc->params.tattach.uname.len, fc->params.tattach.uname.str,
  165. fc->params.tattach.aname.len, fc->params.tattach.aname.str);
  166. break;
  167. case RATTACH:
  168. ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag);
  169. v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid);
  170. break;
  171. case RERROR:
  172. ret += scnprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'",
  173. tag, fc->params.rerror.error.len,
  174. fc->params.rerror.error.str);
  175. if (extended)
  176. ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n",
  177. fc->params.rerror.errno);
  178. break;
  179. case TFLUSH:
  180. ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u",
  181. tag, fc->params.tflush.oldtag);
  182. break;
  183. case RFLUSH:
  184. ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag);
  185. break;
  186. case TWALK:
  187. ret += scnprintf(buf+ret, buflen-ret,
  188. "Twalk tag %u fid %d newfid %d nwname %d", tag,
  189. fc->params.twalk.fid, fc->params.twalk.newfid,
  190. fc->params.twalk.nwname);
  191. for(i = 0; i < fc->params.twalk.nwname; i++)
  192. ret += scnprintf(buf+ret, buflen-ret," '%.*s'",
  193. fc->params.twalk.wnames[i].len,
  194. fc->params.twalk.wnames[i].str);
  195. break;
  196. case RWALK:
  197. ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d",
  198. tag, fc->params.rwalk.nwqid);
  199. for(i = 0; i < fc->params.rwalk.nwqid; i++)
  200. ret += v9fs_printqid(buf+ret, buflen-ret,
  201. &fc->params.rwalk.wqids[i]);
  202. break;
  203. case TOPEN:
  204. ret += scnprintf(buf+ret, buflen-ret,
  205. "Topen tag %u fid %d mode %d", tag,
  206. fc->params.topen.fid, fc->params.topen.mode);
  207. break;
  208. case ROPEN:
  209. ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag);
  210. ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid);
  211. ret += scnprintf(buf+ret, buflen-ret," iounit %d",
  212. fc->params.ropen.iounit);
  213. break;
  214. case TCREATE:
  215. ret += scnprintf(buf+ret, buflen-ret,
  216. "Tcreate tag %u fid %d name '%.*s' perm ", tag,
  217. fc->params.tcreate.fid, fc->params.tcreate.name.len,
  218. fc->params.tcreate.name.str);
  219. ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm);
  220. ret += scnprintf(buf+ret, buflen-ret, " mode %d",
  221. fc->params.tcreate.mode);
  222. break;
  223. case RCREATE:
  224. ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag);
  225. ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid);
  226. ret += scnprintf(buf+ret, buflen-ret, " iounit %d",
  227. fc->params.rcreate.iounit);
  228. break;
  229. case TREAD:
  230. ret += scnprintf(buf+ret, buflen-ret,
  231. "Tread tag %u fid %d offset %lld count %u", tag,
  232. fc->params.tread.fid,
  233. (long long int) fc->params.tread.offset,
  234. fc->params.tread.count);
  235. break;
  236. case RREAD:
  237. ret += scnprintf(buf+ret, buflen-ret,
  238. "Rread tag %u count %u data ", tag,
  239. fc->params.rread.count);
  240. ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data,
  241. fc->params.rread.count);
  242. break;
  243. case TWRITE:
  244. ret += scnprintf(buf+ret, buflen-ret,
  245. "Twrite tag %u fid %d offset %lld count %u data ",
  246. tag, fc->params.twrite.fid,
  247. (long long int) fc->params.twrite.offset,
  248. fc->params.twrite.count);
  249. ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data,
  250. fc->params.twrite.count);
  251. break;
  252. case RWRITE:
  253. ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u",
  254. tag, fc->params.rwrite.count);
  255. break;
  256. case TCLUNK:
  257. ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d",
  258. tag, fc->params.tclunk.fid);
  259. break;
  260. case RCLUNK:
  261. ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag);
  262. break;
  263. case TREMOVE:
  264. ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d",
  265. tag, fc->params.tremove.fid);
  266. break;
  267. case RREMOVE:
  268. ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag);
  269. break;
  270. case TSTAT:
  271. ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d",
  272. tag, fc->params.tstat.fid);
  273. break;
  274. case RSTAT:
  275. ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag);
  276. ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat,
  277. extended);
  278. break;
  279. case TWSTAT:
  280. ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ",
  281. tag, fc->params.twstat.fid);
  282. ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat,
  283. extended);
  284. break;
  285. case RWSTAT:
  286. ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag);
  287. break;
  288. default:
  289. ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type);
  290. break;
  291. }
  292. return ret;
  293. }