1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <auth.h> 5 #include <fcall.h> 6 7 #pragma varargck type "P" char* 8 9 int nsrv; 10 Dir *srv; 11 Biobuf stdout; 12 13 typedef struct Mount Mount; 14 15 struct Mount 16 { 17 char *cmd; 18 char *flag; 19 char *new; 20 char *old; 21 char *spec; 22 }; 23 24 void xlatemnt(Mount*); 25 char *quote(char*); 26 27 int rflag; 28 29 void 30 usage(void) 31 { 32 fprint(2, "usage: ns [-r] [pid]\n"); 33 exits("usage"); 34 } 35 36 void 37 main(int argc, char **argv) 38 { 39 Mount *m; 40 int line, fd, n, pid; 41 char buf[1024], *av[5]; 42 43 ARGBEGIN{ 44 case 'r': 45 rflag++; 46 break; 47 default: 48 usage(); 49 }ARGEND 50 51 if(argc > 1) 52 usage(); 53 if(argc == 1){ 54 pid = atoi(argv[0]); 55 if(pid == 0) 56 usage(); 57 }else 58 pid = getpid(); 59 60 Binit(&stdout, 1, OWRITE); 61 62 sprint(buf, "/proc/%d/ns", pid); 63 fd = open(buf, OREAD); 64 if(fd < 0) { 65 fprint(2, "ns: open %s: %r\n", buf); 66 exits("open ns"); 67 } 68 69 for(line=1; ; line++) { 70 n = read(fd, buf, sizeof(buf)); 71 if(n < 0) { 72 fprint(2, "ns: read %r\n"); 73 exits("read ns"); 74 } 75 if(n == 0) 76 break; 77 buf[n] = '\0'; 78 79 m = mallocz(sizeof(Mount), 1); 80 if(m == nil) { 81 fprint(2, "ns: no memory: %r\n"); 82 exits("no memory"); 83 } 84 85 n = tokenize(buf, av, 5); 86 switch(n){ 87 case 2: 88 if(strcmp(av[0], "cd") == 0){ 89 Bprint(&stdout, "%s %s\n", av[0], av[1]); 90 continue; 91 } 92 /* fall through */ 93 default: 94 fprint(2, "ns: unrecognized format of ns file: %d elements on line %d\n", n, line); 95 exits("format"); 96 case 5: 97 m->cmd = strdup(av[0]); 98 m->flag = strdup(av[1]); 99 m->new = strdup(av[2]); 100 m->old = strdup(av[3]); 101 m->spec = strdup(av[4]); 102 break; 103 case 4: 104 if(av[1][0] == '-'){ 105 m->cmd = strdup(av[0]); 106 m->flag = strdup(av[1]); 107 m->new = strdup(av[2]); 108 m->old = strdup(av[3]); 109 m->spec = strdup(""); 110 }else{ 111 m->cmd = strdup(av[0]); 112 m->flag = strdup(""); 113 m->new = strdup(av[1]); 114 m->old = strdup(av[2]); 115 m->spec = strdup(av[3]); 116 } 117 break; 118 case 3: 119 m->cmd = strdup(av[0]); 120 m->flag = strdup(""); 121 m->new = strdup(av[1]); 122 m->old = strdup(av[2]); 123 m->spec = strdup(""); 124 break; 125 } 126 127 if(!rflag && strcmp(m->cmd, "mount")==0) 128 xlatemnt(m); 129 130 Bprint(&stdout, "%s %s %s %s %s\n", m->cmd, m->flag, 131 quote(m->new), quote(m->old), quote(m->spec)); 132 133 free(m->cmd); 134 free(m->flag); 135 free(m->new); 136 free(m->old); 137 free(m->spec); 138 free(m); 139 } 140 141 exits(nil); 142 } 143 144 void 145 xlatemnt(Mount *m) 146 { 147 int n, fd; 148 char *s, *t, *net, *port; 149 char buf[256]; 150 151 if(strncmp(m->new, "/net/", 5) != 0) 152 return; 153 154 s = strdup(m->new); 155 net = s+5; 156 for(t=net; *t!='/'; t++) 157 if(*t == '\0') 158 goto Return; 159 *t = '\0'; 160 port = t+1; 161 for(t=port; *t!='/'; t++) 162 if(*t == '\0') 163 goto Return; 164 *t = '\0'; 165 if(strcmp(t+1, "data") != 0) 166 goto Return; 167 snprint(buf, sizeof buf, "/net/%s/%s/remote", net, port); 168 fd = open(buf, OREAD); 169 if(fd < 0) 170 goto Return; 171 n = read(fd, buf, sizeof buf); 172 close(fd); 173 if(n<=1 || n>sizeof buf) 174 goto Return; 175 if(buf[n-1] == '\n') 176 --n; 177 buf[n] = '\0'; 178 t = malloc(strlen(net)+1+n+1); 179 if(t == nil) 180 goto Return; 181 sprint(t, "%s!%s", net, buf); 182 free(m->new); 183 m->new = t; 184 185 Return: 186 free(s); 187 } 188 189 char* 190 quote(char *s) 191 { 192 static char buf[3][1024]; 193 static int i; 194 char *p, *ep; 195 196 if(strpbrk(s, " '\\\t#$") == nil) 197 return s; 198 i = (i+1)%3; 199 p = &buf[i][0]; 200 ep = &buf[i][1024]; 201 *p++ = '\''; 202 while(p < ep-5){ 203 switch(*s){ 204 case '\0': 205 goto out; 206 case '\'': 207 *p++ = '\''; 208 break; 209 } 210 *p++ = *s++; 211 } 212 out: 213 *p++ = '\''; 214 *p = '\0'; 215 return buf[i]; 216 } 217