xref: /inferno-os/appl/lib/dbsrv.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
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