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