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