summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ns.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ns.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ns.c')
-rwxr-xr-xsys/src/cmd/ns.c220
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];
+}