diff options
Diffstat (limited to 'appl/lib/dbsrv.b')
| -rw-r--r-- | appl/lib/dbsrv.b | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/appl/lib/dbsrv.b b/appl/lib/dbsrv.b new file mode 100644 index 00000000..859e3150 --- /dev/null +++ b/appl/lib/dbsrv.b @@ -0,0 +1,124 @@ +implement DBserver; + +include "sys.m"; + sys: Sys; + +include "draw.m"; + +include "keyring.m"; + +include "security.m"; + +include "db.m"; # For now. + +stderr: ref Sys->FD; + +DBserver : module +{ + init: fn(ctxt: ref Draw->Context, argv: list of string); +}; + +# argv is a list of Inferno supported algorithms from Security->Auth + +init(nil: ref Draw->Context, argv: list of string) +{ + sys = load Sys Sys->PATH; + stdin := sys->fildes(0); + stderr = sys->fildes(2); + if(argv != nil) + argv = tl argv; + if(argv == nil) + err("no algorithm list"); + + kr := load Keyring Keyring->PATH; + if(nil == kr) + err(sys->sprint("can't load Keyring: %r")); + + auth := load Auth Auth->PATH; + if(auth == nil) + err(sys->sprint("can't load Auth: %r")); + + error := auth->init(); + if(error != nil) + err(sys->sprint("Auth init failed: %s", error)); + + ai := kr->readauthinfo("/usr/"+user()+"/keyring/default"); + + (client_fd, info_or_err) := auth->server(argv, ai, stdin, 1); + if(client_fd == nil) + err(sys->sprint("can't authenticate client: %s", info_or_err)); + + auth = nil; + kr = nil; + + sys->pctl(Sys->FORKNS|Sys->NEWPGRP, nil); + + # run the infdb database program in the host system using /cmd + + cmdfd := sys->open("/cmd/clone", sys->ORDWR); + if (cmdfd == nil) + err(sys->sprint("can't open /cmd/clone: %r")); + + buf := array [20] of byte; + n := sys->read(cmdfd, buf, len buf); + if(n <= 0) + err(sys->sprint("can't read /cmd/clone: %r")); + cmddir := string buf[0:n]; + + if (sys->fprint(cmdfd, "exec infdb") <= 0) + err(sys->sprint("can't start infdb via /cmd/clone: %r")); + + datafile := "/cmd/" + cmddir + "/data"; + infdb_fd := sys->open(datafile, Sys->ORDWR); + if (infdb_fd == nil) + err(sys->sprint("can't open %s: %r", datafile)); + + spawn dbxfer(infdb_fd, client_fd, "client"); + + dbxfer(client_fd, infdb_fd, "infdb"); + sys->fprint(infdb_fd, "X1 0 0 \n"); +} + +dbxfer(source, sink: ref Sys->FD, tag: string) +{ + buf := array [Sys->ATOMICIO] of byte; + while((nr := sys->read(source, buf, len buf)) > 0) + if(sys->write(sink, buf, nr) != nr){ + sys->fprint(stderr, "dbsrv: write to %s failed: %r\n", tag); + shutdown(); + } + if(nr < 0){ + sys->fprint(stderr, "dbsrv: reading data for %s: %r\n", tag); + shutdown(); + } +} + +shutdown() +{ + pid := sys->pctl(0, nil); + fd := sys->open("#p/"+string pid+"/ctl", Sys->OWRITE); + if(fd == nil || sys->fprint(fd, "killgrp") < 0) + err(sys->sprint("can't kill group %d: %r", pid)); +} + +err(s: string) +{ + sys->fprint(stderr, "dbsrv: %s\n", s); + raise "fail:error"; +} + +user(): string +{ + sys = load Sys Sys->PATH; + + fd := sys->open("/dev/user", sys->OREAD); + if(fd == nil) + return ""; + + buf := array[Sys->NAMEMAX] of byte; + n := sys->read(fd, buf, len buf); + if(n < 0) + return ""; + + return string buf[0:n]; +} |
