xref: /plan9/sys/src/cmd/ns.c (revision 80ee5cbfe36716af62da8896207e9763b8e3d760)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <auth.h>
57dd7cddfSDavid du Colombier #include <fcall.h>
67dd7cddfSDavid du Colombier 
77dd7cddfSDavid du Colombier #pragma	varargck	type	"P"	char*
87dd7cddfSDavid du Colombier 
97dd7cddfSDavid du Colombier int	nsrv;
107dd7cddfSDavid du Colombier Dir	*srv;
117dd7cddfSDavid du Colombier Biobuf	stdout;
127dd7cddfSDavid du Colombier 
137dd7cddfSDavid du Colombier typedef struct Mount Mount;
147dd7cddfSDavid du Colombier 
157dd7cddfSDavid du Colombier struct Mount
167dd7cddfSDavid du Colombier {
177dd7cddfSDavid du Colombier 	char	*cmd;
187dd7cddfSDavid du Colombier 	char	*flag;
197dd7cddfSDavid du Colombier 	char	*new;
207dd7cddfSDavid du Colombier 	char	*old;
217dd7cddfSDavid du Colombier 	char	*spec;
227dd7cddfSDavid du Colombier };
237dd7cddfSDavid du Colombier 
247dd7cddfSDavid du Colombier void	xlatemnt(Mount*);
257dd7cddfSDavid du Colombier char	*quote(char*);
267dd7cddfSDavid du Colombier 
277dd7cddfSDavid du Colombier int	rflag;
287dd7cddfSDavid du Colombier 
297dd7cddfSDavid du Colombier void
usage(void)307dd7cddfSDavid du Colombier usage(void)
317dd7cddfSDavid du Colombier {
327dd7cddfSDavid du Colombier 	fprint(2, "usage: ns [-r] [pid]\n");
337dd7cddfSDavid du Colombier 	exits("usage");
347dd7cddfSDavid du Colombier }
357dd7cddfSDavid du Colombier 
367dd7cddfSDavid du Colombier void
main(int argc,char ** argv)377dd7cddfSDavid du Colombier main(int argc, char **argv)
387dd7cddfSDavid du Colombier {
397dd7cddfSDavid du Colombier 	Mount *m;
407dd7cddfSDavid du Colombier 	int line, fd, n, pid;
417dd7cddfSDavid du Colombier 	char buf[1024], *av[5];
427dd7cddfSDavid du Colombier 
437dd7cddfSDavid du Colombier 	ARGBEGIN{
447dd7cddfSDavid du Colombier 	case 'r':
457dd7cddfSDavid du Colombier 		rflag++;
467dd7cddfSDavid du Colombier 		break;
477dd7cddfSDavid du Colombier 	default:
487dd7cddfSDavid du Colombier 		usage();
497dd7cddfSDavid du Colombier 	}ARGEND
507dd7cddfSDavid du Colombier 
517dd7cddfSDavid du Colombier 	if(argc > 1)
527dd7cddfSDavid du Colombier 		usage();
537dd7cddfSDavid du Colombier 	if(argc == 1){
547dd7cddfSDavid du Colombier 		pid = atoi(argv[0]);
557dd7cddfSDavid du Colombier 		if(pid == 0)
567dd7cddfSDavid du Colombier 			usage();
577dd7cddfSDavid du Colombier 	}else
587dd7cddfSDavid du Colombier 		pid = getpid();
597dd7cddfSDavid du Colombier 
607dd7cddfSDavid du Colombier 	Binit(&stdout, 1, OWRITE);
617dd7cddfSDavid du Colombier 
627dd7cddfSDavid du Colombier 	sprint(buf, "/proc/%d/ns", pid);
637dd7cddfSDavid du Colombier 	fd = open(buf, OREAD);
647dd7cddfSDavid du Colombier 	if(fd < 0) {
657dd7cddfSDavid du Colombier 		fprint(2, "ns: open %s: %r\n", buf);
667dd7cddfSDavid du Colombier 		exits("open ns");
677dd7cddfSDavid du Colombier 	}
687dd7cddfSDavid du Colombier 
697dd7cddfSDavid du Colombier 	for(line=1; ; line++) {
707dd7cddfSDavid du Colombier 		n = read(fd, buf, sizeof(buf));
71*80ee5cbfSDavid du Colombier 		if(n == sizeof(buf)) {
72*80ee5cbfSDavid du Colombier 			fprint(2, "ns: ns string too long\n");
73*80ee5cbfSDavid du Colombier 			exits("read ns");
74*80ee5cbfSDavid du Colombier 		}
757dd7cddfSDavid du Colombier 		if(n < 0) {
767dd7cddfSDavid du Colombier 			fprint(2, "ns: read %r\n");
777dd7cddfSDavid du Colombier 			exits("read ns");
787dd7cddfSDavid du Colombier 		}
797dd7cddfSDavid du Colombier 		if(n == 0)
807dd7cddfSDavid du Colombier 			break;
817dd7cddfSDavid du Colombier 		buf[n] = '\0';
827dd7cddfSDavid du Colombier 
837dd7cddfSDavid du Colombier 		m = mallocz(sizeof(Mount), 1);
847dd7cddfSDavid du Colombier 		if(m == nil) {
857dd7cddfSDavid du Colombier 			fprint(2, "ns: no memory: %r\n");
867dd7cddfSDavid du Colombier 			exits("no memory");
877dd7cddfSDavid du Colombier 		}
887dd7cddfSDavid du Colombier 
897dd7cddfSDavid du Colombier 		n = tokenize(buf, av, 5);
907dd7cddfSDavid du Colombier 		switch(n){
917dd7cddfSDavid du Colombier 		case 2:
927dd7cddfSDavid du Colombier 			if(strcmp(av[0], "cd") == 0){
937dd7cddfSDavid du Colombier 				Bprint(&stdout, "%s %s\n", av[0], av[1]);
947dd7cddfSDavid du Colombier 				continue;
957dd7cddfSDavid du Colombier 			}
967dd7cddfSDavid du Colombier 			/* fall through */
977dd7cddfSDavid du Colombier 		default:
987dd7cddfSDavid du Colombier 			fprint(2, "ns: unrecognized format of ns file: %d elements on line %d\n", n, line);
997dd7cddfSDavid du Colombier 			exits("format");
1007dd7cddfSDavid du Colombier 		case 5:
1017dd7cddfSDavid du Colombier 			m->cmd = strdup(av[0]);
1027dd7cddfSDavid du Colombier 			m->flag = strdup(av[1]);
1037dd7cddfSDavid du Colombier 			m->new = strdup(av[2]);
1047dd7cddfSDavid du Colombier 			m->old = strdup(av[3]);
1057dd7cddfSDavid du Colombier 			m->spec = strdup(av[4]);
1067dd7cddfSDavid du Colombier 			break;
1077dd7cddfSDavid du Colombier 		case 4:
1087dd7cddfSDavid du Colombier 			if(av[1][0] == '-'){
1097dd7cddfSDavid du Colombier 				m->cmd = strdup(av[0]);
1107dd7cddfSDavid du Colombier 				m->flag = strdup(av[1]);
1117dd7cddfSDavid du Colombier 				m->new = strdup(av[2]);
1127dd7cddfSDavid du Colombier 				m->old = strdup(av[3]);
1137dd7cddfSDavid du Colombier 				m->spec = strdup("");
1147dd7cddfSDavid du Colombier 			}else{
1157dd7cddfSDavid du Colombier 				m->cmd = strdup(av[0]);
1167dd7cddfSDavid du Colombier 				m->flag = strdup("");
1177dd7cddfSDavid du Colombier 				m->new = strdup(av[1]);
1187dd7cddfSDavid du Colombier 				m->old = strdup(av[2]);
1197dd7cddfSDavid du Colombier 				m->spec = strdup(av[3]);
1207dd7cddfSDavid du Colombier 			}
1217dd7cddfSDavid du Colombier 			break;
1227dd7cddfSDavid du Colombier 		case 3:
1237dd7cddfSDavid du Colombier 			m->cmd = strdup(av[0]);
1247dd7cddfSDavid du Colombier 			m->flag = strdup("");
1257dd7cddfSDavid du Colombier 			m->new = strdup(av[1]);
1267dd7cddfSDavid du Colombier 			m->old = strdup(av[2]);
1277dd7cddfSDavid du Colombier 			m->spec = strdup("");
1287dd7cddfSDavid du Colombier 			break;
1297dd7cddfSDavid du Colombier 		}
1307dd7cddfSDavid du Colombier 
1317dd7cddfSDavid du Colombier 		if(!rflag && strcmp(m->cmd, "mount")==0)
1327dd7cddfSDavid du Colombier 			xlatemnt(m);
1337dd7cddfSDavid du Colombier 
1347dd7cddfSDavid du Colombier 		Bprint(&stdout, "%s %s %s %s %s\n", m->cmd, m->flag,
1357dd7cddfSDavid du Colombier 			quote(m->new), quote(m->old), quote(m->spec));
1367dd7cddfSDavid du Colombier 
1377dd7cddfSDavid du Colombier 		free(m->cmd);
1387dd7cddfSDavid du Colombier 		free(m->flag);
1397dd7cddfSDavid du Colombier 		free(m->new);
1407dd7cddfSDavid du Colombier 		free(m->old);
1417dd7cddfSDavid du Colombier 		free(m->spec);
1427dd7cddfSDavid du Colombier 		free(m);
1437dd7cddfSDavid du Colombier 	}
1447dd7cddfSDavid du Colombier 
1457dd7cddfSDavid du Colombier 	exits(nil);
1467dd7cddfSDavid du Colombier }
1477dd7cddfSDavid du Colombier 
1487dd7cddfSDavid du Colombier void
xlatemnt(Mount * m)1497dd7cddfSDavid du Colombier xlatemnt(Mount *m)
1507dd7cddfSDavid du Colombier {
1517dd7cddfSDavid du Colombier 	int n, fd;
1527dd7cddfSDavid du Colombier 	char *s, *t, *net, *port;
1537dd7cddfSDavid du Colombier 	char buf[256];
1547dd7cddfSDavid du Colombier 
1557dd7cddfSDavid du Colombier 	if(strncmp(m->new, "/net/", 5) != 0)
1567dd7cddfSDavid du Colombier 		return;
1577dd7cddfSDavid du Colombier 
1587dd7cddfSDavid du Colombier 	s = strdup(m->new);
1597dd7cddfSDavid du Colombier 	net = s+5;
1607dd7cddfSDavid du Colombier 	for(t=net; *t!='/'; t++)
1617dd7cddfSDavid du Colombier 		if(*t == '\0')
1627dd7cddfSDavid du Colombier 			goto Return;
1637dd7cddfSDavid du Colombier 	*t = '\0';
1647dd7cddfSDavid du Colombier 	port = t+1;
1657dd7cddfSDavid du Colombier 	for(t=port; *t!='/'; t++)
1667dd7cddfSDavid du Colombier 		if(*t == '\0')
1677dd7cddfSDavid du Colombier 			goto Return;
1687dd7cddfSDavid du Colombier 	*t = '\0';
1697dd7cddfSDavid du Colombier 	if(strcmp(t+1, "data") != 0)
1707dd7cddfSDavid du Colombier 		goto Return;
1717dd7cddfSDavid du Colombier 	snprint(buf, sizeof buf, "/net/%s/%s/remote", net, port);
1727dd7cddfSDavid du Colombier 	fd = open(buf, OREAD);
1737dd7cddfSDavid du Colombier 	if(fd < 0)
1747dd7cddfSDavid du Colombier 		goto Return;
1757dd7cddfSDavid du Colombier 	n = read(fd, buf, sizeof buf);
1767dd7cddfSDavid du Colombier 	close(fd);
1777dd7cddfSDavid du Colombier 	if(n<=1 || n>sizeof buf)
1787dd7cddfSDavid du Colombier 		goto Return;
1797dd7cddfSDavid du Colombier 	if(buf[n-1] == '\n')
1807dd7cddfSDavid du Colombier 		--n;
1817dd7cddfSDavid du Colombier 	buf[n] = '\0';
1827dd7cddfSDavid du Colombier 	t = malloc(strlen(net)+1+n+1);
1837dd7cddfSDavid du Colombier 	if(t == nil)
1847dd7cddfSDavid du Colombier 		goto Return;
1857dd7cddfSDavid du Colombier 	sprint(t, "%s!%s", net, buf);
1867dd7cddfSDavid du Colombier 	free(m->new);
1877dd7cddfSDavid du Colombier 	m->new = t;
1887dd7cddfSDavid du Colombier 
1897dd7cddfSDavid du Colombier Return:
1907dd7cddfSDavid du Colombier 	free(s);
1917dd7cddfSDavid du Colombier }
1927dd7cddfSDavid du Colombier 
1937dd7cddfSDavid du Colombier char*
quote(char * s)1947dd7cddfSDavid du Colombier quote(char *s)
1957dd7cddfSDavid du Colombier {
1967dd7cddfSDavid du Colombier 	static char buf[3][1024];
1977dd7cddfSDavid du Colombier 	static int i;
1987dd7cddfSDavid du Colombier 	char *p, *ep;
1997dd7cddfSDavid du Colombier 
2007dd7cddfSDavid du Colombier 	if(strpbrk(s, " '\\\t#$") == nil)
2017dd7cddfSDavid du Colombier 		return s;
2027dd7cddfSDavid du Colombier 	i = (i+1)%3;
2037dd7cddfSDavid du Colombier 	p = &buf[i][0];
2047dd7cddfSDavid du Colombier 	ep = &buf[i][1024];
2057dd7cddfSDavid du Colombier 	*p++ = '\'';
2067dd7cddfSDavid du Colombier 	while(p < ep-5){
2077dd7cddfSDavid du Colombier 		switch(*s){
2087dd7cddfSDavid du Colombier 		case '\0':
2097dd7cddfSDavid du Colombier 			goto out;
2107dd7cddfSDavid du Colombier 		case '\'':
2117dd7cddfSDavid du Colombier 			*p++ = '\'';
2127dd7cddfSDavid du Colombier 			break;
2137dd7cddfSDavid du Colombier 		}
2147dd7cddfSDavid du Colombier 		*p++ = *s++;
2157dd7cddfSDavid du Colombier 	}
2167dd7cddfSDavid du Colombier     out:
2177dd7cddfSDavid du Colombier 	*p++ = '\'';
2187dd7cddfSDavid du Colombier 	*p = '\0';
2197dd7cddfSDavid du Colombier 	return buf[i];
2207dd7cddfSDavid du Colombier }
221