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