xref: /inferno-os/appl/lib/msgio.b (revision d9c5943558618085062d60aab36ef94e12fa81c8)
1implement Msgio;
2
3# probably need Authio or Auth instead, to include Authinfo, Certificate and signing operations?
4# eliminates certificates and sigalgs from Keyring
5# might be better just to have mp.m and sec.m?
6# general signature module?
7# Keyring->dhparams is is only needed by createsignerkey (and others creating Authinfo)
8# should also improve pkcs
9
10include "sys.m";
11	sys: Sys;
12
13include "keyring.m";
14
15include "msgio.m";
16
17init()
18{
19	sys = load Sys Sys->PATH;
20}
21
22seterr(r: int)
23{
24	if(r > 0)
25		sys->werrstr("input or format error");
26	else if(r == 0)
27		sys->werrstr("hungup");
28}
29
30#
31# i/o on a channel that might or might not retain record boundaries
32#
33getmsg(fd: ref Sys->FD): array of byte
34{
35	num := array[5] of byte;
36	r := sys->readn(fd, num, len num);
37	if(r != len num) {
38		seterr(r);
39		return nil;
40	}
41	h := string num;
42	if(h[0] == '!')
43		m := int h[1:];
44	else
45		m = int h;
46	if(m < 0 || m > Maxmsg) {
47		seterr(1);
48		return nil;
49	}
50	buf := array[m] of byte;
51	r = sys->readn(fd, buf, m);
52	if(r != m){
53		seterr(r);
54		return nil;
55	}
56	if(h[0] == '!'){
57		sys->werrstr(string buf);
58		return nil;
59	}
60	return buf;
61}
62
63sendmsg(fd: ref Sys->FD, buf: array of byte, n: int): int
64{
65	if(sys->fprint(fd, "%4.4d\n", n) < 0)
66		return -1;
67	return sys->write(fd, buf, n);
68}
69
70senderrmsg(fd: ref Sys->FD, s: string): int
71{
72	buf := array of byte s;
73	if(sys->fprint(fd, "!%3.3d\n", len buf) < 0)
74		return -1;
75	if(sys->write(fd, buf, len buf) <= 0)
76		return -1;
77	return 0;
78}
79
80#
81# i/o on a delimited channel
82#
83getbuf(fd: ref Sys->FD, buf: array of byte, n: int): (int, string)
84{
85	n = sys->read(fd, buf, n);
86	if(n <= 0){
87		seterr(n);
88		return (-1, sys->sprint("%r"));
89	}
90	if(buf[0] == byte 0)
91		return (n, nil);
92	if(buf[0] != byte 16rFF){
93		# garbled, possibly the wrong encryption
94		return (-1, "failure");
95	}
96	# error string
97	if(--n < 1)
98		return (-1, "unknown");
99	return (-1, string buf[1:]);
100}
101
102getbytearray(fd: ref Sys->FD): (array of byte, string)
103{
104	buf := array[Maxmsg] of byte;
105	(n, err) := getbuf(fd, buf, len buf);
106	if(n < 0)
107		return (nil, err);
108	return (buf[1: n], nil);
109}
110
111getstring(fd: ref Sys->FD): (string, string)
112{
113	(a, err) := getbytearray(fd);
114	if(a != nil)
115		return (string a, err);
116	return (nil, err);
117}
118
119putbuf(fd: ref Sys->FD, data: array of byte, n: int): int
120{
121	buf := array[Maxmsg] of byte;
122	if(n < 0) {
123		buf[0] = byte 16rFF;
124		n = -n;
125	}else
126		buf[0] = byte 0;
127	if(n >= Maxmsg)
128		n = Maxmsg-1;
129	buf[1:] = data;
130	return sys->write(fd, buf, n+1);
131}
132
133putstring(fd: ref Sys->FD, s: string): int
134{
135	a := array of byte s;
136	return putbuf(fd, a, len a);
137}
138
139putbytearray(fd: ref Sys->FD, a: array of byte, n: int): int
140{
141	if(n > len a)
142		n = len a;
143	return putbuf(fd, a, n);
144}
145
146puterror(fd: ref Sys->FD, s: string): int
147{
148	if(s == nil)
149		s = "unknown";
150	a := array of byte s;
151	return putbuf(fd, a, -len a);
152}
153