ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/cmd/fs/setroot.b/
implement Fsmodule;
include "sys.m";
sys: Sys;
include "draw.m";
include "sh.m";
include "fslib.m";
fslib: Fslib;
Report, Value, type2s, quit: import fslib;
Fschan, Fsdata, Entrychan, Entry,
Gatechan, Gatequery, Nilentry, Option,
Next, Down, Skip, Quit: import Fslib;
# set the root
types(): string
{
return "xsx-c";
}
badmod(p: string)
{
sys->fprint(sys->fildes(2), "fs: size: cannot load %s: %r\n", p);
raise "fail:bad module";
}
init()
{
sys = load Sys Sys->PATH;
fslib = load Fslib Fslib->PATH;
if(fslib == nil)
badmod(Fslib->PATH);
}
run(nil: ref Draw->Context, nil: ref Report,
opts: list of Option, args: list of ref Value): ref Value
{
root := (hd args).s().i;
if(root == nil && opts == nil){
sys->fprint(sys->fildes(2), "fs: setroot: empty path\n");
return nil;
}
v := ref Value.X(chan of (Fsdata, chan of int));
spawn setroot((hd tl args).x().i, v.i, root, opts != nil);
return v;
}
setroot(src, dst: Fschan, root: string, cflag: int)
{
((d, nil), reply) := <-src;
if(cflag){
createroot(src, dst, root, d, reply);
}else{
myreply := chan of int;
rd := ref *d;
rd.name = root;
dst <-= ((rd, nil), myreply);
if(<-myreply == Down){
reply <-= Down;
fslib->copy(src, dst);
}
}
}
createroot(src, dst: Fschan, root: string, d: ref Sys->Dir, reply: chan of int)
{
if(root == nil)
root = d.name;
(n, elems) := sys->tokenize(root, "/"); # XXX should really do a cleanname first
if(root[0] == '/'){
elems = "/" :: elems;
n++;
}
myreply := chan of int;
lev := 0;
r := -1;
for(; elems != nil; elems = tl elems){
rd := ref *d;
rd.name = hd elems;
dst <-= ((rd, nil), myreply);
case r = <-myreply {
Quit =>
(<-src).t1 <-= Quit;
exit;
Skip =>
break;
Next =>
lev++;
break;
}
lev++;
}
if(r == Down){
reply <-= Down;
if(fslib->copy(src, dst) == Quit)
exit;
}else
reply <-= Quit;
while(lev-- > 1){
dst <-= ((nil, nil), myreply);
if(<-myreply == Quit){
(<-src).t1 <-= Quit;
exit;
}
}
}