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/srv.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/srv.c')
-rwxr-xr-x | sys/src/cmd/srv.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/sys/src/cmd/srv.c b/sys/src/cmd/srv.c new file mode 100755 index 000000000..f4186f56c --- /dev/null +++ b/sys/src/cmd/srv.c @@ -0,0 +1,237 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <auth.h> + +char *dest = "system"; +int mountflag = MREPL; + +void error(char *); +void rpc(int, int); +void post(char*, int); +void mountfs(char*, int); +int doauth = 1; + +void +usage(void) +{ + fprint(2, "usage: %s [-abcCm] [net!]host [srvname [mtpt]]\n", argv0); + fprint(2, " or %s -e [-abcCm] command [srvname [mtpt]]\n", argv0); + + exits("usage"); +} + +void +ignore(void *a, char *c) +{ + USED(a); + if(strcmp(c, "alarm") == 0){ + fprint(2, "srv: timeout establishing connection to %s\n", dest); + exits("timeout"); + } + if(strstr(c, "write on closed pipe") == 0){ + fprint(2, "write on closed pipe\n"); + noted(NCONT); + } + noted(NDFLT); +} + +int +connectcmd(char *cmd) +{ + int p[2]; + + if(pipe(p) < 0) + return -1; + switch(fork()){ + case -1: + fprint(2, "fork failed: %r\n"); + _exits("exec"); + case 0: + rfork(RFNOTEG); + dup(p[0], 0); + dup(p[0], 1); + close(p[1]); + execl("/bin/rc", "rc", "-c", cmd, nil); + fprint(2, "exec failed: %r\n"); + _exits("exec"); + default: + close(p[0]); + return p[1]; + } +} + +void +main(int argc, char *argv[]) +{ + int fd, doexec; + char *srv, *mtpt; + char dir[1024]; + char err[ERRMAX]; + char *p, *p2; + int domount, reallymount, try, sleeptime; + + notify(ignore); + + domount = 0; + reallymount = 0; + doexec = 0; + sleeptime = 0; + + ARGBEGIN{ + case 'a': + mountflag |= MAFTER; + domount = 1; + reallymount = 1; + break; + case 'b': + mountflag |= MBEFORE; + domount = 1; + reallymount = 1; + break; + case 'c': + mountflag |= MCREATE; + domount = 1; + reallymount = 1; + break; + case 'C': + mountflag |= MCACHE; + domount = 1; + reallymount = 1; + break; + case 'e': + doexec = 1; + break; + case 'm': + domount = 1; + reallymount = 1; + break; + case 'n': + doauth = 0; + break; + case 'q': + domount = 1; + reallymount = 0; + break; + case 'r': + /* deprecated -r flag; ignored for compatibility */ + break; + case 's': + sleeptime = atoi(EARGF(usage())); + break; + default: + usage(); + break; + }ARGEND + + if((mountflag&MAFTER)&&(mountflag&MBEFORE)) + usage(); + + switch(argc){ + case 1: /* calculate srv and mtpt from address */ + p = strrchr(argv[0], '/'); + p = p ? p+1 : argv[0]; + srv = smprint("/srv/%s", p); + p2 = strchr(p, '!'); + p2 = p2 ? p2+1 : p; + mtpt = smprint("/n/%s", p2); + break; + case 2: /* calculate mtpt from address, srv given */ + srv = smprint("/srv/%s", argv[1]); + p = strrchr(argv[0], '/'); + p = p ? p+1 : argv[0]; + p2 = strchr(p, '!'); + p2 = p2 ? p2+1 : p; + mtpt = smprint("/n/%s", p2); + break; + case 3: /* srv and mtpt given */ + domount = 1; + reallymount = 1; + srv = smprint("/srv/%s", argv[1]); + mtpt = smprint("%s", argv[2]); + break; + default: + srv = mtpt = nil; + usage(); + } + + try = 0; + dest = *argv; +Again: + try++; + + if(access(srv, 0) == 0){ + if(domount){ + fd = open(srv, ORDWR); + if(fd >= 0) + goto Mount; + remove(srv); + } + else{ + fprint(2, "srv: %s already exists\n", srv); + exits(0); + } + } + + alarm(10000); + if(doexec) + fd = connectcmd(dest); + else{ + dest = netmkaddr(dest, 0, "9fs"); + fd = dial(dest, 0, dir, 0); + } + if(fd < 0) { + fprint(2, "srv: dial %s: %r\n", dest); + exits("dial"); + } + alarm(0); + + if(sleeptime){ + fprint(2, "sleep..."); + sleep(sleeptime*1000); + } + + post(srv, fd); + +Mount: + if(domount == 0 || reallymount == 0) + exits(0); + + if((!doauth && mount(fd, -1, mtpt, mountflag, "") < 0) + || (doauth && amount(fd, mtpt, mountflag, "") < 0)){ + err[0] = 0; + errstr(err, sizeof err); + if(strstr(err, "Hangup") || strstr(err, "hungup") || strstr(err, "timed out")){ + remove(srv); + if(try == 1) + goto Again; + } + fprint(2, "srv %s: mount failed: %s\n", dest, err); + exits("mount"); + } + exits(0); +} + +void +post(char *srv, int fd) +{ + int f; + char buf[128]; + + fprint(2, "post...\n"); + f = create(srv, OWRITE, 0666); + if(f < 0){ + sprint(buf, "create(%s)", srv); + error(buf); + } + sprint(buf, "%d", fd); + if(write(f, buf, strlen(buf)) != strlen(buf)) + error("write"); +} + +void +error(char *s) +{ + fprint(2, "srv %s: %s: %r\n", dest, s); + exits("srv: error"); +} |