summaryrefslogtreecommitdiff
path: root/appl/cmd/ssh/cons.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/cmd/ssh/cons.b')
-rw-r--r--appl/cmd/ssh/cons.b116
1 files changed, 116 insertions, 0 deletions
diff --git a/appl/cmd/ssh/cons.b b/appl/cmd/ssh/cons.b
new file mode 100644
index 00000000..bea7733d
--- /dev/null
+++ b/appl/cmd/ssh/cons.b
@@ -0,0 +1,116 @@
+# promptstring
+
+RAWON_STR := "*";
+
+RAWON : con 0;
+RAWOFF : con 1;
+
+promptstring(prompt, def: string, mode: int): string
+{
+ if(mode == RAWON || def == nil)
+ sys->fprint(stdout, "%s: ", prompt);
+ else
+ sys->fprint(stdout, "%s [%s]: ", prompt, def);
+ (eof, resp) := readline(stdin, mode);
+ if(eof)
+ exit;
+ if(resp == nil)
+ return def;
+ return resp;
+}
+
+readline(fd: ref Sys->FD, mode: int): (int, string)
+{
+ i: int;
+ eof: int;
+ fdctl: ref Sys->FD;
+
+ eof = 0;
+ buf := array[128] of byte;
+ tmp := array[128] of byte;
+
+ if(mode == RAWON){
+ fdctl = sys->open("/dev/consctl", sys->OWRITE);
+ if(fdctl == nil || sys->write(fdctl,array of byte "rawon",5) != 5){
+ sys->fprint(stderr, "unable to change console mode");
+ return (1,nil);
+ }
+ }
+
+ for(sofar := 0; sofar < 128; sofar += i){
+ i = sys->read(fd, tmp, 128 - sofar);
+ if(i <= 0){
+ eof = 1;
+ break;
+ }
+ if(tmp[i-1] == byte '\n'){
+ for(j := 0; j < i-1; j++){
+ buf[sofar+j] = tmp[j];
+ if(mode == RAWON && RAWON_STR != nil)
+ sys->write(stdout,array of byte RAWON_STR,1);
+ }
+ sofar += j;
+ if(mode == RAWON)
+ sys->write(stdout,array of byte "\n",1);
+ break;
+ }
+ else {
+ for(j := 0; j < i; j++){
+ buf[sofar+j] = tmp[j];
+ if(mode == RAWON && RAWON_STR != nil)
+ sys->write(stdout,array of byte RAWON_STR,1);
+ }
+ }
+ }
+ if(mode == RAWON)
+ sys->write(fdctl,array of byte "rawoff",6);
+ return (eof, string buf[0:sofar]);
+}
+
+# from keyfs
+
+readconsline(prompt: string, raw: int): (string, string)
+{
+ fd := sys->open("/dev/cons", Sys->ORDWR);
+ if(fd == nil)
+ return (nil, sys->sprint("can't open cons: %r"));
+ sys->fprint(fd, "%s", prompt);
+ fdctl: ref Sys->FD;
+ if(raw){
+ fdctl = sys->open("/dev/consctl", sys->OWRITE);
+ if(fdctl == nil || sys->fprint(fdctl, "rawon") < 0)
+ return (nil, sys->sprint("can't open consctl: %r"));
+ }
+ line := array[256] of byte;
+ o := 0;
+ err: string;
+ buf := array[1] of byte;
+ Read:
+ while((r := sys->read(fd, buf, len buf)) > 0){
+ c := int buf[0];
+ case c {
+ 16r7F =>
+ err = "interrupt";
+ break Read;
+ '\b' =>
+ if(o > 0)
+ o--;
+ '\n' or '\r' or 16r4 =>
+ break Read;
+ * =>
+ if(o > len line){
+ err = "line too long";
+ break Read;
+ }
+ line[o++] = byte c;
+ }
+ }
+ sys->fprint(fd, "\n");
+ if(r < 0)
+ err = sys->sprint("can't read cons: %r");
+ if(raw)
+ sys->fprint(fdctl, "rawoff");
+ if(err != nil)
+ return (nil, err);
+ return (string line[0:o], err);
+}