Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}