⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 newns.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <auth.h>#include <authsrv.h>#include "authlocal.h"enum{	NARG	= 15,		/* max number of arguments */	MAXARG	= 10*ANAMELEN,	/* max length of an argument */};static int	setenv(char*, char*);static char	*expandarg(char*, char*);static int	splitargs(char*, char*[], char*, int);static int	nsfile(char*, Biobuf *, AuthRpc *);static int	nsop(char*, int, char*[], AuthRpc*);static int	callexport(char*, char*);static int	catch(void*, char*);int newnsdebug;static intbuildns(int newns, char *user, char *file){	Biobuf *b;	char home[4*ANAMELEN];	int afd;	AuthRpc *rpc;	int cdroot;	char *path;	rpc = nil;	/* try for factotum now because later is impossible */	afd = open("/mnt/factotum/rpc", ORDWR);	if (afd < 0 && newnsdebug)		fprint(2, "open /mnt/factotum/rpc: %r\n");	if(afd >= 0){		rpc = auth_allocrpc(afd);		if(rpc == nil){			close(afd);			afd = -1;		}	}	if(file == nil){		if(!newns){			werrstr("no namespace file specified");			return -1;		}		file = "/lib/namespace";	}	b = Bopen(file, OREAD);	if(b == 0){		werrstr("can't open %s: %r", file);		close(afd);		auth_freerpc(rpc);		return -1;	}	if(newns){		rfork(RFENVG|RFCNAMEG);		setenv("user", user);		snprint(home, 2*ANAMELEN, "/usr/%s", user);		setenv("home", home);	}	cdroot = nsfile(newns ? "newns" : "addns", b, rpc);	Bterm(b);	if(rpc){		close(rpc->afd);		auth_freerpc(rpc);	}	/* make sure we managed to cd into the new name space */	if(newns && !cdroot){		path = malloc(1024);		if(path == nil || getwd(path, 1024) == 0 || chdir(path) < 0)			chdir("/");		if(path != nil)			free(path);	}	return 0;}static intnsfile(char *fn, Biobuf *b, AuthRpc *rpc){	int argc;	char *cmd, *argv[NARG+1], argbuf[MAXARG*NARG];	int cdroot;	cdroot = 0;	atnotify(catch, 1);	while(cmd = Brdline(b, '\n')){		cmd[Blinelen(b)-1] = '\0';		while(*cmd==' ' || *cmd=='\t')			cmd++;		if(*cmd == '#')			continue;		argc = splitargs(cmd, argv, argbuf, NARG);		if(argc)			cdroot |= nsop(fn, argc, argv, rpc);	}	atnotify(catch, 0);	return cdroot;}intnewns(char *user, char *file){	return buildns(1, user, file);}intaddns(char *user, char *file){	return buildns(0, user, file);}static intfamount(int fd, AuthRpc *rpc, char *mntpt, int flags, char *aname){	int afd;	AuthInfo *ai;	afd = fauth(fd, aname);	if(afd >= 0){		ai = fauth_proxy(afd, rpc, amount_getkey, "proto=p9any role=client");		if(ai != nil)			auth_freeAI(ai);	}	return mount(fd, afd, mntpt, flags, aname);}static intnsop(char *fn, int argc, char *argv[], AuthRpc *rpc){	char *argv0;	ulong flags;	int fd, i;	Biobuf *b;	int cdroot;	cdroot = 0;	flags = 0;	argv0 = 0;	if (newnsdebug){		for (i = 0; i < argc; i++)			fprint(2, "%s ", argv[i]);		fprint(2, "\n");	}	ARGBEGIN{	case 'a':		flags |= MAFTER;		break;	case 'b':		flags |= MBEFORE;		break;	case 'c':		flags |= MCREATE;		break;	case 'C':		flags |= MCACHE;		break;	}ARGEND	if(!(flags & (MAFTER|MBEFORE)))		flags |= MREPL;	if(strcmp(argv0, ".") == 0 && argc == 1){		b = Bopen(argv[0], OREAD);		if(b == nil)			return 0;		cdroot |= nsfile(fn, b, rpc);		Bterm(b);	}else if(strcmp(argv0, "clear") == 0 && argc == 0)		rfork(RFCNAMEG);	else if(strcmp(argv0, "bind") == 0 && argc == 2){		if(bind(argv[0], argv[1], flags) < 0 && newnsdebug)			fprint(2, "%s: bind: %s %s: %r\n", fn, argv[0], argv[1]);	}else if(strcmp(argv0, "unmount") == 0){		if(argc == 1)			unmount(nil, argv[0]);		else if(argc == 2)			unmount(argv[0], argv[1]);	}else if(strcmp(argv0, "mount") == 0){		fd = open(argv[0], ORDWR);		if(argc == 2){			if(famount(fd, rpc, argv[1], flags, "") < 0 && newnsdebug)				fprint(2, "%s: mount: %s %s: %r\n", fn, argv[0], argv[1]);		}else if(argc == 3){			if(famount(fd, rpc, argv[1], flags, argv[2]) < 0 && newnsdebug)				fprint(2, "%s: mount: %s %s %s: %r\n", fn, argv[0], argv[1], argv[2]);		}		close(fd);	}else if(strcmp(argv0, "import") == 0){		fd = callexport(argv[0], argv[1]);		if(argc == 2)			famount(fd, rpc, argv[1], flags, "");		else if(argc == 3)			famount(fd, rpc, argv[2], flags, "");		close(fd);	}else if(strcmp(argv0, "cd") == 0 && argc == 1){		if(chdir(argv[0]) == 0 && *argv[0] == '/')			cdroot = 1;	}	return cdroot;}static char *wocp = "sys: write on closed pipe";static intcatch(void *x, char *m){	USED(x);	return strncmp(m, wocp, strlen(wocp)) == 0;}static intcallexport(char *sys, char *tree){	char *na, buf[3];	int fd;	AuthInfo *ai;	na = netmkaddr(sys, 0, "exportfs");	if((fd = dial(na, 0, 0, 0)) < 0)		return -1;	if((ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client")) == nil	|| write(fd, tree, strlen(tree)) < 0	|| read(fd, buf, 3) != 2 || buf[0]!='O' || buf[1]!= 'K'){		close(fd);		auth_freeAI(ai);		return -1;	}	auth_freeAI(ai);	return fd;}static char*unquote(char *s){	char *r, *w;	int inquote;		inquote = 0;	for(r=w=s; *r; r++){		if(*r != '\''){			*w++ = *r;			continue;		}		if(inquote){			if(*(r+1) == '\''){				*w++ = '\'';				r++;			}else				inquote = 0;		}else			inquote = 1;	}	*w = 0;	return s;}static intsplitargs(char *p, char *argv[], char *argbuf, int nargv){	char *q;	int i, n;	n = gettokens(p, argv, nargv, " \t\r");	if(n == nargv)		return 0;	for(i = 0; i < n; i++){		q = argv[i];		argv[i] = argbuf;		argbuf = expandarg(q, argbuf);		if(argbuf == nil)			return 0;		unquote(argv[i]);	}	return n;}static char*nextdollar(char *arg){	char *p;	int inquote;		inquote = 0;	for(p=arg; *p; p++){		if(*p == '\'')			inquote = !inquote;		if(*p == '$' && !inquote)			return p;	}	return nil;}/* * copy the arg into the buffer, * expanding any environment variables. * environment variables are assumed to be * names (ie. < ANAMELEN long) * the entire argument is expanded to be at * most MAXARG long and null terminated * the address of the byte after the terminating null is returned * any problems cause a 0 return; */static char *expandarg(char *arg, char *buf){	char env[3+ANAMELEN], *p, *x;	int fd, n, len;	n = 0;	while(p = nextdollar(arg)){		len = p - arg;		if(n + len + ANAMELEN >= MAXARG-1)			return 0;		memmove(&buf[n], arg, len);		n += len;		p++;		arg = strpbrk(p, "/.!'$");		if(arg == nil)			arg = p+strlen(p);		len = arg - p;		if(len == 0 || len >= ANAMELEN)			continue;		strcpy(env, "#e/");		strncpy(env+3, p, len);		env[3+len] = '\0';		fd = open(env, OREAD);		if(fd >= 0){			len = read(fd, &buf[n], ANAMELEN - 1);			/* some singleton environment variables have trailing NULs */			/* lists separate entries with NULs; we arbitrarily take the first element */			if(len > 0){				x = memchr(&buf[n], 0, len);				if(x != nil)					len = x - &buf[n];				n += len;			}			close(fd);		}	}	len = strlen(arg);	if(n + len >= MAXARG - 1)		return 0;	strcpy(&buf[n], arg);	return &buf[n+len+1];}static intsetenv(char *name, char *val){	int f;	char ename[ANAMELEN+6];	long s;	sprint(ename, "#e/%s", name);	f = create(ename, OWRITE, 0664);	if(f < 0)		return -1;	s = strlen(val);	if(write(f, val, s) != s){		close(f);		return -1;	}	close(f);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -