1*1ac9729eSCharles Forsythimplement Dialc; 237da2899SCharles.Forsythinclude "sys.m"; 337da2899SCharles.Forsyth sys: Sys; 437da2899SCharles.Forsythinclude "draw.m"; 537da2899SCharles.Forsythinclude "arg.m"; 637da2899SCharles.Forsythinclude "keyring.m"; 737da2899SCharles.Forsyth keyring: Keyring; 837da2899SCharles.Forsythinclude "security.m"; 937da2899SCharles.Forsyth auth: Auth; 10*1ac9729eSCharles Forsythinclude "dial.m"; 11*1ac9729eSCharles Forsyth dial: Dial; 1237da2899SCharles.Forsythinclude "sh.m"; 1337da2899SCharles.Forsyth sh: Sh; 1437da2899SCharles.Forsyth Context: import sh; 1537da2899SCharles.Forsyth 16*1ac9729eSCharles ForsythDialc: module { 1737da2899SCharles.Forsyth init: fn(nil: ref Draw->Context, argv: list of string); 1837da2899SCharles.Forsyth}; 1937da2899SCharles.Forsyth 2037da2899SCharles.Forsythbadmodule(p: string) 2137da2899SCharles.Forsyth{ 2237da2899SCharles.Forsyth sys->fprint(stderr(), "dial: cannot load %s: %r\n", p); 2337da2899SCharles.Forsyth raise "fail:bad module"; 2437da2899SCharles.Forsyth} 2537da2899SCharles.Forsyth 2637da2899SCharles.ForsythDEFAULTALG := "none"; 2737da2899SCharles.Forsyth 2837da2899SCharles.Forsythverbose := 0; 2937da2899SCharles.Forsyth 3037da2899SCharles.Forsythinit(drawctxt: ref Draw->Context, argv: list of string) 3137da2899SCharles.Forsyth{ 3237da2899SCharles.Forsyth sys = load Sys Sys->PATH; 3337da2899SCharles.Forsyth keyring = load Keyring Keyring->PATH; 3437da2899SCharles.Forsyth auth = load Auth Auth->PATH; 3537da2899SCharles.Forsyth if (auth == nil) 3637da2899SCharles.Forsyth badmodule(Auth->PATH); 3737da2899SCharles.Forsyth arg := load Arg Arg->PATH; 3837da2899SCharles.Forsyth if (arg == nil) 3937da2899SCharles.Forsyth badmodule(Arg->PATH); 4037da2899SCharles.Forsyth sh = load Sh Sh->PATH; 4137da2899SCharles.Forsyth if (sh == nil) 4237da2899SCharles.Forsyth badmodule(Sh->PATH); 43*1ac9729eSCharles Forsyth dial = load Dial Dial->PATH; 44*1ac9729eSCharles Forsyth if (dial == nil) 45*1ac9729eSCharles Forsyth badmodule(Dial->PATH); 4637da2899SCharles.Forsyth 4737da2899SCharles.Forsyth auth->init(); 4837da2899SCharles.Forsyth alg: string; 4937da2899SCharles.Forsyth keyfile: string; 5037da2899SCharles.Forsyth doauth := 1; 5137da2899SCharles.Forsyth arg->init(argv); 5237da2899SCharles.Forsyth arg->setusage("dial [-A] [-k keyfile] [-a alg] addr command [arg...]"); 5337da2899SCharles.Forsyth while ((opt := arg->opt()) != 0) { 5437da2899SCharles.Forsyth case opt { 5537da2899SCharles.Forsyth 'A' => 5637da2899SCharles.Forsyth doauth = 0; 5737da2899SCharles.Forsyth 'a' => 5837da2899SCharles.Forsyth alg = arg->earg(); 5937da2899SCharles.Forsyth 'f' or 6037da2899SCharles.Forsyth 'k' => 6137da2899SCharles.Forsyth keyfile = arg->earg(); 6237da2899SCharles.Forsyth if (! (keyfile[0] == '/' || (len keyfile > 2 && keyfile[0:2] == "./"))) 6337da2899SCharles.Forsyth keyfile = "/usr/" + user() + "/keyring/" + keyfile; 6437da2899SCharles.Forsyth 'v' => 6537da2899SCharles.Forsyth verbose = 1; 6637da2899SCharles.Forsyth * => 6737da2899SCharles.Forsyth arg->usage(); 6837da2899SCharles.Forsyth } 6937da2899SCharles.Forsyth } 7037da2899SCharles.Forsyth argv = arg->argv(); 7137da2899SCharles.Forsyth if (len argv < 2) 7237da2899SCharles.Forsyth arg->usage(); 7337da2899SCharles.Forsyth arg = nil; 7437da2899SCharles.Forsyth (addr, shcmd) := (hd argv, tl argv); 7537da2899SCharles.Forsyth 7637da2899SCharles.Forsyth if (doauth && alg == nil) 7737da2899SCharles.Forsyth alg = DEFAULTALG; 7837da2899SCharles.Forsyth 7937da2899SCharles.Forsyth if (alg != nil && keyfile == nil) { 8037da2899SCharles.Forsyth kd := "/usr/" + user() + "/keyring/"; 8137da2899SCharles.Forsyth if (exists(kd + addr)) 8237da2899SCharles.Forsyth keyfile = kd + addr; 8337da2899SCharles.Forsyth else 8437da2899SCharles.Forsyth keyfile = kd + "default"; 8537da2899SCharles.Forsyth } 8637da2899SCharles.Forsyth cert: ref Keyring->Authinfo; 8737da2899SCharles.Forsyth if (alg != nil) { 8837da2899SCharles.Forsyth cert = keyring->readauthinfo(keyfile); 8937da2899SCharles.Forsyth if (cert == nil) { 9037da2899SCharles.Forsyth sys->fprint(stderr(), "dial: cannot read %s: %r\n", keyfile); 9137da2899SCharles.Forsyth raise "fail:bad keyfile"; 9237da2899SCharles.Forsyth } 9337da2899SCharles.Forsyth } 9437da2899SCharles.Forsyth 95*1ac9729eSCharles Forsyth c := dial->dial(addr, nil); 96*1ac9729eSCharles Forsyth if (c == nil) { 97*1ac9729eSCharles Forsyth sys->fprint(stderr(), "dial: cannot dial %s: %r\n", addr); 9837da2899SCharles.Forsyth raise "fail:errors"; 9937da2899SCharles.Forsyth } 10037da2899SCharles.Forsyth user: string; 10137da2899SCharles.Forsyth if (alg != nil) { 10237da2899SCharles.Forsyth err: string; 10337da2899SCharles.Forsyth (c.dfd, err) = auth->client(alg, cert, c.dfd); 10437da2899SCharles.Forsyth if (c.dfd == nil) { 10537da2899SCharles.Forsyth sys->fprint(stderr(), "dial: authentication failed: %s\n", err); 10637da2899SCharles.Forsyth raise "fail:errors"; 10737da2899SCharles.Forsyth } 10837da2899SCharles.Forsyth user = err; 10937da2899SCharles.Forsyth } 11037da2899SCharles.Forsyth sys->dup(c.dfd.fd, 0); 11137da2899SCharles.Forsyth sys->dup(c.dfd.fd, 1); 11237da2899SCharles.Forsyth c.dfd = c.cfd = nil; 11337da2899SCharles.Forsyth ctxt := Context.new(drawctxt); 11437da2899SCharles.Forsyth if (user != nil) 11537da2899SCharles.Forsyth ctxt.set("user", sh->stringlist2list(user :: nil)); 11637da2899SCharles.Forsyth else 11737da2899SCharles.Forsyth ctxt.set("user", nil); 11837da2899SCharles.Forsyth ctxt.set("net", ref Sh->Listnode(nil, c.dir) :: nil); 11937da2899SCharles.Forsyth ctxt.run(sh->stringlist2list(shcmd), 1); 12037da2899SCharles.Forsyth} 12137da2899SCharles.Forsyth 12237da2899SCharles.Forsythexists(f: string): int 12337da2899SCharles.Forsyth{ 12437da2899SCharles.Forsyth (ok, nil) := sys->stat(f); 12537da2899SCharles.Forsyth return ok != -1; 12637da2899SCharles.Forsyth} 12737da2899SCharles.Forsyth 12837da2899SCharles.Forsythstderr(): ref Sys->FD 12937da2899SCharles.Forsyth{ 13037da2899SCharles.Forsyth return sys->fildes(2); 13137da2899SCharles.Forsyth} 13237da2899SCharles.Forsyth 13337da2899SCharles.Forsythuser(): string 13437da2899SCharles.Forsyth{ 13537da2899SCharles.Forsyth u := readfile("/dev/user"); 13637da2899SCharles.Forsyth if (u == nil) 13737da2899SCharles.Forsyth return "nobody"; 13837da2899SCharles.Forsyth return u; 13937da2899SCharles.Forsyth} 14037da2899SCharles.Forsyth 14137da2899SCharles.Forsythreadfile(f: string): string 14237da2899SCharles.Forsyth{ 14337da2899SCharles.Forsyth fd := sys->open(f, sys->OREAD); 14437da2899SCharles.Forsyth if(fd == nil) 14537da2899SCharles.Forsyth return nil; 14637da2899SCharles.Forsyth 14737da2899SCharles.Forsyth buf := array[128] of byte; 14837da2899SCharles.Forsyth n := sys->read(fd, buf, len buf); 14937da2899SCharles.Forsyth if(n < 0) 15037da2899SCharles.Forsyth return nil; 15137da2899SCharles.Forsyth 15237da2899SCharles.Forsyth return string buf[0:n]; 15337da2899SCharles.Forsyth} 154