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 == sizeof(buf)) { 72 fprint(2, "ns: ns string too long\n"); 73 exits("read ns"); 74 } 75 if(n < 0) { 76 fprint(2, "ns: read %r\n"); 77 exits("read ns"); 78 } 79 if(n == 0) 80 break; 81 buf[n] = '\0'; 82 83 m = mallocz(sizeof(Mount), 1); 84 if(m == nil) { 85 fprint(2, "ns: no memory: %r\n"); 86 exits("no memory"); 87 } 88 89 n = tokenize(buf, av, 5); 90 switch(n){ 91 case 2: 92 if(strcmp(av[0], "cd") == 0){ 93 Bprint(&stdout, "%s %s\n", av[0], av[1]); 94 continue; 95 } 96 /* fall through */ 97 default: 98 fprint(2, "ns: unrecognized format of ns file: %d elements on line %d\n", n, line); 99 exits("format"); 100 case 5: 101 m->cmd = strdup(av[0]); 102 m->flag = strdup(av[1]); 103 m->new = strdup(av[2]); 104 m->old = strdup(av[3]); 105 m->spec = strdup(av[4]); 106 break; 107 case 4: 108 if(av[1][0] == '-'){ 109 m->cmd = strdup(av[0]); 110 m->flag = strdup(av[1]); 111 m->new = strdup(av[2]); 112 m->old = strdup(av[3]); 113 m->spec = strdup(""); 114 }else{ 115 m->cmd = strdup(av[0]); 116 m->flag = strdup(""); 117 m->new = strdup(av[1]); 118 m->old = strdup(av[2]); 119 m->spec = strdup(av[3]); 120 } 121 break; 122 case 3: 123 m->cmd = strdup(av[0]); 124 m->flag = strdup(""); 125 m->new = strdup(av[1]); 126 m->old = strdup(av[2]); 127 m->spec = strdup(""); 128 break; 129 } 130 131 if(!rflag && strcmp(m->cmd, "mount")==0) 132 xlatemnt(m); 133 134 Bprint(&stdout, "%s %s %s %s %s\n", m->cmd, m->flag, 135 quote(m->new), quote(m->old), quote(m->spec)); 136 137 free(m->cmd); 138 free(m->flag); 139 free(m->new); 140 free(m->old); 141 free(m->spec); 142 free(m); 143 } 144 145 exits(nil); 146 } 147 148 void 149 xlatemnt(Mount *m) 150 { 151 int n, fd; 152 char *s, *t, *net, *port; 153 char buf[256]; 154 155 if(strncmp(m->new, "/net/", 5) != 0) 156 return; 157 158 s = strdup(m->new); 159 net = s+5; 160 for(t=net; *t!='/'; t++) 161 if(*t == '\0') 162 goto Return; 163 *t = '\0'; 164 port = t+1; 165 for(t=port; *t!='/'; t++) 166 if(*t == '\0') 167 goto Return; 168 *t = '\0'; 169 if(strcmp(t+1, "data") != 0) 170 goto Return; 171 snprint(buf, sizeof buf, "/net/%s/%s/remote", net, port); 172 fd = open(buf, OREAD); 173 if(fd < 0) 174 goto Return; 175 n = read(fd, buf, sizeof buf); 176 close(fd); 177 if(n<=1 || n>sizeof buf) 178 goto Return; 179 if(buf[n-1] == '\n') 180 --n; 181 buf[n] = '\0'; 182 t = malloc(strlen(net)+1+n+1); 183 if(t == nil) 184 goto Return; 185 sprint(t, "%s!%s", net, buf); 186 free(m->new); 187 m->new = t; 188 189 Return: 190 free(s); 191 } 192 193 char* 194 quote(char *s) 195 { 196 static char buf[3][1024]; 197 static int i; 198 char *p, *ep; 199 200 if(strpbrk(s, " '\\\t#$") == nil) 201 return s; 202 i = (i+1)%3; 203 p = &buf[i][0]; 204 ep = &buf[i][1024]; 205 *p++ = '\''; 206 while(p < ep-5){ 207 switch(*s){ 208 case '\0': 209 goto out; 210 case '\'': 211 *p++ = '\''; 212 break; 213 } 214 *p++ = *s++; 215 } 216 out: 217 *p++ = '\''; 218 *p = '\0'; 219 return buf[i]; 220 } 221