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/ns.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ns.c')
-rwxr-xr-x | sys/src/cmd/ns.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/sys/src/cmd/ns.c b/sys/src/cmd/ns.c new file mode 100755 index 000000000..569009635 --- /dev/null +++ b/sys/src/cmd/ns.c @@ -0,0 +1,220 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <auth.h> +#include <fcall.h> + +#pragma varargck type "P" char* + +int nsrv; +Dir *srv; +Biobuf stdout; + +typedef struct Mount Mount; + +struct Mount +{ + char *cmd; + char *flag; + char *new; + char *old; + char *spec; +}; + +void xlatemnt(Mount*); +char *quote(char*); + +int rflag; + +void +usage(void) +{ + fprint(2, "usage: ns [-r] [pid]\n"); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + Mount *m; + int line, fd, n, pid; + char buf[1024], *av[5]; + + ARGBEGIN{ + case 'r': + rflag++; + break; + default: + usage(); + }ARGEND + + if(argc > 1) + usage(); + if(argc == 1){ + pid = atoi(argv[0]); + if(pid == 0) + usage(); + }else + pid = getpid(); + + Binit(&stdout, 1, OWRITE); + + sprint(buf, "/proc/%d/ns", pid); + fd = open(buf, OREAD); + if(fd < 0) { + fprint(2, "ns: open %s: %r\n", buf); + exits("open ns"); + } + + for(line=1; ; line++) { + n = read(fd, buf, sizeof(buf)); + if(n == sizeof(buf)) { + fprint(2, "ns: ns string too long\n"); + exits("read ns"); + } + if(n < 0) { + fprint(2, "ns: read %r\n"); + exits("read ns"); + } + if(n == 0) + break; + buf[n] = '\0'; + + m = mallocz(sizeof(Mount), 1); + if(m == nil) { + fprint(2, "ns: no memory: %r\n"); + exits("no memory"); + } + + n = tokenize(buf, av, 5); + switch(n){ + case 2: + if(strcmp(av[0], "cd") == 0){ + Bprint(&stdout, "%s %s\n", av[0], av[1]); + continue; + } + /* fall through */ + default: + fprint(2, "ns: unrecognized format of ns file: %d elements on line %d\n", n, line); + exits("format"); + case 5: + m->cmd = strdup(av[0]); + m->flag = strdup(av[1]); + m->new = strdup(av[2]); + m->old = strdup(av[3]); + m->spec = strdup(av[4]); + break; + case 4: + if(av[1][0] == '-'){ + m->cmd = strdup(av[0]); + m->flag = strdup(av[1]); + m->new = strdup(av[2]); + m->old = strdup(av[3]); + m->spec = strdup(""); + }else{ + m->cmd = strdup(av[0]); + m->flag = strdup(""); + m->new = strdup(av[1]); + m->old = strdup(av[2]); + m->spec = strdup(av[3]); + } + break; + case 3: + m->cmd = strdup(av[0]); + m->flag = strdup(""); + m->new = strdup(av[1]); + m->old = strdup(av[2]); + m->spec = strdup(""); + break; + } + + if(!rflag && strcmp(m->cmd, "mount")==0) + xlatemnt(m); + + Bprint(&stdout, "%s %s %s %s %s\n", m->cmd, m->flag, + quote(m->new), quote(m->old), quote(m->spec)); + + free(m->cmd); + free(m->flag); + free(m->new); + free(m->old); + free(m->spec); + free(m); + } + + exits(nil); +} + +void +xlatemnt(Mount *m) +{ + int n, fd; + char *s, *t, *net, *port; + char buf[256]; + + if(strncmp(m->new, "/net/", 5) != 0) + return; + + s = strdup(m->new); + net = s+5; + for(t=net; *t!='/'; t++) + if(*t == '\0') + goto Return; + *t = '\0'; + port = t+1; + for(t=port; *t!='/'; t++) + if(*t == '\0') + goto Return; + *t = '\0'; + if(strcmp(t+1, "data") != 0) + goto Return; + snprint(buf, sizeof buf, "/net/%s/%s/remote", net, port); + fd = open(buf, OREAD); + if(fd < 0) + goto Return; + n = read(fd, buf, sizeof buf); + close(fd); + if(n<=1 || n>sizeof buf) + goto Return; + if(buf[n-1] == '\n') + --n; + buf[n] = '\0'; + t = malloc(strlen(net)+1+n+1); + if(t == nil) + goto Return; + sprint(t, "%s!%s", net, buf); + free(m->new); + m->new = t; + +Return: + free(s); +} + +char* +quote(char *s) +{ + static char buf[3][1024]; + static int i; + char *p, *ep; + + if(strpbrk(s, " '\\\t#$") == nil) + return s; + i = (i+1)%3; + p = &buf[i][0]; + ep = &buf[i][1024]; + *p++ = '\''; + while(p < ep-5){ + switch(*s){ + case '\0': + goto out; + case '\'': + *p++ = '\''; + break; + } + *p++ = *s++; + } + out: + *p++ = '\''; + *p = '\0'; + return buf[i]; +} |