10 NARG = 15, /* max number of arguments */
11 MAXARG = 10*ANAMELEN, /* max length of an argument */
14 static int setenv(char*, char*);
15 static char *expandarg(char*, char*);
16 static int splitargs(char*, char*[], char*, int);
17 static int nsfile(char*, Biobuf *, AuthRpc *);
18 static int nsop(char*, int, char*[], AuthRpc*);
19 static int callexport(char*, char*);
20 static int catch(void*, char*);
25 freecloserpc(AuthRpc *rpc)
35 buildns(int newns, char *user, char *file)
38 char home[4*ANAMELEN];
44 /* try for factotum now because later is impossible */
45 afd = open("/mnt/factotum/rpc", ORDWR);
46 if(afd < 0 && newnsdebug)
47 fprint(2, "open /mnt/factotum/rpc: %r\n");
49 rpc = auth_allocrpc(afd);
53 /* rpc != nil iff afd >= 0 */
57 werrstr("no namespace file specified");
58 return freecloserpc(rpc);
60 file = "/lib/namespace";
62 b = Bopen(file, OREAD);
64 werrstr("can't open %s: %r", file);
65 return freecloserpc(rpc);
68 rfork(RFENVG|RFCNAMEG);
70 snprint(home, sizeof home, "/usr/%s", user);
74 cdroot = nsfile(newns ? "newns" : "addns", b, rpc);
78 /* make sure we managed to cd into the new name space */
81 if(path == nil || getwd(path, 1024) == 0 || chdir(path) < 0)
91 nsfile(char *fn, Biobuf *b, AuthRpc *rpc)
94 char *cmd, *argv[NARG+1], argbuf[MAXARG*NARG];
99 while(cmd = Brdline(b, '\n')){
100 cmd[Blinelen(b)-1] = '\0';
101 while(*cmd==' ' || *cmd=='\t')
105 argc = splitargs(cmd, argv, argbuf, NARG);
107 cdroot |= nsop(fn, argc, argv, rpc);
114 newns(char *user, char *file)
116 return buildns(1, user, file);
120 addns(char *user, char *file)
122 return buildns(0, user, file);
126 famount(int fd, AuthRpc *rpc, char *mntpt, int flags, char *aname)
132 afd = fauth(fd, aname);
134 ai = fauth_proxy(afd, rpc, amount_getkey, "proto=p9any role=client");
138 ret = mount(fd, afd, mntpt, flags, aname);
145 nsop(char *fn, int argc, char *argv[], AuthRpc *rpc)
157 for (i = 0; i < argc; i++)
158 fprint(2, "%s ", argv[i]);
176 if(!(flags & (MAFTER|MBEFORE)))
179 if(strcmp(argv0, ".") == 0 && argc == 1){
180 b = Bopen(argv[0], OREAD);
183 cdroot |= nsfile(fn, b, rpc);
185 }else if(strcmp(argv0, "clear") == 0 && argc == 0)
187 else if(strcmp(argv0, "bind") == 0 && argc == 2){
188 if(bind(argv[0], argv[1], flags) < 0 && newnsdebug)
189 fprint(2, "%s: bind: %s %s: %r\n", fn, argv[0], argv[1]);
190 }else if(strcmp(argv0, "unmount") == 0){
192 unmount(nil, argv[0]);
194 unmount(argv[0], argv[1]);
195 }else if(strcmp(argv0, "mount") == 0){
196 fd = open(argv[0], ORDWR);
198 if(famount(fd, rpc, argv[1], flags, "") < 0 && newnsdebug)
199 fprint(2, "%s: mount: %s %s: %r\n", fn, argv[0], argv[1]);
201 if(famount(fd, rpc, argv[1], flags, argv[2]) < 0 && newnsdebug)
202 fprint(2, "%s: mount: %s %s %s: %r\n", fn, argv[0], argv[1], argv[2]);
205 }else if(strcmp(argv0, "import") == 0){
206 fd = callexport(argv[0], argv[1]);
208 famount(fd, rpc, argv[1], flags, "");
210 famount(fd, rpc, argv[2], flags, "");
212 }else if(strcmp(argv0, "cd") == 0 && argc == 1){
213 if(chdir(argv[0]) == 0 && *argv[0] == '/')
219 static char *wocp = "sys: write on closed pipe";
222 catch(void *x, char *m)
225 return strncmp(m, wocp, strlen(wocp)) == 0;
229 callexport(char *sys, char *tree)
235 na = netmkaddr(sys, 0, "exportfs");
236 if((fd = dial(na, 0, 0, 0)) < 0)
238 if((ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client")) == nil
239 || write(fd, tree, strlen(tree)) < 0
240 || read(fd, buf, 3) != 2 || buf[0]!='O' || buf[1]!= 'K'){
275 splitargs(char *p, char *argv[], char *argbuf, int nargv)
280 n = gettokens(p, argv, nargv, " \t\r");
283 for(i = 0; i < n; i++){
286 argbuf = expandarg(q, argbuf);
295 nextdollar(char *arg)
304 if(*p == '$' && !inquote)
311 * copy the arg into the buffer,
312 * expanding any environment variables.
313 * environment variables are assumed to be
314 * names (ie. < ANAMELEN long)
315 * the entire argument is expanded to be at
316 * most MAXARG long and null terminated
317 * the address of the byte after the terminating null is returned
318 * any problems cause a 0 return;
321 expandarg(char *arg, char *buf)
323 char env[3+ANAMELEN], *p, *x;
327 while(p = nextdollar(arg)){
329 if(n + len + ANAMELEN >= MAXARG-1)
331 memmove(&buf[n], arg, len);
334 arg = strpbrk(p, "/.!'$");
338 if(len == 0 || len >= ANAMELEN)
341 strncpy(env+3, p, len);
343 fd = open(env, OREAD);
345 len = read(fd, &buf[n], ANAMELEN - 1);
346 /* some singleton environment variables have trailing NULs */
347 /* lists separate entries with NULs; we arbitrarily take the first element */
349 x = memchr(&buf[n], 0, len);
358 if(n + len >= MAXARG - 1)
360 strcpy(&buf[n], arg);
361 return &buf[n+len+1];
365 setenv(char *name, char *val)
368 char ename[ANAMELEN+6];
371 sprint(ename, "#e/%s", name);
372 f = create(ename, OWRITE, 0664);
376 if(write(f, val, s) != s){