]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ns.c
upas/fs: fix more locking bugs, remove debugging clutter, remove planb mbox code
[plan9front.git] / sys / src / cmd / ns.c
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 }