xref: /inferno-os/appl/cmd/ns.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsyth# ns - display the construction of the current namespace (loosely based on plan 9's ns)
2*37da2899SCharles.Forsythimplement Ns;
3*37da2899SCharles.Forsyth
4*37da2899SCharles.Forsythinclude "sys.m";
5*37da2899SCharles.Forsyth	sys: Sys;
6*37da2899SCharles.Forsyth
7*37da2899SCharles.Forsythinclude "draw.m";
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsythinclude "arg.m";
10*37da2899SCharles.Forsyth
11*37da2899SCharles.ForsythNs: module
12*37da2899SCharles.Forsyth{
13*37da2899SCharles.Forsyth	init: fn(nil: ref Draw->Context, argv: list of string);
14*37da2899SCharles.Forsyth};
15*37da2899SCharles.Forsyth
16*37da2899SCharles.ForsythSHELLMETA: con "' \t\\$#";
17*37da2899SCharles.Forsyth
18*37da2899SCharles.Forsythusage()
19*37da2899SCharles.Forsyth{
20*37da2899SCharles.Forsyth	sys->fprint(sys->fildes(2), "usage: ns [-r] [pid]\n");
21*37da2899SCharles.Forsyth	raise "fail:usage";
22*37da2899SCharles.Forsyth}
23*37da2899SCharles.Forsyth
24*37da2899SCharles.Forsythinit(nil: ref Draw->Context, args: list of string)
25*37da2899SCharles.Forsyth{
26*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
27*37da2899SCharles.Forsyth
28*37da2899SCharles.Forsyth	arg := load Arg Arg->PATH;
29*37da2899SCharles.Forsyth	if(arg == nil){
30*37da2899SCharles.Forsyth		sys->fprint(sys->fildes(2), "ns: can't load %s: %r\n", Arg->PATH);
31*37da2899SCharles.Forsyth		raise "fail:load";
32*37da2899SCharles.Forsyth	}
33*37da2899SCharles.Forsyth	arg->init(args);
34*37da2899SCharles.Forsyth	pid := sys->pctl(0, nil);
35*37da2899SCharles.Forsyth	raw := 0;
36*37da2899SCharles.Forsyth	while((o := arg->opt()) != 0)
37*37da2899SCharles.Forsyth		case o {
38*37da2899SCharles.Forsyth		'r' =>
39*37da2899SCharles.Forsyth			raw = 1;
40*37da2899SCharles.Forsyth		* =>
41*37da2899SCharles.Forsyth			usage();
42*37da2899SCharles.Forsyth		}
43*37da2899SCharles.Forsyth	args = arg->argv();
44*37da2899SCharles.Forsyth	arg = nil;
45*37da2899SCharles.Forsyth
46*37da2899SCharles.Forsyth	if(len args > 1)
47*37da2899SCharles.Forsyth		usage();
48*37da2899SCharles.Forsyth	if(len args > 0)
49*37da2899SCharles.Forsyth		pid = int hd args;
50*37da2899SCharles.Forsyth
51*37da2899SCharles.Forsyth	nsname := sys->sprint("/prog/%d/ns", pid);
52*37da2899SCharles.Forsyth	nsfd := sys->open(nsname, Sys->OREAD);
53*37da2899SCharles.Forsyth	if(nsfd == nil) {
54*37da2899SCharles.Forsyth		sys->fprint(sys->fildes(2), "ns: can't open %s: %r\n", nsname);
55*37da2899SCharles.Forsyth		raise "fail:open";
56*37da2899SCharles.Forsyth	}
57*37da2899SCharles.Forsyth
58*37da2899SCharles.Forsyth	buf := array[2048] of byte;
59*37da2899SCharles.Forsyth	while((l := sys->read(nsfd, buf, len buf)) > 0){
60*37da2899SCharles.Forsyth		(nstr, lstr) := sys->tokenize(string buf[0:l], " \n");
61*37da2899SCharles.Forsyth		if(nstr < 2)
62*37da2899SCharles.Forsyth			continue;
63*37da2899SCharles.Forsyth		cmd := hd lstr;
64*37da2899SCharles.Forsyth		lstr = tl lstr;
65*37da2899SCharles.Forsyth		if(cmd == "cd" && lstr != nil){
66*37da2899SCharles.Forsyth			sys->print("%s %s\n", cmd, quoted(hd lstr));
67*37da2899SCharles.Forsyth			continue;
68*37da2899SCharles.Forsyth		}
69*37da2899SCharles.Forsyth
70*37da2899SCharles.Forsyth		sflag := "";
71*37da2899SCharles.Forsyth		if((hd lstr)[0] == '-') {
72*37da2899SCharles.Forsyth			sflag = hd lstr + " ";
73*37da2899SCharles.Forsyth			lstr = tl lstr;
74*37da2899SCharles.Forsyth		}
75*37da2899SCharles.Forsyth		if(len lstr < 2)
76*37da2899SCharles.Forsyth			continue;
77*37da2899SCharles.Forsyth
78*37da2899SCharles.Forsyth		src := hd lstr;
79*37da2899SCharles.Forsyth		lstr = tl lstr;
80*37da2899SCharles.Forsyth		if(len src >= 3 && (src[0:2] == "#/" || src[0:2] == "#U")) # remove unnecesary #/'s and #U's
81*37da2899SCharles.Forsyth			src = src[2:];
82*37da2899SCharles.Forsyth
83*37da2899SCharles.Forsyth		# remove "#." from beginning of destination path
84*37da2899SCharles.Forsyth		dest := hd lstr;
85*37da2899SCharles.Forsyth		if(dest == "#M") {
86*37da2899SCharles.Forsyth			dest = dest[2:];
87*37da2899SCharles.Forsyth			if(dest == "")
88*37da2899SCharles.Forsyth				dest = "/";
89*37da2899SCharles.Forsyth		}
90*37da2899SCharles.Forsyth
91*37da2899SCharles.Forsyth		if(cmd == "mount" && !raw)
92*37da2899SCharles.Forsyth			src = netaddr(src);	# optionally rewrite network files to network address
93*37da2899SCharles.Forsyth
94*37da2899SCharles.Forsyth		# quote arguments if "#" found
95*37da2899SCharles.Forsyth		sys->print("%s %s%s %s\n", cmd, sflag, quoted(src), quoted(dest));
96*37da2899SCharles.Forsyth	}
97*37da2899SCharles.Forsyth	if(l < 0)
98*37da2899SCharles.Forsyth		sys->fprint(sys->fildes(2), "ns: error reading %s: %r\n", nsname);
99*37da2899SCharles.Forsyth}
100*37da2899SCharles.Forsyth
101*37da2899SCharles.Forsythnetaddr(f: string): string
102*37da2899SCharles.Forsyth{
103*37da2899SCharles.Forsyth	if(len f < 1 || f[0] != '/')
104*37da2899SCharles.Forsyth		return f;
105*37da2899SCharles.Forsyth	(nf, flds) := sys->tokenize(f, "/");	# expect /net[.alt]/proto/2/data
106*37da2899SCharles.Forsyth	if(nf < 4)
107*37da2899SCharles.Forsyth		return f;
108*37da2899SCharles.Forsyth	netdir := hd flds;
109*37da2899SCharles.Forsyth	if(netdir != "net" && netdir != "net.alt")
110*37da2899SCharles.Forsyth		return f;
111*37da2899SCharles.Forsyth	proto := hd tl flds;
112*37da2899SCharles.Forsyth	d := hd tl tl flds;
113*37da2899SCharles.Forsyth	if(hd tl tl tl flds != "data")
114*37da2899SCharles.Forsyth		return f;
115*37da2899SCharles.Forsyth	fd := sys->open(sys->sprint("/%s/%s/%s/remote", hd flds, proto, d), Sys->OREAD);
116*37da2899SCharles.Forsyth	if(fd == nil)
117*37da2899SCharles.Forsyth		return f;
118*37da2899SCharles.Forsyth	buf := array[256] of byte;
119*37da2899SCharles.Forsyth	n := sys->read(fd, buf, len buf);
120*37da2899SCharles.Forsyth	if(n <= 0)
121*37da2899SCharles.Forsyth		return f;
122*37da2899SCharles.Forsyth	if(buf[n-1] == byte '\n')
123*37da2899SCharles.Forsyth		n--;
124*37da2899SCharles.Forsyth	if(netdir != "net")
125*37da2899SCharles.Forsyth		proto = "/"+netdir+"/"+proto;
126*37da2899SCharles.Forsyth	return sys->sprint("%s!%s", proto, string buf[0:n]);
127*37da2899SCharles.Forsyth}
128*37da2899SCharles.Forsyth
129*37da2899SCharles.Forsythany(c: int, t: string): int
130*37da2899SCharles.Forsyth{
131*37da2899SCharles.Forsyth	for(j := 0; j < len t; j++)
132*37da2899SCharles.Forsyth		if(c == t[j])
133*37da2899SCharles.Forsyth			return 1;
134*37da2899SCharles.Forsyth	return 0;
135*37da2899SCharles.Forsyth}
136*37da2899SCharles.Forsyth
137*37da2899SCharles.Forsythcontains(s: string, t: string): int
138*37da2899SCharles.Forsyth{
139*37da2899SCharles.Forsyth	for(i := 0; i<len s; i++)
140*37da2899SCharles.Forsyth		if(any(s[i], t))
141*37da2899SCharles.Forsyth			return 1;
142*37da2899SCharles.Forsyth	return 0;
143*37da2899SCharles.Forsyth}
144*37da2899SCharles.Forsyth
145*37da2899SCharles.Forsythquoted(s: string): string
146*37da2899SCharles.Forsyth{
147*37da2899SCharles.Forsyth	if(!contains(s, SHELLMETA))
148*37da2899SCharles.Forsyth		return s;
149*37da2899SCharles.Forsyth	r := "'";
150*37da2899SCharles.Forsyth	for(i := 0; i < len s; i++){
151*37da2899SCharles.Forsyth		if(s[i] == '\'')
152*37da2899SCharles.Forsyth			r[len r] = '\'';
153*37da2899SCharles.Forsyth		r[len r] = s[i];
154*37da2899SCharles.Forsyth	}
155*37da2899SCharles.Forsyth	r[len r] = '\'';
156*37da2899SCharles.Forsyth	return r;
157*37da2899SCharles.Forsyth}
158