1
0

nfsmount.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /* Copyright © 2003 Russ Cox, MIT; see /sys/src/libsunrpc/COPYING */
  10. #include <u.h>
  11. #include <libc.h>
  12. #include <thread.h>
  13. #include <sunrpc.h>
  14. #include <nfs3.h>
  15. int chatty;
  16. SunClient *client;
  17. void
  18. usage(void)
  19. {
  20. fprint(2, "usage: nfsmount address [cmd]\n"
  21. "cmd is one of:\n"
  22. "\tnull\n"
  23. "\tmnt path\n"
  24. "\tdump\n"
  25. "\tumnt path\n"
  26. "\tumntall\n"
  27. "\texport (default)\n");
  28. threadexitsall("usage");
  29. }
  30. void
  31. portCall(SunCall *c, PortCallType type)
  32. {
  33. c->rpc.prog = PortProgram;
  34. c->rpc.vers = PortVersion;
  35. c->rpc.proc = type>>1;
  36. c->rpc.iscall = !(type&1);
  37. c->type = type;
  38. }
  39. int
  40. getport(SunClient *client, uint prog, uint vers, uint prot, uint *port)
  41. {
  42. PortTGetport tx;
  43. PortRGetport rx;
  44. memset(&tx, 0, sizeof tx);
  45. portCall(&tx.call, PortCallTGetport);
  46. tx.map.prog = prog;
  47. tx.map.vers = vers;
  48. tx.map.prot = prot;
  49. memset(&rx, 0, sizeof rx);
  50. portCall(&rx.call, PortCallRGetport);
  51. if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
  52. return -1;
  53. *port = rx.port;
  54. return 0;
  55. }
  56. uint8_t unixauth[] = {
  57. 0x12, 0x23, 0x34, 0x45, /* stamp */
  58. 0x00, 0x00, 0x00, 0x04, /* gnot */
  59. 0x67, 0x6e, 0x6f, 0x74,
  60. 0x00, 0x00, 0x03, 0xE9, /* 1001 */
  61. 0x00, 0x00, 0x03, 0xE9, /* 1001 */
  62. 0x00, 0x00, 0x00, 0x00, /* gid list */
  63. };
  64. void
  65. mountCall(SunCall *c, NfsMount3CallType type)
  66. {
  67. c->rpc.prog = NfsMount3Program;
  68. c->rpc.vers = NfsMount3Version;
  69. c->rpc.proc = type>>1;
  70. c->rpc.iscall = !(type&1);
  71. if(c->rpc.iscall){
  72. c->rpc.cred.flavor = SunAuthSys;
  73. c->rpc.cred.data = unixauth;
  74. c->rpc.cred.ndata = sizeof unixauth;
  75. }
  76. c->type = type;
  77. }
  78. void
  79. tnull(char **argv)
  80. {
  81. NfsMount3TNull tx;
  82. NfsMount3RNull rx;
  83. USED(argv);
  84. memset(&tx, 0, sizeof tx);
  85. mountCall(&tx.call, NfsMount3CallTNull);
  86. memset(&rx, 0, sizeof rx);
  87. mountCall(&rx.call, NfsMount3CallRNull);
  88. if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
  89. sysfatal("rpc: %r");
  90. }
  91. void
  92. tmnt(char **argv)
  93. {
  94. int i;
  95. NfsMount3TMnt tx;
  96. NfsMount3RMnt rx;
  97. memset(&tx, 0, sizeof tx);
  98. mountCall(&tx.call, NfsMount3CallTMnt);
  99. tx.path = argv[0];
  100. memset(&rx, 0, sizeof rx);
  101. mountCall(&rx.call, NfsMount3CallRMnt);
  102. if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
  103. sysfatal("rpc: %r");
  104. if(rx.status != 0){
  105. nfs3Errstr(rx.status);
  106. sysfatal("mnt: %r");
  107. }
  108. print("handle %.*H\n", rx.len, rx.handle);
  109. print("auth:");
  110. for(i=0; i<rx.nauth; i++)
  111. print(" %ud", (uint)rx.auth[i]);
  112. print("\n");
  113. }
  114. void
  115. tdump(char **argv)
  116. {
  117. uint8_t *p, *ep;
  118. NfsMount3TDump tx;
  119. NfsMount3RDump rx;
  120. NfsMount3Entry e;
  121. memset(&tx, 0, sizeof tx);
  122. mountCall(&tx.call, NfsMount3CallTDump);
  123. USED(argv);
  124. memset(&rx, 0, sizeof rx);
  125. mountCall(&rx.call, NfsMount3CallRDump);
  126. if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
  127. sysfatal("rpc: %r");
  128. p = rx.data;
  129. ep = p+rx.count;
  130. while(p < ep){
  131. if(nfsMount3EntryUnpack(p, ep, &p, &e) < 0)
  132. sysfatal("unpack entry structure failed");
  133. print("%s %s\n", e.host, e.path);
  134. }
  135. }
  136. void
  137. tumnt(char **argv)
  138. {
  139. NfsMount3TUmnt tx;
  140. NfsMount3RUmnt rx;
  141. memset(&tx, 0, sizeof tx);
  142. mountCall(&tx.call, NfsMount3CallTUmnt);
  143. tx.path = argv[0];
  144. memset(&rx, 0, sizeof rx);
  145. mountCall(&rx.call, NfsMount3CallRUmnt);
  146. if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
  147. sysfatal("rpc: %r");
  148. print("\n");
  149. }
  150. void
  151. tumntall(char **argv)
  152. {
  153. NfsMount3TUmntall tx;
  154. NfsMount3RUmntall rx;
  155. memset(&tx, 0, sizeof tx);
  156. mountCall(&tx.call, NfsMount3CallTUmntall);
  157. USED(argv);
  158. memset(&rx, 0, sizeof rx);
  159. mountCall(&rx.call, NfsMount3CallRUmntall);
  160. if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0)
  161. sysfatal("rpc: %r");
  162. print("\n");
  163. }
  164. void
  165. texport(char **argv)
  166. {
  167. uint8_t *p, *ep, *tofree;
  168. char **g, **gg;
  169. int ng, i, n;
  170. NfsMount3TDump tx;
  171. NfsMount3RDump rx;
  172. NfsMount3Export e;
  173. memset(&tx, 0, sizeof tx);
  174. mountCall(&tx.call, NfsMount3CallTExport);
  175. USED(argv);
  176. memset(&rx, 0, sizeof rx);
  177. mountCall(&rx.call, NfsMount3CallRExport);
  178. if(sunClientRpc(client, 0, &tx.call, &rx.call, &tofree) < 0)
  179. sysfatal("rpc: %r");
  180. p = rx.data;
  181. ep = p+rx.count;
  182. g = nil;
  183. ng = 0;
  184. while(p < ep){
  185. n = nfsMount3ExportGroupSize(p);
  186. if(n > ng){
  187. ng = n;
  188. g = erealloc(g, sizeof(g[0])*ng);
  189. }
  190. if(nfsMount3ExportUnpack(p, ep, &p, g, &gg, &e) < 0)
  191. sysfatal("unpack export structure failed");
  192. print("%s", e.path);
  193. for(i=0; i<e.ng; i++)
  194. print(" %s", e.g[i]);
  195. print("\n");
  196. }
  197. free(tofree);
  198. }
  199. static struct {
  200. char *cmd;
  201. int narg;
  202. void (*fn)(char**);
  203. } tab[] = {
  204. "null", 0, tnull,
  205. "mnt", 1, tmnt,
  206. "dump", 0, tdump,
  207. "umnt", 1, tumnt,
  208. "umntall", 1, tumntall,
  209. "export", 0, texport,
  210. };
  211. char*
  212. netchangeport(char *addr, char *port)
  213. {
  214. static char buf[256];
  215. char *r;
  216. strecpy(buf, buf+sizeof buf, addr);
  217. r = strrchr(buf, '!');
  218. if(r == nil)
  219. return nil;
  220. r++;
  221. strecpy(r, buf+sizeof buf, port);
  222. return buf;
  223. }
  224. void
  225. threadmain(int argc, char **argv)
  226. {
  227. char *dflt[] = { "export", };
  228. char *addr, *cmd;
  229. int i, proto;
  230. uint port;
  231. char buf[32];
  232. int mapit;
  233. mapit = 1;
  234. ARGBEGIN{
  235. case 'R':
  236. chatty++;
  237. break;
  238. case 'm':
  239. mapit = 0;
  240. break;
  241. }ARGEND
  242. if(argc < 1)
  243. usage();
  244. fmtinstall('B', sunRpcFmt);
  245. fmtinstall('C', sunCallFmt);
  246. fmtinstall('H', encodefmt);
  247. sunFmtInstall(&portProg);
  248. sunFmtInstall(&nfsMount3Prog);
  249. addr = netmkaddr(argv[0], "udp", "portmap");
  250. if(mapit){
  251. /* translate with port mapper */
  252. fprint(2, "connecting to %s\n", addr);
  253. if((client = sunDial(addr)) == nil)
  254. sysfatal("dial %s: %r", addr);
  255. client->chatty = chatty;
  256. sunClientProg(client, &portProg);
  257. if(strstr(addr, "udp!"))
  258. proto = PortProtoUdp;
  259. else
  260. proto = PortProtoTcp;
  261. if(getport(client, NfsMount3Program, NfsMount3Version, proto, &port) < 0)
  262. sysfatal("getport: %r");
  263. snprint(buf, sizeof buf, "%ud!r", port);
  264. addr = netchangeport(addr, buf);
  265. sunClientClose(client);
  266. }
  267. fprint(2, "connecting to %s\n", addr);
  268. if((client = sunDial(addr)) == nil)
  269. sysfatal("dial %s: %r", addr);
  270. client->chatty = chatty;
  271. sunClientProg(client, &nfsMount3Prog);
  272. argv++;
  273. argc--;
  274. if(argc == 0){
  275. argc = 1;
  276. argv = dflt;
  277. }
  278. cmd = argv[0];
  279. argv++;
  280. argc--;
  281. for(i=0; i<nelem(tab); i++){
  282. if(strcmp(tab[i].cmd, cmd) == 0){
  283. if(tab[i].narg != argc)
  284. usage();
  285. (*tab[i].fn)(argv);
  286. threadexitsall(nil);
  287. }
  288. }
  289. usage();
  290. }