summaryrefslogtreecommitdiff
path: root/appl/cmd/ssh/cons.b
blob: bea7733d276a9db5c0dacd35ce1b2a920836eacd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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);
}