ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /appl/lib/dbsrv.b/
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];
}