diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/aux/nfsmount.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/aux/nfsmount.c')
-rwxr-xr-x | sys/src/cmd/aux/nfsmount.c | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/nfsmount.c b/sys/src/cmd/aux/nfsmount.c new file mode 100755 index 000000000..7a95602b1 --- /dev/null +++ b/sys/src/cmd/aux/nfsmount.c @@ -0,0 +1,334 @@ +/* Copyright © 2003 Russ Cox, MIT; see /sys/src/libsunrpc/COPYING */ +#include <u.h> +#include <libc.h> +#include <thread.h> +#include <sunrpc.h> +#include <nfs3.h> + +int chatty; +SunClient *client; + +void +usage(void) +{ + fprint(2, "usage: nfsmount address [cmd]\n" + "cmd is one of:\n" + "\tnull\n" + "\tmnt path\n" + "\tdump\n" + "\tumnt path\n" + "\tumntall\n" + "\texport (default)\n"); + threadexitsall("usage"); +} + +void +portCall(SunCall *c, PortCallType type) +{ + c->rpc.prog = PortProgram; + c->rpc.vers = PortVersion; + c->rpc.proc = type>>1; + c->rpc.iscall = !(type&1); + c->type = type; +} + +int +getport(SunClient *client, uint prog, uint vers, uint prot, uint *port) +{ + PortTGetport tx; + PortRGetport rx; + + memset(&tx, 0, sizeof tx); + portCall(&tx.call, PortCallTGetport); + tx.map.prog = prog; + tx.map.vers = vers; + tx.map.prot = prot; + + memset(&rx, 0, sizeof rx); + portCall(&rx.call, PortCallRGetport); + + if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0) + return -1; + *port = rx.port; + return 0; +} + +uchar unixauth[] = { + 0x12, 0x23, 0x34, 0x45, /* stamp */ + 0x00, 0x00, 0x00, 0x04, /* gnot */ + 0x67, 0x6e, 0x6f, 0x74, + 0x00, 0x00, 0x03, 0xE9, /* 1001 */ + 0x00, 0x00, 0x03, 0xE9, /* 1001 */ + 0x00, 0x00, 0x00, 0x00, /* gid list */ +}; +void +mountCall(SunCall *c, NfsMount3CallType type) +{ + c->rpc.prog = NfsMount3Program; + c->rpc.vers = NfsMount3Version; + c->rpc.proc = type>>1; + c->rpc.iscall = !(type&1); + if(c->rpc.iscall){ + c->rpc.cred.flavor = SunAuthSys; + c->rpc.cred.data = unixauth; + c->rpc.cred.ndata = sizeof unixauth; + } + c->type = type; +} + +void +tnull(char **argv) +{ + NfsMount3TNull tx; + NfsMount3RNull rx; + + USED(argv); + + memset(&tx, 0, sizeof tx); + mountCall(&tx.call, NfsMount3CallTNull); + + memset(&rx, 0, sizeof rx); + mountCall(&rx.call, NfsMount3CallRNull); + + if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0) + sysfatal("rpc: %r"); +} + +void +tmnt(char **argv) +{ + int i; + NfsMount3TMnt tx; + NfsMount3RMnt rx; + + memset(&tx, 0, sizeof tx); + mountCall(&tx.call, NfsMount3CallTMnt); + tx.path = argv[0]; + + memset(&rx, 0, sizeof rx); + mountCall(&rx.call, NfsMount3CallRMnt); + + if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0) + sysfatal("rpc: %r"); + + if(rx.status != 0){ + nfs3Errstr(rx.status); + sysfatal("mnt: %r"); + } + + print("handle %.*H\n", rx.len, rx.handle); + print("auth:"); + for(i=0; i<rx.nauth; i++) + print(" %ud", (uint)rx.auth[i]); + print("\n"); +} + +void +tdump(char **argv) +{ + uchar *p, *ep; + NfsMount3TDump tx; + NfsMount3RDump rx; + NfsMount3Entry e; + + memset(&tx, 0, sizeof tx); + mountCall(&tx.call, NfsMount3CallTDump); + USED(argv); + + memset(&rx, 0, sizeof rx); + mountCall(&rx.call, NfsMount3CallRDump); + + if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0) + sysfatal("rpc: %r"); + + p = rx.data; + ep = p+rx.count; + while(p < ep){ + if(nfsMount3EntryUnpack(p, ep, &p, &e) < 0) + sysfatal("unpack entry structure failed"); + print("%s %s\n", e.host, e.path); + } +} + +void +tumnt(char **argv) +{ + NfsMount3TUmnt tx; + NfsMount3RUmnt rx; + + memset(&tx, 0, sizeof tx); + mountCall(&tx.call, NfsMount3CallTUmnt); + tx.path = argv[0]; + + memset(&rx, 0, sizeof rx); + mountCall(&rx.call, NfsMount3CallRUmnt); + + if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0) + sysfatal("rpc: %r"); + + print("\n"); +} + +void +tumntall(char **argv) +{ + NfsMount3TUmntall tx; + NfsMount3RUmntall rx; + + memset(&tx, 0, sizeof tx); + mountCall(&tx.call, NfsMount3CallTUmntall); + USED(argv); + + memset(&rx, 0, sizeof rx); + mountCall(&rx.call, NfsMount3CallRUmntall); + + if(sunClientRpc(client, 0, &tx.call, &rx.call, nil) < 0) + sysfatal("rpc: %r"); + + print("\n"); +} + +void +texport(char **argv) +{ + uchar *p, *ep, *tofree; + char **g, **gg; + int ng, i, n; + NfsMount3TDump tx; + NfsMount3RDump rx; + NfsMount3Export e; + + memset(&tx, 0, sizeof tx); + mountCall(&tx.call, NfsMount3CallTExport); + USED(argv); + + memset(&rx, 0, sizeof rx); + mountCall(&rx.call, NfsMount3CallRExport); + + if(sunClientRpc(client, 0, &tx.call, &rx.call, &tofree) < 0) + sysfatal("rpc: %r"); + + p = rx.data; + ep = p+rx.count; + g = nil; + ng = 0; + while(p < ep){ + n = nfsMount3ExportGroupSize(p); + if(n > ng){ + ng = n; + g = erealloc(g, sizeof(g[0])*ng); + } + if(nfsMount3ExportUnpack(p, ep, &p, g, &gg, &e) < 0) + sysfatal("unpack export structure failed"); + print("%s", e.path); + for(i=0; i<e.ng; i++) + print(" %s", e.g[i]); + print("\n"); + } + free(tofree); +} + +static struct { + char *cmd; + int narg; + void (*fn)(char**); +} tab[] = { + "null", 0, tnull, + "mnt", 1, tmnt, + "dump", 0, tdump, + "umnt", 1, tumnt, + "umntall", 1, tumntall, + "export", 0, texport, +}; + +char* +netchangeport(char *addr, char *port) +{ + static char buf[256]; + char *r; + + strecpy(buf, buf+sizeof buf, addr); + r = strrchr(buf, '!'); + if(r == nil) + return nil; + r++; + strecpy(r, buf+sizeof buf, port); + return buf; +} + +void +threadmain(int argc, char **argv) +{ + char *dflt[] = { "export", }; + char *addr, *cmd; + int i, proto; + uint port; + char buf[32]; + int mapit; + + mapit = 1; + ARGBEGIN{ + case 'R': + chatty++; + break; + case 'm': + mapit = 0; + break; + }ARGEND + + if(argc < 1) + usage(); + + fmtinstall('B', sunRpcFmt); + fmtinstall('C', sunCallFmt); + fmtinstall('H', encodefmt); + sunFmtInstall(&portProg); + sunFmtInstall(&nfsMount3Prog); + + addr = netmkaddr(argv[0], "udp", "portmap"); + if(mapit){ + /* translate with port mapper */ + fprint(2, "connecting to %s\n", addr); + if((client = sunDial(addr)) == nil) + sysfatal("dial %s: %r", addr); + client->chatty = chatty; + sunClientProg(client, &portProg); + if(strstr(addr, "udp!")) + proto = PortProtoUdp; + else + proto = PortProtoTcp; + if(getport(client, NfsMount3Program, NfsMount3Version, proto, &port) < 0) + sysfatal("getport: %r"); + snprint(buf, sizeof buf, "%ud!r", port); + addr = netchangeport(addr, buf); + sunClientClose(client); + } + + fprint(2, "connecting to %s\n", addr); + if((client = sunDial(addr)) == nil) + sysfatal("dial %s: %r", addr); + + client->chatty = chatty; + sunClientProg(client, &nfsMount3Prog); + + argv++; + argc--; + + if(argc == 0){ + argc = 1; + argv = dflt; + } + cmd = argv[0]; + argv++; + argc--; + + for(i=0; i<nelem(tab); i++){ + if(strcmp(tab[i].cmd, cmd) == 0){ + if(tab[i].narg != argc) + usage(); + (*tab[i].fn)(argv); + threadexitsall(nil); + } + } + usage(); +} |