137da2899SCharles.Forsythimplement FBrowse; 237da2899SCharles.Forsyth 337da2899SCharles.Forsyth# 437da2899SCharles.Forsyth# Copyright © 2003 Vita Nuova Holdings Limited. All rights reserved. 537da2899SCharles.Forsyth# 637da2899SCharles.Forsyth 737da2899SCharles.Forsyth 837da2899SCharles.Forsythinclude "sys.m"; 937da2899SCharles.Forsyth sys : Sys; 1037da2899SCharles.Forsythinclude "draw.m"; 1137da2899SCharles.Forsyth draw: Draw; 1237da2899SCharles.Forsyth Rect: import draw; 1337da2899SCharles.Forsythinclude "tk.m"; 1437da2899SCharles.Forsyth tk: Tk; 1537da2899SCharles.Forsythinclude "tkclient.m"; 1637da2899SCharles.Forsyth tkclient: Tkclient; 1737da2899SCharles.Forsythinclude "readdir.m"; 1837da2899SCharles.Forsyth readdir: Readdir; 1937da2899SCharles.Forsythinclude "workdir.m"; 2037da2899SCharles.Forsythinclude "sh.m"; 2137da2899SCharles.Forsyth sh: Sh; 2237da2899SCharles.Forsythinclude "grid/pathreader.m"; 2337da2899SCharles.Forsyth reader: PathReader; 2437da2899SCharles.Forsythinclude "grid/browser.m"; 2537da2899SCharles.Forsyth browser: Browser; 2637da2899SCharles.Forsyth Browse, Select, File, Parameter, 2737da2899SCharles.Forsyth DESELECT, SELECT, TOGGLE: import browser; 2837da2899SCharles.Forsythinclude "grid/fbrowse.m"; 2937da2899SCharles.Forsyth 3037da2899SCharles.Forsythbr: ref Browse; 3137da2899SCharles.Forsyth 3237da2899SCharles.Forsythinit(ctxt : ref Draw->Context, title, root, currdir: string): string 3337da2899SCharles.Forsyth{ 3437da2899SCharles.Forsyth sys = load Sys Sys->PATH; 3537da2899SCharles.Forsyth if (sys == nil) 3637da2899SCharles.Forsyth badmod(Sys->PATH); 3737da2899SCharles.Forsyth draw = load Draw Draw->PATH; 3837da2899SCharles.Forsyth if (draw == nil) 3937da2899SCharles.Forsyth badmod(Draw->PATH); 4037da2899SCharles.Forsyth readdir = load Readdir Readdir->PATH; 4137da2899SCharles.Forsyth if (readdir == nil) 4237da2899SCharles.Forsyth badmod(Readdir->PATH); 4337da2899SCharles.Forsyth tk = load Tk Tk->PATH; 4437da2899SCharles.Forsyth if (tk == nil) 4537da2899SCharles.Forsyth badmod(Tk->PATH); 4637da2899SCharles.Forsyth tkclient = load Tkclient Tkclient->PATH; 4737da2899SCharles.Forsyth if (tkclient == nil) 4837da2899SCharles.Forsyth badmod(Tkclient->PATH); 4937da2899SCharles.Forsyth tkclient->init(); 5037da2899SCharles.Forsyth workdir := load Workdir Workdir->PATH; 5137da2899SCharles.Forsyth if (workdir == nil) 5237da2899SCharles.Forsyth badmod(Workdir->PATH); 5337da2899SCharles.Forsyth sh = load Sh Sh->PATH; 5437da2899SCharles.Forsyth if (sh == nil) 5537da2899SCharles.Forsyth badmod(Sh->PATH); 5637da2899SCharles.Forsyth browser = load Browser Browser->PATH; 5737da2899SCharles.Forsyth if (browser == nil) 5837da2899SCharles.Forsyth badmod(Browser->PATH); 5937da2899SCharles.Forsyth browser->init(); 6037da2899SCharles.Forsyth reader = load PathReader "$self"; 6137da2899SCharles.Forsyth if (reader == nil) 6237da2899SCharles.Forsyth sys->print("cannot load reader!\n"); 6337da2899SCharles.Forsyth sys->pctl(sys->NEWPGRP, nil); 6437da2899SCharles.Forsyth if (root == nil) 6537da2899SCharles.Forsyth root = "/"; 6637da2899SCharles.Forsyth sys->chdir(root); 6737da2899SCharles.Forsyth if (currdir == nil) 6837da2899SCharles.Forsyth currdir = workdir->init(); 6937da2899SCharles.Forsyth if (root[len root - 1] != '/') 7037da2899SCharles.Forsyth root[len root] = '/'; 7137da2899SCharles.Forsyth if (currdir[len currdir - 1] != '/') 7237da2899SCharles.Forsyth currdir[len currdir] = '/'; 7337da2899SCharles.Forsyth 7437da2899SCharles.Forsyth (top, titlebar) := tkclient->toplevel(ctxt,"", title , tkclient->OK | tkclient->Appl); 7537da2899SCharles.Forsyth browsechan := chan of string; 7637da2899SCharles.Forsyth tk->namechan(top, browsechan, "browsechan"); 7737da2899SCharles.Forsyth br = Browse.new(top, "browsechan", root, root, 2, reader); 7837da2899SCharles.Forsyth br.addopened(File (root, nil), 1); 7937da2899SCharles.Forsyth br.gotoselectfile(File (currdir, nil)); 8037da2899SCharles.Forsyth for (ik := 0; ik < len mainscreen; ik++) 8137da2899SCharles.Forsyth tkcmd(top,mainscreen[ik]); 8237da2899SCharles.Forsyth butchan := chan of string; 8337da2899SCharles.Forsyth tk->namechan(top, butchan, "butchan"); 8437da2899SCharles.Forsyth 8537da2899SCharles.Forsyth tkcmd(top, "pack .f -fill both -expand 1; pack propagate . 0"); 8637da2899SCharles.Forsyth tkcmd(top, ". configure -height 300 -width 300"); 8737da2899SCharles.Forsyth 8837da2899SCharles.Forsyth tkcmd(top, "update"); 8937da2899SCharles.Forsyth released := 1; 9037da2899SCharles.Forsyth title = ""; 9137da2899SCharles.Forsyth 9237da2899SCharles.Forsyth tkclient->onscreen(top, nil); 9337da2899SCharles.Forsyth resize(top, ctxt.display.image); 9437da2899SCharles.Forsyth tkclient->startinput(top, "kbd"::"ptr"::nil); 9537da2899SCharles.Forsyth 9637da2899SCharles.Forsyth path: string; 9737da2899SCharles.Forsyth 9837da2899SCharles.Forsyth main: for (;;) { 9937da2899SCharles.Forsyth alt { 10037da2899SCharles.Forsyth s := <-top.ctxt.kbd => 10137da2899SCharles.Forsyth tk->keyboard(top, s); 10237da2899SCharles.Forsyth s := <-top.ctxt.ptr => 10337da2899SCharles.Forsyth tk->pointer(top, *s); 10437da2899SCharles.Forsyth inp := <-browsechan => 10537da2899SCharles.Forsyth (nil, lst) := sys->tokenize(inp, " \n\t"); 10637da2899SCharles.Forsyth selected := br.getselected(1); 10737da2899SCharles.Forsyth case hd lst { 10837da2899SCharles.Forsyth "double1pane1" => 10937da2899SCharles.Forsyth tkpath := hd tl lst; 11037da2899SCharles.Forsyth file := br.getpath(tkpath); 11137da2899SCharles.Forsyth br.defaultaction(lst, file); 11237da2899SCharles.Forsyth (n, dir) := sys->stat(file.path); 11337da2899SCharles.Forsyth if (n == -1 || dir.mode & sys->DMDIR) 11437da2899SCharles.Forsyth break; 11537da2899SCharles.Forsyth if ((len dir.name > 4 && dir.name[len dir.name - 4:] == ".dis") || 11637da2899SCharles.Forsyth dir.mode & 8r111) 11737da2899SCharles.Forsyth spawn send(butchan, "run "+tkpath); 11837da2899SCharles.Forsyth else if (dir.mode & 8r222) 11937da2899SCharles.Forsyth spawn send(butchan, "write "+tkpath); 12037da2899SCharles.Forsyth else if (dir.mode & 8r444) 12137da2899SCharles.Forsyth spawn send(butchan, "open "+tkpath); 12237da2899SCharles.Forsyth * => 12337da2899SCharles.Forsyth br.defaultaction(lst, nil); 12437da2899SCharles.Forsyth } 12537da2899SCharles.Forsyth if (!File.eq(selected, br.getselected(1))) 12637da2899SCharles.Forsyth actionbutton(top, br.selected[1].file.path, br.selected[1].tkpath); 12737da2899SCharles.Forsyth tkcmd(top, "update"); 12837da2899SCharles.Forsyth inp := <-butchan => 12937da2899SCharles.Forsyth (nil, lst) := sys->tokenize(inp, " \n\t"); 13037da2899SCharles.Forsyth case hd lst { 13137da2899SCharles.Forsyth "refresh" => 13237da2899SCharles.Forsyth br.refresh(); 13337da2899SCharles.Forsyth "shell" => 13437da2899SCharles.Forsyth path = br.getselected(1).path; 13537da2899SCharles.Forsyth if (path == nil) 13637da2899SCharles.Forsyth sys->chdir(root); 13737da2899SCharles.Forsyth else 13837da2899SCharles.Forsyth sys->chdir(path); 13937da2899SCharles.Forsyth sh->run(ctxt, "/dis/wm/sh.dis" :: nil); 14037da2899SCharles.Forsyth 14137da2899SCharles.Forsyth "run" => 14237da2899SCharles.Forsyth spawn run(ctxt, br.getselected(1).path); 14337da2899SCharles.Forsyth "read" => 14437da2899SCharles.Forsyth wtitle := tkcmd(top, hd tl lst+" cget text"); 14537da2899SCharles.Forsyth spawn openfile(ctxt, br.getselected(1).path, wtitle,0); 14637da2899SCharles.Forsyth "write" => 14737da2899SCharles.Forsyth wtitle := tkcmd(top, hd tl lst+" cget text"); 14837da2899SCharles.Forsyth spawn openfile(ctxt, br.getselected(1).path, wtitle,1); 14937da2899SCharles.Forsyth } 15037da2899SCharles.Forsyth tkcmd(top, "update"); 15137da2899SCharles.Forsyth 15237da2899SCharles.Forsyth title = <-top.ctxt.ctl or 15337da2899SCharles.Forsyth title = <-top.wreq or 15437da2899SCharles.Forsyth title = <-titlebar => 15537da2899SCharles.Forsyth if (title == "exit" || title == "ok") 15637da2899SCharles.Forsyth break main; 15737da2899SCharles.Forsyth e := tkclient->wmctl(top, title); 15837da2899SCharles.Forsyth if (e != nil && e[0] == '!') 15937da2899SCharles.Forsyth br.resize(); 16037da2899SCharles.Forsyth } 16137da2899SCharles.Forsyth } 16237da2899SCharles.Forsyth if (title == "ok") 16337da2899SCharles.Forsyth return br.getselected(1).path; 16437da2899SCharles.Forsyth return ""; 16537da2899SCharles.Forsyth} 16637da2899SCharles.Forsyth 16737da2899SCharles.Forsythsend(chanout: chan of string, s: string) 16837da2899SCharles.Forsyth{ 16937da2899SCharles.Forsyth chanout <-= s; 17037da2899SCharles.Forsyth} 17137da2899SCharles.Forsyth 17237da2899SCharles.Forsythresize(top: ref Tk->Toplevel, img: ref Draw->Image) 17337da2899SCharles.Forsyth{ 17437da2899SCharles.Forsyth if (img != nil) { 17537da2899SCharles.Forsyth scw := img.r.dx(); 17637da2899SCharles.Forsyth sch := img.r.dy(); 17737da2899SCharles.Forsyth ww := int tkcmd(top, ". cget -width"); 17837da2899SCharles.Forsyth wh := int tkcmd(top, ". cget -height"); 17937da2899SCharles.Forsyth if (ww > scw) 18037da2899SCharles.Forsyth tkcmd(top, ". configure -x 0 -width "+string scw); 18137da2899SCharles.Forsyth if (wh > sch) 18237da2899SCharles.Forsyth tkcmd(top, ". configure -y 0 -height "+string sch); 18337da2899SCharles.Forsyth } 18437da2899SCharles.Forsyth} 18537da2899SCharles.Forsyth 18637da2899SCharles.Forsythmainscreen := array[] of { 18737da2899SCharles.Forsyth "frame .f", 18837da2899SCharles.Forsyth "frame .f.ftop", 18937da2899SCharles.Forsyth "button .f.ftop.bs -text {Shell} -command {send butchan shell} -font /fonts/charon/bold.normal.font", 19037da2899SCharles.Forsyth "button .f.ftop.br -text {Refresh} -command {send butchan refresh} -font /fonts/charon/bold.normal.font", 19137da2899SCharles.Forsyth "grid .f.ftop.bs .f.ftop.br -row 0", 19237da2899SCharles.Forsyth "grid columnconfigure .f.ftop 2 -minsize 30", 19337da2899SCharles.Forsyth "grid .f.ftop -row 0 -column 0 -pady 2 -sticky w", 19437da2899SCharles.Forsyth "label .f.l -text { } -height 1 -bg red", 19537da2899SCharles.Forsyth "grid .f.l -row 1 -sticky ew", 19637da2899SCharles.Forsyth "grid .fbrowse -in .f -row 2 -column 0 -sticky nsew", 19737da2899SCharles.Forsyth "grid rowconfigure .f 2 -weight 1", 19837da2899SCharles.Forsyth "grid columnconfigure .f 0 -weight 1", 19937da2899SCharles.Forsyth 20037da2899SCharles.Forsyth "bind .Wm_t <Button-1> +{focus .Wm_t}", 20137da2899SCharles.Forsyth "bind .Wm_t.title <Button-1> +{focus .Wm_t}", 20237da2899SCharles.Forsyth "focus .Wm_t", 20337da2899SCharles.Forsyth}; 20437da2899SCharles.Forsyth 20537da2899SCharles.Forsythreadpath(file: File): (array of ref sys->Dir, int) 20637da2899SCharles.Forsyth{ 20737da2899SCharles.Forsyth (dirs, nil) := readdir->init(file.path, readdir->NAME | readdir->COMPACT); 20837da2899SCharles.Forsyth return (dirs, 0); 20937da2899SCharles.Forsyth} 21037da2899SCharles.Forsyth 21137da2899SCharles.Forsythrun(ctxt: ref Draw->Context, file: string) 21237da2899SCharles.Forsyth{ 21337da2899SCharles.Forsyth sys->pctl(sys->FORKNS | sys->NEWPGRP, nil); 21437da2899SCharles.Forsyth sys->chdir(browser->prevpath(file)); 21537da2899SCharles.Forsyth sh->run(ctxt, file :: nil); 21637da2899SCharles.Forsyth} 21737da2899SCharles.Forsyth 21837da2899SCharles.Forsythopenscr := array[] of { 21937da2899SCharles.Forsyth "frame .f", 22037da2899SCharles.Forsyth "scrollbar .f.sy -command {.f.t yview}", 22137da2899SCharles.Forsyth "text .f.t -yscrollcommand {.f.sy set} -bg white -font /fonts/charon/plain.normal.font", 22237da2899SCharles.Forsyth "pack .f.sy -side left -fill y", 22337da2899SCharles.Forsyth "pack .f.t -fill both -expand 1", 22437da2899SCharles.Forsyth "bind .Wm_t <Button-1> +{focus .Wm_t}", 22537da2899SCharles.Forsyth "bind .Wm_t.title <Button-1> +{focus .Wm_t}", 22637da2899SCharles.Forsyth "focus .f.t", 22737da2899SCharles.Forsyth}; 22837da2899SCharles.Forsyth 22937da2899SCharles.Forsythfopensize := ("", ""); 23037da2899SCharles.Forsyth 23137da2899SCharles.Forsythplumbing := array[] of { 23237da2899SCharles.Forsyth ("bit", "wm/view"), 23337da2899SCharles.Forsyth ("jpg", "wm/view"), 23437da2899SCharles.Forsyth}; 23537da2899SCharles.Forsyth 23637da2899SCharles.Forsythfreader(top: ref Tk->Toplevel, fd: ref sys->FD, sync: chan of int) 23737da2899SCharles.Forsyth{ 23837da2899SCharles.Forsyth sync <-= sys->pctl(0,nil); 23937da2899SCharles.Forsyth buf := array[8192] of byte; 24037da2899SCharles.Forsyth for (;;) { 24137da2899SCharles.Forsyth i := sys->read(fd, buf, len buf); 24237da2899SCharles.Forsyth if (i < 1) 24337da2899SCharles.Forsyth return; 24437da2899SCharles.Forsyth s :=""; 24537da2899SCharles.Forsyth for (j := 0; j < i; j++) { 24637da2899SCharles.Forsyth c := int buf[j]; 24737da2899SCharles.Forsyth if (c == '{' || c == '}') 24837da2899SCharles.Forsyth s[len s] = '\\'; 24937da2899SCharles.Forsyth s[len s] = c; 25037da2899SCharles.Forsyth } 25137da2899SCharles.Forsyth tk->cmd(top, ".f.t insert end {"+s+"}; update"); 25237da2899SCharles.Forsyth } 25337da2899SCharles.Forsyth} 25437da2899SCharles.Forsyth 25537da2899SCharles.Forsythopenfile(ctxt: ref draw->Context, file, title: string, writeable: int) 25637da2899SCharles.Forsyth{ 25737da2899SCharles.Forsyth ext := getext(file); 25837da2899SCharles.Forsyth plumb := getplumb(ext); 25937da2899SCharles.Forsyth if (plumb != nil) { 26037da2899SCharles.Forsyth sh->run(ctxt, plumb :: file :: nil); 26137da2899SCharles.Forsyth return; 26237da2899SCharles.Forsyth } 26337da2899SCharles.Forsyth button := tkclient->Appl; 26437da2899SCharles.Forsyth if (writeable) 26537da2899SCharles.Forsyth button = button | tkclient->OK; 26637da2899SCharles.Forsyth (top, titlebar) := tkclient->toplevel(ctxt, "", title, button); 26737da2899SCharles.Forsyth tkcmds(top, openscr); 26837da2899SCharles.Forsyth tkcmd(top,"pack .f -fill both -expand 1"); 26937da2899SCharles.Forsyth tkcmd(top,"pack propagate . 0"); 27037da2899SCharles.Forsyth (w,h) := fopensize; 27137da2899SCharles.Forsyth if (w != "" && h != "") 27237da2899SCharles.Forsyth tkcmd(top, ". configure -width "+w+" -height "+h); 27337da2899SCharles.Forsyth killpid := -1; 27437da2899SCharles.Forsyth fd := sys->open(file, sys->OREAD); 27537da2899SCharles.Forsyth if (fd != nil) { 27637da2899SCharles.Forsyth sync := chan of int; 27737da2899SCharles.Forsyth spawn freader(top, fd, sync); 27837da2899SCharles.Forsyth killpid = <-sync; 27937da2899SCharles.Forsyth } 28037da2899SCharles.Forsyth tkcmd(top, "update"); 28137da2899SCharles.Forsyth tkclient->onscreen(top, nil); 28237da2899SCharles.Forsyth tkclient->startinput(top, "kbd"::"ptr"::nil); 28337da2899SCharles.Forsyth main: for (;;) { 28437da2899SCharles.Forsyth alt { 28537da2899SCharles.Forsyth s := <-top.ctxt.kbd => 28637da2899SCharles.Forsyth tk->keyboard(top, s); 28737da2899SCharles.Forsyth s := <-top.ctxt.ptr => 28837da2899SCharles.Forsyth tk->pointer(top, *s); 28937da2899SCharles.Forsyth 29037da2899SCharles.Forsyth title = <-top.ctxt.ctl or 29137da2899SCharles.Forsyth title = <-top.wreq or 29237da2899SCharles.Forsyth title = <-titlebar => 29337da2899SCharles.Forsyth if (title == "exit" || title == "ok") 29437da2899SCharles.Forsyth break main; 29537da2899SCharles.Forsyth tkclient->wmctl(top, title); 29637da2899SCharles.Forsyth } 29737da2899SCharles.Forsyth } 29837da2899SCharles.Forsyth if (killpid != -1) 29937da2899SCharles.Forsyth kill(killpid); 30037da2899SCharles.Forsyth fopensize = (tkcmd(top, ". cget -width"), tkcmd(top, ". cget -height")); 30137da2899SCharles.Forsyth if (title == "ok") { 30237da2899SCharles.Forsyth (n, dir) := sys->stat(file); 30337da2899SCharles.Forsyth if (n != -1) { 30437da2899SCharles.Forsyth fd = sys->create(file, sys->OWRITE, dir.mode); 30537da2899SCharles.Forsyth if (fd != nil) { 30637da2899SCharles.Forsyth s := tkcmd(top, ".f.t get 1.0 end"); 30737da2899SCharles.Forsyth sys->fprint(fd,"%s",s); 30837da2899SCharles.Forsyth fd = nil; 30937da2899SCharles.Forsyth } 31037da2899SCharles.Forsyth } 31137da2899SCharles.Forsyth } 31237da2899SCharles.Forsyth} 31337da2899SCharles.Forsyth 31437da2899SCharles.Forsythbadmod(path: string) 31537da2899SCharles.Forsyth{ 31637da2899SCharles.Forsyth sys->print("FBrowse: failed to load: %s\n",path); 31737da2899SCharles.Forsyth exit; 31837da2899SCharles.Forsyth} 31937da2899SCharles.Forsyth 32037da2899SCharles.Forsythtkcmd(top: ref Tk->Toplevel, cmd: string): string 32137da2899SCharles.Forsyth{ 32237da2899SCharles.Forsyth e := tk->cmd(top, cmd); 32337da2899SCharles.Forsyth if (e != "" && e[0] == '!') 32437da2899SCharles.Forsyth sys->print("Tk error: '%s': %s\n",cmd,e); 32537da2899SCharles.Forsyth return e; 32637da2899SCharles.Forsyth} 32737da2899SCharles.Forsyth 32837da2899SCharles.Forsythtkcmds(top: ref Tk->Toplevel, a: array of string) 32937da2899SCharles.Forsyth{ 33037da2899SCharles.Forsyth for (j := 0; j < len a; j++) 33137da2899SCharles.Forsyth tkcmd(top, a[j]); 33237da2899SCharles.Forsyth} 33337da2899SCharles.Forsyth 33437da2899SCharles.Forsythnactionbuttons := 0; 33537da2899SCharles.Forsythactionbutton(top: ref Tk->Toplevel, path, tkpath: string) 33637da2899SCharles.Forsyth{ 33737da2899SCharles.Forsyth (n, dir) := sys->stat(path); 33837da2899SCharles.Forsyth for (i := 0; i < nactionbuttons; i++) { 33937da2899SCharles.Forsyth tkcmd(top, "grid forget .f.ftop.baction"+string i); 34037da2899SCharles.Forsyth tkcmd(top, "destroy .f.ftop.baction"+string i); 34137da2899SCharles.Forsyth } 34237da2899SCharles.Forsyth if (path == nil || n == -1 || dir.mode & sys->DMDIR) { 34337da2899SCharles.Forsyth nactionbuttons = 0; 34437da2899SCharles.Forsyth return; 34537da2899SCharles.Forsyth } 34637da2899SCharles.Forsyth buttons : list of (string,string) = nil; 34737da2899SCharles.Forsyth 34837da2899SCharles.Forsyth if (dir.mode & 8r222) 34937da2899SCharles.Forsyth buttons = ("Open", "write "+tkpath) :: buttons; 35037da2899SCharles.Forsyth else if (dir.mode & 8r444) 35137da2899SCharles.Forsyth buttons = ("Open", "read "+tkpath) :: buttons; 35237da2899SCharles.Forsyth if (len dir.name > 4 && dir.name[len dir.name - 4:] == ".dis" || dir.mode & 8r111) 35337da2899SCharles.Forsyth buttons = ("Run", "run "+tkpath) :: buttons; 35437da2899SCharles.Forsyth 35537da2899SCharles.Forsyth nactionbuttons = len buttons; 35637da2899SCharles.Forsyth for (i = 0; i < nactionbuttons; i++) { 35737da2899SCharles.Forsyth name := ".f.ftop.baction"+string i+" "; 35837da2899SCharles.Forsyth (text,cmd) := hd buttons; 35937da2899SCharles.Forsyth tkcmd(top, "button "+name+"-text {"+text+"} "+ 36037da2899SCharles.Forsyth "-font /fonts/charon/bold.normal.font "+ 36137da2899SCharles.Forsyth "-command {send butchan "+cmd+"}"); 36237da2899SCharles.Forsyth tkcmd(top, "grid "+name+" -row 0 -column "+string (4+i)); 36337da2899SCharles.Forsyth buttons = tl buttons; 36437da2899SCharles.Forsyth } 36537da2899SCharles.Forsyth} 36637da2899SCharles.Forsyth 36737da2899SCharles.Forsythgetext(file: string): string 36837da2899SCharles.Forsyth{ 369*170ff9d4SCharles Forsyth (nil, lst) := sys->tokenize(file, "."); 37037da2899SCharles.Forsyth for (; tl lst != nil; lst = tl lst) 37137da2899SCharles.Forsyth ; 37237da2899SCharles.Forsyth return hd lst; 37337da2899SCharles.Forsyth} 37437da2899SCharles.Forsyth 37537da2899SCharles.Forsythgetplumb(ext: string): string 37637da2899SCharles.Forsyth{ 37737da2899SCharles.Forsyth for (i := 0; i < len plumbing; i++) 37837da2899SCharles.Forsyth if (ext == plumbing[i].t0) 37937da2899SCharles.Forsyth return plumbing[i].t1; 38037da2899SCharles.Forsyth return nil; 38137da2899SCharles.Forsyth} 38237da2899SCharles.Forsyth 38337da2899SCharles.Forsythkill(pid: int) 38437da2899SCharles.Forsyth{ 38537da2899SCharles.Forsyth if ((fd := sys->open("/prog/" + string pid + "/ctl", Sys->OWRITE)) != nil) 38637da2899SCharles.Forsyth sys->fprint(fd, "kill"); 38737da2899SCharles.Forsyth} 388