implement DBserver; include "sys.m"; sys: Sys; stdin, stderr: ref Sys->FD; include "draw.m"; include "keyring.m"; kr: Keyring; include "security.m"; auth: Auth; include "db.m"; # For now. 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)); sys->pctl(Sys->FORKNS|Sys->NEWPGRP, nil); # run the infdb database program in the host system using /cmd ctl_fd := sys->open("/cmd/clone", sys->ORDWR); if (ctl_fd == nil) err(sys->sprint("can't open /cmd/clone: %r")); n_buf := array [20] of byte; num_read := sys->read(ctl_fd, n_buf, len n_buf); if (num_read == 0) err(sys->sprint("can't read /cmd/clone: %r")); n_string := string n_buf[0:num_read]; command := "exec infdb"; num_written := sys->write(ctl_fd, array of byte command, len command); if (num_written != len command) err(sys->sprint("can't start %s (by write to /cmd/clone): %r", command)); datafile := "/cmd/" + n_string + "/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); exit; } user(): string { sys = load Sys Sys->PATH; fd := sys->open("/dev/user", sys->OREAD); if(fd == nil) return ""; buf := array[128] of byte; n := sys->read(fd, buf, len buf); if(n < 0) return ""; return string buf[0:n]; }