1implement DBserver; 2 3include "sys.m"; 4 sys: Sys; 5 6include "draw.m"; 7 8include "keyring.m"; 9 10include "security.m"; 11 12include "db.m"; # For now. 13 14stderr: ref Sys->FD; 15 16DBserver : module 17{ 18 init: fn(ctxt: ref Draw->Context, argv: list of string); 19}; 20 21# argv is a list of Inferno supported algorithms from Security->Auth 22 23init(nil: ref Draw->Context, argv: list of string) 24{ 25 sys = load Sys Sys->PATH; 26 stdin := sys->fildes(0); 27 stderr = sys->fildes(2); 28 if(argv != nil) 29 argv = tl argv; 30 if(argv == nil) 31 err("no algorithm list"); 32 33 kr := load Keyring Keyring->PATH; 34 if(nil == kr) 35 err(sys->sprint("can't load Keyring: %r")); 36 37 auth := load Auth Auth->PATH; 38 if(auth == nil) 39 err(sys->sprint("can't load Auth: %r")); 40 41 error := auth->init(); 42 if(error != nil) 43 err(sys->sprint("Auth init failed: %s", error)); 44 45 ai := kr->readauthinfo("/usr/"+user()+"/keyring/default"); 46 47 (client_fd, info_or_err) := auth->server(argv, ai, stdin, 1); 48 if(client_fd == nil) 49 err(sys->sprint("can't authenticate client: %s", info_or_err)); 50 51 auth = nil; 52 kr = nil; 53 54 sys->pctl(Sys->FORKNS|Sys->NEWPGRP, nil); 55 56 # run the infdb database program in the host system using /cmd 57 58 cmdfd := sys->open("/cmd/clone", sys->ORDWR); 59 if (cmdfd == nil) 60 err(sys->sprint("can't open /cmd/clone: %r")); 61 62 buf := array [20] of byte; 63 n := sys->read(cmdfd, buf, len buf); 64 if(n <= 0) 65 err(sys->sprint("can't read /cmd/clone: %r")); 66 cmddir := string buf[0:n]; 67 68 if (sys->fprint(cmdfd, "exec infdb") <= 0) 69 err(sys->sprint("can't start infdb via /cmd/clone: %r")); 70 71 datafile := "/cmd/" + cmddir + "/data"; 72 infdb_fd := sys->open(datafile, Sys->ORDWR); 73 if (infdb_fd == nil) 74 err(sys->sprint("can't open %s: %r", datafile)); 75 76 spawn dbxfer(infdb_fd, client_fd, "client"); 77 78 dbxfer(client_fd, infdb_fd, "infdb"); 79 sys->fprint(infdb_fd, "X1 0 0 \n"); 80} 81 82dbxfer(source, sink: ref Sys->FD, tag: string) 83{ 84 buf := array [Sys->ATOMICIO] of byte; 85 while((nr := sys->read(source, buf, len buf)) > 0) 86 if(sys->write(sink, buf, nr) != nr){ 87 sys->fprint(stderr, "dbsrv: write to %s failed: %r\n", tag); 88 shutdown(); 89 } 90 if(nr < 0){ 91 sys->fprint(stderr, "dbsrv: reading data for %s: %r\n", tag); 92 shutdown(); 93 } 94} 95 96shutdown() 97{ 98 pid := sys->pctl(0, nil); 99 fd := sys->open("#p/"+string pid+"/ctl", Sys->OWRITE); 100 if(fd == nil || sys->fprint(fd, "killgrp") < 0) 101 err(sys->sprint("can't kill group %d: %r", pid)); 102} 103 104err(s: string) 105{ 106 sys->fprint(stderr, "dbsrv: %s\n", s); 107 raise "fail:error"; 108} 109 110user(): string 111{ 112 sys = load Sys Sys->PATH; 113 114 fd := sys->open("/dev/user", sys->OREAD); 115 if(fd == nil) 116 return ""; 117 118 buf := array[Sys->NAMEMAX] of byte; 119 n := sys->read(fd, buf, len buf); 120 if(n < 0) 121 return ""; 122 123 return string buf[0:n]; 124} 125