# # Quering paths for network gadgets # implement Query; include "sys.m"; sys: Sys; fildes, write, open, read, fprint, MBEFORE, OREAD, print, bind, MREPL, sprint, MCREATE, FD: import sys; include "draw.m"; include "registries.m"; regs: Registries; Service, Registered, Attributes, Registry: import regs; include "error.m"; err: Error; checkload, stderr, error, kill: import err; include "arg.m"; arg: Arg; usage: import arg; include "env.m"; env: Env; getenv: import env; include "query.m"; readall(n: string) : string { fd := open(n, OREAD); if (fd == nil) return nil; max : con int 1024; data := array[max] of byte; tot := nr := 0; do { nr = read(fd, data[tot:], len data - tot); if (nr > 0) tot += nr; } while(nr > 0 && tot < len data); s := string data[0:tot]; if (s[len s - 1] == '\n') s = s[0:len s - 1]; return s; } userloc(): string { l := readall("/devs/who/" + getenv("user") + "/where"); if (l == nil) l = getenv("location"); else if (l[len l - 1] == '\n') l = l[0:len l -1]; return l; } expand(n, v: string): string { if (n == "loc"){ if (v == "$user") return userloc(); if (v == "$term") return getenv("location"); } if (n == "arch" && v == "$term") return getenv("emuhost") + getenv("cputype"); return v; } lookup(args: list of string) : (list of string, string) { if (sys == nil){ sys = load Sys Sys->PATH; err = load Error Error->PATH; err->init(); regs = checkload(load Registries Registries->PATH, Registries->PATH); regs->init(); env = checkload(load Env Env->PATH, Env->PATH); } nargs := len args; if (nargs == 0 || (nargs%2) != 0) return(nil, "odd lookup arguments"); reg := Registry.new(nil); if (reg == nil) return (nil, sprint("can't locate registry: %r")); l : list of (string, string); while(len args > 0){ # could add $min as value: collect name appart, and later, # after reg.find(), put first the entry with min. value for name (name, val) := (hd args, expand(hd args, hd tl args)); l = (name, val) :: l; args = tl args; args = tl args; } (svcs, e) := reg.find(l); if (e != nil) return (nil, sprint("query: %s\n", e)); paths: list of string; while(svcs != nil){ s := hd svcs; svcs = tl svcs; path := s.attrs.get("path"); if (path == nil) fprint(stderr, "no path for svc\n"); else paths = path :: paths; } return (paths, nil); } init(nil: ref Draw->Context, args: list of string) { mnt: string; sys = load Sys Sys->PATH; err = load Error Error->PATH; err->init(); regs = checkload(load Registries Registries->PATH, Registries->PATH); regs->init(); arg = checkload(load Arg Arg->PATH, Arg->PATH); arg->init(args); arg->setusage("query [-m mnt] [-u mnt] attr val..."); env = checkload(load Env Env->PATH, Env->PATH); union := 0; while((opt := arg->opt()) != 0) { case opt { 'u' => mnt = arg->earg(); union = 1; 'm' => mnt = arg->earg(); * => usage(); } } (paths, e) := lookup(arg->argv()); if (e != nil) error(e); if (len paths == 0) error("resource not found"); if (mnt == nil) for(; paths != nil; paths = tl paths) print("%s\n", hd paths); else { if (bind(hd paths, mnt, MREPL|MCREATE) < 0) error(sprint("query: bind: %r")); if (union){ for (paths = tl paths; paths != nil; paths = tl paths) if (bind(hd paths, mnt, MBEFORE|MCREATE) < 0) error(sprint("query: bind: %r")); } } }