xref: /inferno-os/os/boot/pc/conf.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include "u.h"
2*74a4d8c2SCharles.Forsyth #include "lib.h"
3*74a4d8c2SCharles.Forsyth #include "mem.h"
4*74a4d8c2SCharles.Forsyth #include "dat.h"
5*74a4d8c2SCharles.Forsyth #include "fns.h"
6*74a4d8c2SCharles.Forsyth #include "io.h"
7*74a4d8c2SCharles.Forsyth 
8*74a4d8c2SCharles.Forsyth #include "fs.h"
9*74a4d8c2SCharles.Forsyth 
10*74a4d8c2SCharles.Forsyth /*
11*74a4d8c2SCharles.Forsyth  * Where configuration info is left for the loaded programme.
12*74a4d8c2SCharles.Forsyth  * This will turn into a structure as more is done by the boot loader
13*74a4d8c2SCharles.Forsyth  * (e.g. why parse the .ini file twice?).
14*74a4d8c2SCharles.Forsyth  * There are 3584 bytes available at CONFADDR.
15*74a4d8c2SCharles.Forsyth  *
16*74a4d8c2SCharles.Forsyth  * The low-level boot routines in l.s leave data for us at CONFADDR,
17*74a4d8c2SCharles.Forsyth  * which we pick up before reading the plan9.ini file.
18*74a4d8c2SCharles.Forsyth  */
19*74a4d8c2SCharles.Forsyth #define BOOTLINELEN	64
20*74a4d8c2SCharles.Forsyth #define BOOTARGS	((char*)(CONFADDR+BOOTLINELEN))
21*74a4d8c2SCharles.Forsyth #define	BOOTARGSLEN	(3584-0x200-BOOTLINELEN)
22*74a4d8c2SCharles.Forsyth #define	MAXCONF		100
23*74a4d8c2SCharles.Forsyth 
24*74a4d8c2SCharles.Forsyth static char *confname[MAXCONF];
25*74a4d8c2SCharles.Forsyth static char *confval[MAXCONF];
26*74a4d8c2SCharles.Forsyth static int nconf;
27*74a4d8c2SCharles.Forsyth 
28*74a4d8c2SCharles.Forsyth extern char **ini;
29*74a4d8c2SCharles.Forsyth 
30*74a4d8c2SCharles.Forsyth typedef struct {
31*74a4d8c2SCharles.Forsyth 	char*	name;
32*74a4d8c2SCharles.Forsyth 	int	start;
33*74a4d8c2SCharles.Forsyth 	int	end;
34*74a4d8c2SCharles.Forsyth } Mblock;
35*74a4d8c2SCharles.Forsyth 
36*74a4d8c2SCharles.Forsyth typedef struct {
37*74a4d8c2SCharles.Forsyth 	char*	tag;
38*74a4d8c2SCharles.Forsyth 	Mblock*	mb;
39*74a4d8c2SCharles.Forsyth } Mitem;
40*74a4d8c2SCharles.Forsyth 
41*74a4d8c2SCharles.Forsyth static Mblock mblock[MAXCONF];
42*74a4d8c2SCharles.Forsyth static int nmblock;
43*74a4d8c2SCharles.Forsyth static Mitem mitem[MAXCONF];
44*74a4d8c2SCharles.Forsyth static int nmitem;
45*74a4d8c2SCharles.Forsyth static char* mdefault;
46*74a4d8c2SCharles.Forsyth static char mdefaultbuf[10];
47*74a4d8c2SCharles.Forsyth static int mtimeout;
48*74a4d8c2SCharles.Forsyth 
49*74a4d8c2SCharles.Forsyth static char*
comma(char * line,char ** residue)50*74a4d8c2SCharles.Forsyth comma(char* line, char** residue)
51*74a4d8c2SCharles.Forsyth {
52*74a4d8c2SCharles.Forsyth 	char *q, *r;
53*74a4d8c2SCharles.Forsyth 
54*74a4d8c2SCharles.Forsyth 	if((q = strchr(line, ',')) != nil){
55*74a4d8c2SCharles.Forsyth 		*q++ = 0;
56*74a4d8c2SCharles.Forsyth 		if(*q == ' ')
57*74a4d8c2SCharles.Forsyth 			q++;
58*74a4d8c2SCharles.Forsyth 	}
59*74a4d8c2SCharles.Forsyth 	*residue = q;
60*74a4d8c2SCharles.Forsyth 
61*74a4d8c2SCharles.Forsyth 	if((r = strchr(line, ' ')) != nil)
62*74a4d8c2SCharles.Forsyth 		*r = 0;
63*74a4d8c2SCharles.Forsyth 
64*74a4d8c2SCharles.Forsyth 	if(*line == ' ')
65*74a4d8c2SCharles.Forsyth 		line++;
66*74a4d8c2SCharles.Forsyth 	return line;
67*74a4d8c2SCharles.Forsyth }
68*74a4d8c2SCharles.Forsyth 
69*74a4d8c2SCharles.Forsyth static Mblock*
findblock(char * name,char ** residue)70*74a4d8c2SCharles.Forsyth findblock(char* name, char** residue)
71*74a4d8c2SCharles.Forsyth {
72*74a4d8c2SCharles.Forsyth 	int i;
73*74a4d8c2SCharles.Forsyth 	char *p;
74*74a4d8c2SCharles.Forsyth 
75*74a4d8c2SCharles.Forsyth 	p = comma(name, residue);
76*74a4d8c2SCharles.Forsyth 	for(i = 0; i < nmblock; i++){
77*74a4d8c2SCharles.Forsyth 		if(strcmp(p, mblock[i].name) == 0)
78*74a4d8c2SCharles.Forsyth 			return &mblock[i];
79*74a4d8c2SCharles.Forsyth 	}
80*74a4d8c2SCharles.Forsyth 	return nil;
81*74a4d8c2SCharles.Forsyth }
82*74a4d8c2SCharles.Forsyth 
83*74a4d8c2SCharles.Forsyth static Mitem*
finditem(char * name,char ** residue)84*74a4d8c2SCharles.Forsyth finditem(char* name, char** residue)
85*74a4d8c2SCharles.Forsyth {
86*74a4d8c2SCharles.Forsyth 	int i;
87*74a4d8c2SCharles.Forsyth 	char *p;
88*74a4d8c2SCharles.Forsyth 
89*74a4d8c2SCharles.Forsyth 	p = comma(name, residue);
90*74a4d8c2SCharles.Forsyth 	for(i = 0; i < nmitem; i++){
91*74a4d8c2SCharles.Forsyth 		if(strcmp(p, mitem[i].mb->name) == 0)
92*74a4d8c2SCharles.Forsyth 			return &mitem[i];
93*74a4d8c2SCharles.Forsyth 	}
94*74a4d8c2SCharles.Forsyth 	return nil;
95*74a4d8c2SCharles.Forsyth }
96*74a4d8c2SCharles.Forsyth 
97*74a4d8c2SCharles.Forsyth static void
parsemenu(char * str,char * scratch,int len)98*74a4d8c2SCharles.Forsyth parsemenu(char* str, char* scratch, int len)
99*74a4d8c2SCharles.Forsyth {
100*74a4d8c2SCharles.Forsyth 	Mitem *mi;
101*74a4d8c2SCharles.Forsyth 	Mblock *mb, *menu;
102*74a4d8c2SCharles.Forsyth 	char buf[20], *p, *q, *line[MAXCONF];
103*74a4d8c2SCharles.Forsyth 	int i, inblock, n, show;
104*74a4d8c2SCharles.Forsyth 
105*74a4d8c2SCharles.Forsyth 	inblock = 0;
106*74a4d8c2SCharles.Forsyth 	menu = nil;
107*74a4d8c2SCharles.Forsyth 	memmove(scratch, str, len);
108*74a4d8c2SCharles.Forsyth 	n = getfields(scratch, line, MAXCONF, '\n');
109*74a4d8c2SCharles.Forsyth 	if(n >= MAXCONF)
110*74a4d8c2SCharles.Forsyth 		print("warning: possibly too many lines in plan9.ini\n");
111*74a4d8c2SCharles.Forsyth 	for(i = 0; i < n; i++){
112*74a4d8c2SCharles.Forsyth 		p = line[i];
113*74a4d8c2SCharles.Forsyth 		if(inblock && *p == '['){
114*74a4d8c2SCharles.Forsyth 			mblock[nmblock].end = i;
115*74a4d8c2SCharles.Forsyth 			if(strcmp(mblock[nmblock].name, "menu") == 0)
116*74a4d8c2SCharles.Forsyth 				menu = &mblock[nmblock];
117*74a4d8c2SCharles.Forsyth 			nmblock++;
118*74a4d8c2SCharles.Forsyth 			inblock = 0;
119*74a4d8c2SCharles.Forsyth 		}
120*74a4d8c2SCharles.Forsyth 		if(*p == '['){
121*74a4d8c2SCharles.Forsyth 			if(nmblock == 0 && i != 0){
122*74a4d8c2SCharles.Forsyth 				mblock[nmblock].name = "common";
123*74a4d8c2SCharles.Forsyth 				mblock[nmblock].start = 0;
124*74a4d8c2SCharles.Forsyth 				mblock[nmblock].end = i;
125*74a4d8c2SCharles.Forsyth 				nmblock++;
126*74a4d8c2SCharles.Forsyth 			}
127*74a4d8c2SCharles.Forsyth 			q = strchr(p+1, ']');
128*74a4d8c2SCharles.Forsyth 			if(q == nil || *(q+1) != 0){
129*74a4d8c2SCharles.Forsyth 				print("malformed menu block header - %s\n", p);
130*74a4d8c2SCharles.Forsyth 				return;
131*74a4d8c2SCharles.Forsyth 			}
132*74a4d8c2SCharles.Forsyth 			*q = 0;
133*74a4d8c2SCharles.Forsyth 			mblock[nmblock].name = p+1;
134*74a4d8c2SCharles.Forsyth 			mblock[nmblock].start = i+1;
135*74a4d8c2SCharles.Forsyth 			inblock = 1;
136*74a4d8c2SCharles.Forsyth 		}
137*74a4d8c2SCharles.Forsyth 	}
138*74a4d8c2SCharles.Forsyth 
139*74a4d8c2SCharles.Forsyth 	if(inblock){
140*74a4d8c2SCharles.Forsyth 		mblock[nmblock].end = i;
141*74a4d8c2SCharles.Forsyth 		nmblock++;
142*74a4d8c2SCharles.Forsyth 	}
143*74a4d8c2SCharles.Forsyth 	if(menu == nil)
144*74a4d8c2SCharles.Forsyth 		return;
145*74a4d8c2SCharles.Forsyth 	if(nmblock < 2){
146*74a4d8c2SCharles.Forsyth 		print("incomplete menu specification\n");
147*74a4d8c2SCharles.Forsyth 		return;
148*74a4d8c2SCharles.Forsyth 	}
149*74a4d8c2SCharles.Forsyth 
150*74a4d8c2SCharles.Forsyth 	for(i = menu->start; i < menu->end; i++){
151*74a4d8c2SCharles.Forsyth 		p = line[i];
152*74a4d8c2SCharles.Forsyth 		if(cistrncmp(p, "menuitem=", 9) == 0){
153*74a4d8c2SCharles.Forsyth 			p += 9;
154*74a4d8c2SCharles.Forsyth 			if((mb = findblock(p, &q)) == nil){
155*74a4d8c2SCharles.Forsyth 				print("no block for menuitem %s\n", p);
156*74a4d8c2SCharles.Forsyth 				return;
157*74a4d8c2SCharles.Forsyth 			}
158*74a4d8c2SCharles.Forsyth 			if(q != nil)
159*74a4d8c2SCharles.Forsyth 				mitem[nmitem].tag = q;
160*74a4d8c2SCharles.Forsyth 			else
161*74a4d8c2SCharles.Forsyth 				mitem[nmitem].tag = mb->name;
162*74a4d8c2SCharles.Forsyth 			mitem[nmitem].mb = mb;
163*74a4d8c2SCharles.Forsyth 			nmitem++;
164*74a4d8c2SCharles.Forsyth 		}
165*74a4d8c2SCharles.Forsyth 		else if(cistrncmp(p, "menudefault=", 12) == 0){
166*74a4d8c2SCharles.Forsyth 			p += 12;
167*74a4d8c2SCharles.Forsyth 			if((mi = finditem(p, &q)) == nil){
168*74a4d8c2SCharles.Forsyth 				print("no item for menudefault %s\n", p);
169*74a4d8c2SCharles.Forsyth 				return;
170*74a4d8c2SCharles.Forsyth 			}
171*74a4d8c2SCharles.Forsyth 			if(q != nil)
172*74a4d8c2SCharles.Forsyth 				mtimeout = strtol(q, 0, 0);
173*74a4d8c2SCharles.Forsyth 			sprint(mdefaultbuf, "%ld", mi-mitem+1);
174*74a4d8c2SCharles.Forsyth 			mdefault = mdefaultbuf;
175*74a4d8c2SCharles.Forsyth 		}
176*74a4d8c2SCharles.Forsyth 		else if(cistrncmp(p, "menuconsole=", 12) == 0){
177*74a4d8c2SCharles.Forsyth 			p += 12;
178*74a4d8c2SCharles.Forsyth 			p = comma(p, &q);
179*74a4d8c2SCharles.Forsyth 			consinit(p, q);
180*74a4d8c2SCharles.Forsyth 		}
181*74a4d8c2SCharles.Forsyth 		else{
182*74a4d8c2SCharles.Forsyth 			print("invalid line in [menu] block - %s\n", p);
183*74a4d8c2SCharles.Forsyth 			return;
184*74a4d8c2SCharles.Forsyth 		}
185*74a4d8c2SCharles.Forsyth 	}
186*74a4d8c2SCharles.Forsyth 
187*74a4d8c2SCharles.Forsyth again:
188*74a4d8c2SCharles.Forsyth 	print("\nPlan 9 Startup Menu:\n====================\n");
189*74a4d8c2SCharles.Forsyth 	for(i = 0; i < nmitem; i++)
190*74a4d8c2SCharles.Forsyth 		print("    %d. %s\n", i+1, mitem[i].tag);
191*74a4d8c2SCharles.Forsyth 	for(;;){
192*74a4d8c2SCharles.Forsyth 		getstr("Selection", buf, sizeof(buf), mdefault, mtimeout);
193*74a4d8c2SCharles.Forsyth 		mtimeout = 0;
194*74a4d8c2SCharles.Forsyth 		i = strtol(buf, &p, 0)-1;
195*74a4d8c2SCharles.Forsyth 		if(i < 0 || i >= nmitem)
196*74a4d8c2SCharles.Forsyth 			goto again;
197*74a4d8c2SCharles.Forsyth 		switch(*p){
198*74a4d8c2SCharles.Forsyth 		case 'p':
199*74a4d8c2SCharles.Forsyth 		case 'P':
200*74a4d8c2SCharles.Forsyth 			show = 1;
201*74a4d8c2SCharles.Forsyth 			print("\n");
202*74a4d8c2SCharles.Forsyth 			break;
203*74a4d8c2SCharles.Forsyth 		case 0:
204*74a4d8c2SCharles.Forsyth 			show = 0;
205*74a4d8c2SCharles.Forsyth 			break;
206*74a4d8c2SCharles.Forsyth 		default:
207*74a4d8c2SCharles.Forsyth 			continue;
208*74a4d8c2SCharles.Forsyth 
209*74a4d8c2SCharles.Forsyth 		}
210*74a4d8c2SCharles.Forsyth 		mi = &mitem[i];
211*74a4d8c2SCharles.Forsyth 
212*74a4d8c2SCharles.Forsyth 		p = str;
213*74a4d8c2SCharles.Forsyth 		p += sprint(p, "menuitem=%s\n", mi->mb->name);
214*74a4d8c2SCharles.Forsyth 		for(i = 0; i < nmblock; i++){
215*74a4d8c2SCharles.Forsyth 			mb = &mblock[i];
216*74a4d8c2SCharles.Forsyth 			if(mi->mb != mb && cistrcmp(mb->name, "common") != 0)
217*74a4d8c2SCharles.Forsyth 				continue;
218*74a4d8c2SCharles.Forsyth 			for(n = mb->start; n < mb->end; n++)
219*74a4d8c2SCharles.Forsyth 				p += sprint(p, "%s\n", line[n]);
220*74a4d8c2SCharles.Forsyth 		}
221*74a4d8c2SCharles.Forsyth 
222*74a4d8c2SCharles.Forsyth 		if(show){
223*74a4d8c2SCharles.Forsyth 			for(q = str; q < p; q += i){
224*74a4d8c2SCharles.Forsyth 				if((i = print(q)) <= 0)
225*74a4d8c2SCharles.Forsyth 					break;
226*74a4d8c2SCharles.Forsyth 			}
227*74a4d8c2SCharles.Forsyth 			goto again;
228*74a4d8c2SCharles.Forsyth 		}
229*74a4d8c2SCharles.Forsyth 		break;
230*74a4d8c2SCharles.Forsyth 	}
231*74a4d8c2SCharles.Forsyth 	print("\n");
232*74a4d8c2SCharles.Forsyth }
233*74a4d8c2SCharles.Forsyth 
234*74a4d8c2SCharles.Forsyth /*
235*74a4d8c2SCharles.Forsyth static void
236*74a4d8c2SCharles.Forsyth msleep(int msec)
237*74a4d8c2SCharles.Forsyth {
238*74a4d8c2SCharles.Forsyth 	ulong start;
239*74a4d8c2SCharles.Forsyth 
240*74a4d8c2SCharles.Forsyth 	for(start = m->ticks; TK2MS(m->ticks - start) < msec; )
241*74a4d8c2SCharles.Forsyth 		;
242*74a4d8c2SCharles.Forsyth }
243*74a4d8c2SCharles.Forsyth */
244*74a4d8c2SCharles.Forsyth 
245*74a4d8c2SCharles.Forsyth void
readlsconf(void)246*74a4d8c2SCharles.Forsyth readlsconf(void)
247*74a4d8c2SCharles.Forsyth {
248*74a4d8c2SCharles.Forsyth 	uchar *p;
249*74a4d8c2SCharles.Forsyth 
250*74a4d8c2SCharles.Forsyth 	p = (uchar*)CONFADDR;
251*74a4d8c2SCharles.Forsyth 	for(;;) {
252*74a4d8c2SCharles.Forsyth 		if(strcmp((char*)p, "APM") == 0){
253*74a4d8c2SCharles.Forsyth 			apm.haveinfo = 1;
254*74a4d8c2SCharles.Forsyth 			apm.ax = *(ushort*)(p+4);
255*74a4d8c2SCharles.Forsyth 			apm.cx = *(ushort*)(p+6);
256*74a4d8c2SCharles.Forsyth 			apm.dx = *(ushort*)(p+8);
257*74a4d8c2SCharles.Forsyth 			apm.di = *(ushort*)(p+10);
258*74a4d8c2SCharles.Forsyth 			apm.ebx = *(ulong*)(p+12);
259*74a4d8c2SCharles.Forsyth 			apm.esi = *(ulong*)(p+16);
260*74a4d8c2SCharles.Forsyth 			print("apm ax=%x cx=%x dx=%x di=%x ebx=%x esi=%x\n",
261*74a4d8c2SCharles.Forsyth 				apm.ax, apm.cx, apm.dx, apm.di, apm.ebx, apm.esi);
262*74a4d8c2SCharles.Forsyth 			p += 20;
263*74a4d8c2SCharles.Forsyth 			continue;
264*74a4d8c2SCharles.Forsyth 		}
265*74a4d8c2SCharles.Forsyth 		break;
266*74a4d8c2SCharles.Forsyth 	}
267*74a4d8c2SCharles.Forsyth }
268*74a4d8c2SCharles.Forsyth 
269*74a4d8c2SCharles.Forsyth char*
getconf(char * name)270*74a4d8c2SCharles.Forsyth getconf(char *name)
271*74a4d8c2SCharles.Forsyth {
272*74a4d8c2SCharles.Forsyth 	int i, n, nmatch;
273*74a4d8c2SCharles.Forsyth 	char buf[20];
274*74a4d8c2SCharles.Forsyth 
275*74a4d8c2SCharles.Forsyth 	nmatch = 0;
276*74a4d8c2SCharles.Forsyth 	for(i = 0; i < nconf; i++)
277*74a4d8c2SCharles.Forsyth 		if(cistrcmp(confname[i], name) == 0)
278*74a4d8c2SCharles.Forsyth 			nmatch++;
279*74a4d8c2SCharles.Forsyth 
280*74a4d8c2SCharles.Forsyth 	switch(nmatch) {
281*74a4d8c2SCharles.Forsyth 	default:
282*74a4d8c2SCharles.Forsyth 		print("\n");
283*74a4d8c2SCharles.Forsyth 		nmatch = 0;
284*74a4d8c2SCharles.Forsyth 		for(i = 0; i < nconf; i++)
285*74a4d8c2SCharles.Forsyth 			if(cistrcmp(confname[i], name) == 0)
286*74a4d8c2SCharles.Forsyth 				print("%d. %s\n", ++nmatch, confval[i]);
287*74a4d8c2SCharles.Forsyth 		print("%d. none of the above\n", ++nmatch);
288*74a4d8c2SCharles.Forsyth 		do {
289*74a4d8c2SCharles.Forsyth 			getstr(name, buf, sizeof(buf), nil, 0);
290*74a4d8c2SCharles.Forsyth 			n = atoi(buf);
291*74a4d8c2SCharles.Forsyth 		} while(n < 1 || n > nmatch);
292*74a4d8c2SCharles.Forsyth 
293*74a4d8c2SCharles.Forsyth 		for(i = 0; i < nconf; i++)
294*74a4d8c2SCharles.Forsyth 			if(cistrcmp(confname[i], name) == 0)
295*74a4d8c2SCharles.Forsyth 				if(--n == 0)
296*74a4d8c2SCharles.Forsyth 					return confval[i];
297*74a4d8c2SCharles.Forsyth 		break;
298*74a4d8c2SCharles.Forsyth 
299*74a4d8c2SCharles.Forsyth 	case 1:
300*74a4d8c2SCharles.Forsyth 		for(i = 0; i < nconf; i++)
301*74a4d8c2SCharles.Forsyth 			if(cistrcmp(confname[i], name) == 0)
302*74a4d8c2SCharles.Forsyth 				return confval[i];
303*74a4d8c2SCharles.Forsyth 		break;
304*74a4d8c2SCharles.Forsyth 
305*74a4d8c2SCharles.Forsyth 	case 0:
306*74a4d8c2SCharles.Forsyth 		break;
307*74a4d8c2SCharles.Forsyth 	}
308*74a4d8c2SCharles.Forsyth 	return nil;
309*74a4d8c2SCharles.Forsyth }
310*74a4d8c2SCharles.Forsyth 
311*74a4d8c2SCharles.Forsyth void
addconf(char * fmt,...)312*74a4d8c2SCharles.Forsyth addconf(char *fmt, ...)
313*74a4d8c2SCharles.Forsyth {
314*74a4d8c2SCharles.Forsyth 	va_list arg;
315*74a4d8c2SCharles.Forsyth 
316*74a4d8c2SCharles.Forsyth 	va_start(arg, fmt);
317*74a4d8c2SCharles.Forsyth 	vseprint(BOOTARGS+strlen(BOOTARGS), BOOTARGS+BOOTARGSLEN, fmt, arg);
318*74a4d8c2SCharles.Forsyth 	va_end(arg);
319*74a4d8c2SCharles.Forsyth }
320*74a4d8c2SCharles.Forsyth 
321*74a4d8c2SCharles.Forsyth void
changeconf(char * fmt,...)322*74a4d8c2SCharles.Forsyth changeconf(char *fmt, ...)
323*74a4d8c2SCharles.Forsyth {
324*74a4d8c2SCharles.Forsyth 	va_list arg;
325*74a4d8c2SCharles.Forsyth 	char *p, *q, pref[20], buf[128];
326*74a4d8c2SCharles.Forsyth 
327*74a4d8c2SCharles.Forsyth 	va_start(arg, fmt);
328*74a4d8c2SCharles.Forsyth 	vseprint(buf, buf+sizeof buf, fmt, arg);
329*74a4d8c2SCharles.Forsyth 	va_end(arg);
330*74a4d8c2SCharles.Forsyth 	strncpy(pref+1, buf, 19);
331*74a4d8c2SCharles.Forsyth 	pref[19] = '\0';
332*74a4d8c2SCharles.Forsyth 	if(p = strchr(pref, '='))
333*74a4d8c2SCharles.Forsyth 		*(p+1) = '\0';
334*74a4d8c2SCharles.Forsyth 	else
335*74a4d8c2SCharles.Forsyth 		print("warning: did not change %s in plan9.ini\n", buf);
336*74a4d8c2SCharles.Forsyth 
337*74a4d8c2SCharles.Forsyth 	/* find old line by looking for \nwhat= */
338*74a4d8c2SCharles.Forsyth 	pref[0] = '\n';
339*74a4d8c2SCharles.Forsyth 	if(strncmp(BOOTARGS, pref+1, strlen(pref+1)) == 0)
340*74a4d8c2SCharles.Forsyth 		p = BOOTARGS;
341*74a4d8c2SCharles.Forsyth 	else if(p = strstr(BOOTARGS, pref))
342*74a4d8c2SCharles.Forsyth 		p++;
343*74a4d8c2SCharles.Forsyth 	else
344*74a4d8c2SCharles.Forsyth 		p = nil;
345*74a4d8c2SCharles.Forsyth 
346*74a4d8c2SCharles.Forsyth 	/* move rest of args up, deleting what= line. */
347*74a4d8c2SCharles.Forsyth 	if(p != nil && (q = strchr(p, '\n')) != nil)
348*74a4d8c2SCharles.Forsyth 		memmove(p, q+1, strlen(q+1)+1);
349*74a4d8c2SCharles.Forsyth 
350*74a4d8c2SCharles.Forsyth 	/* add replacement to end */
351*74a4d8c2SCharles.Forsyth 	addconf("%s", buf);
352*74a4d8c2SCharles.Forsyth }
353*74a4d8c2SCharles.Forsyth 
354*74a4d8c2SCharles.Forsyth /*
355*74a4d8c2SCharles.Forsyth  *  read configuration file
356*74a4d8c2SCharles.Forsyth  */
357*74a4d8c2SCharles.Forsyth static char inibuf[BOOTARGSLEN];
358*74a4d8c2SCharles.Forsyth static char id[8] = "ZORT 0\r\n";
359*74a4d8c2SCharles.Forsyth 
360*74a4d8c2SCharles.Forsyth int
dotini(Fs * fs)361*74a4d8c2SCharles.Forsyth dotini(Fs *fs)
362*74a4d8c2SCharles.Forsyth {
363*74a4d8c2SCharles.Forsyth 	File rc;
364*74a4d8c2SCharles.Forsyth 	int blankline, i, incomment, inspace, n;
365*74a4d8c2SCharles.Forsyth 	char *cp, *p, *q, *line[MAXCONF];
366*74a4d8c2SCharles.Forsyth 
367*74a4d8c2SCharles.Forsyth 	if(fswalk(fs, *ini, &rc) <= 0)
368*74a4d8c2SCharles.Forsyth 		return -1;
369*74a4d8c2SCharles.Forsyth 
370*74a4d8c2SCharles.Forsyth 	cp = inibuf;
371*74a4d8c2SCharles.Forsyth 	*cp = 0;
372*74a4d8c2SCharles.Forsyth 	n = fsread(&rc, cp, BOOTARGSLEN-1);
373*74a4d8c2SCharles.Forsyth 	if(n <= 0)
374*74a4d8c2SCharles.Forsyth 		return -1;
375*74a4d8c2SCharles.Forsyth 
376*74a4d8c2SCharles.Forsyth 	cp[n] = 0;
377*74a4d8c2SCharles.Forsyth 
378*74a4d8c2SCharles.Forsyth 	/*
379*74a4d8c2SCharles.Forsyth 	 * Strip out '\r', change '\t' -> ' '.
380*74a4d8c2SCharles.Forsyth 	 * Change runs of spaces into single spaces.
381*74a4d8c2SCharles.Forsyth 	 * Strip out trailing spaces, blank lines.
382*74a4d8c2SCharles.Forsyth 	 *
383*74a4d8c2SCharles.Forsyth 	 * We do this before we make the copy so that if we
384*74a4d8c2SCharles.Forsyth 	 * need to change the copy, it is already fairly clean.
385*74a4d8c2SCharles.Forsyth 	 * The main need is in the case when plan9.ini has been
386*74a4d8c2SCharles.Forsyth 	 * padded with lots of trailing spaces, as is the case
387*74a4d8c2SCharles.Forsyth 	 * for those created during a distribution install.
388*74a4d8c2SCharles.Forsyth 	 */
389*74a4d8c2SCharles.Forsyth 	p = cp;
390*74a4d8c2SCharles.Forsyth 	blankline = 1;
391*74a4d8c2SCharles.Forsyth 	incomment = inspace = 0;
392*74a4d8c2SCharles.Forsyth 	for(q = cp; *q; q++){
393*74a4d8c2SCharles.Forsyth 		if(*q == '\r')
394*74a4d8c2SCharles.Forsyth 			continue;
395*74a4d8c2SCharles.Forsyth 		if(*q == '\t')
396*74a4d8c2SCharles.Forsyth 			*q = ' ';
397*74a4d8c2SCharles.Forsyth 		if(*q == ' '){
398*74a4d8c2SCharles.Forsyth 			inspace = 1;
399*74a4d8c2SCharles.Forsyth 			continue;
400*74a4d8c2SCharles.Forsyth 		}
401*74a4d8c2SCharles.Forsyth 		if(*q == '\n'){
402*74a4d8c2SCharles.Forsyth 			if(!blankline){
403*74a4d8c2SCharles.Forsyth 				if(!incomment)
404*74a4d8c2SCharles.Forsyth 					*p++ = '\n';
405*74a4d8c2SCharles.Forsyth 				blankline = 1;
406*74a4d8c2SCharles.Forsyth 			}
407*74a4d8c2SCharles.Forsyth 			incomment = inspace = 0;
408*74a4d8c2SCharles.Forsyth 			continue;
409*74a4d8c2SCharles.Forsyth 		}
410*74a4d8c2SCharles.Forsyth 		if(inspace){
411*74a4d8c2SCharles.Forsyth 			if(!blankline && !incomment)
412*74a4d8c2SCharles.Forsyth 				*p++ = ' ';
413*74a4d8c2SCharles.Forsyth 			inspace = 0;
414*74a4d8c2SCharles.Forsyth 		}
415*74a4d8c2SCharles.Forsyth 		if(blankline && *q == '#')
416*74a4d8c2SCharles.Forsyth 			incomment = 1;
417*74a4d8c2SCharles.Forsyth 		blankline = 0;
418*74a4d8c2SCharles.Forsyth 		if(!incomment)
419*74a4d8c2SCharles.Forsyth 			*p++ = *q;
420*74a4d8c2SCharles.Forsyth 	}
421*74a4d8c2SCharles.Forsyth 	if(p > cp && p[-1] != '\n')
422*74a4d8c2SCharles.Forsyth 		*p++ = '\n';
423*74a4d8c2SCharles.Forsyth 	*p++ = 0;
424*74a4d8c2SCharles.Forsyth 	n = p-cp;
425*74a4d8c2SCharles.Forsyth 
426*74a4d8c2SCharles.Forsyth 	parsemenu(cp, BOOTARGS, n);
427*74a4d8c2SCharles.Forsyth 
428*74a4d8c2SCharles.Forsyth 	/*
429*74a4d8c2SCharles.Forsyth 	 * Keep a copy.
430*74a4d8c2SCharles.Forsyth 	 * We could change this to pass the parsed strings
431*74a4d8c2SCharles.Forsyth 	 * to the booted programme instead of the raw
432*74a4d8c2SCharles.Forsyth 	 * string, then it only gets done once.
433*74a4d8c2SCharles.Forsyth 	 */
434*74a4d8c2SCharles.Forsyth 	if(strncmp(cp, id, sizeof(id))){
435*74a4d8c2SCharles.Forsyth 		memmove(BOOTARGS, id, sizeof(id));
436*74a4d8c2SCharles.Forsyth 		if(n+1+sizeof(id) >= BOOTARGSLEN)
437*74a4d8c2SCharles.Forsyth 			n -= sizeof(id);
438*74a4d8c2SCharles.Forsyth 		memmove(BOOTARGS+sizeof(id), cp, n+1);
439*74a4d8c2SCharles.Forsyth 	}
440*74a4d8c2SCharles.Forsyth 	else
441*74a4d8c2SCharles.Forsyth 		memmove(BOOTARGS, cp, n+1);
442*74a4d8c2SCharles.Forsyth 
443*74a4d8c2SCharles.Forsyth 	n = getfields(cp, line, MAXCONF, '\n');
444*74a4d8c2SCharles.Forsyth 	for(i = 0; i < n; i++){
445*74a4d8c2SCharles.Forsyth 		cp = strchr(line[i], '=');
446*74a4d8c2SCharles.Forsyth 		if(cp == 0)
447*74a4d8c2SCharles.Forsyth 			continue;
448*74a4d8c2SCharles.Forsyth 		*cp++ = 0;
449*74a4d8c2SCharles.Forsyth 		if(cp - line[i] >= NAMELEN+1)
450*74a4d8c2SCharles.Forsyth 			*(line[i]+NAMELEN-1) = 0;
451*74a4d8c2SCharles.Forsyth 		confname[nconf] = line[i];
452*74a4d8c2SCharles.Forsyth 		confval[nconf] = cp;
453*74a4d8c2SCharles.Forsyth 		nconf++;
454*74a4d8c2SCharles.Forsyth 	}
455*74a4d8c2SCharles.Forsyth 	return 0;
456*74a4d8c2SCharles.Forsyth }
457*74a4d8c2SCharles.Forsyth 
458*74a4d8c2SCharles.Forsyth static int
parseether(uchar * to,char * from)459*74a4d8c2SCharles.Forsyth parseether(uchar *to, char *from)
460*74a4d8c2SCharles.Forsyth {
461*74a4d8c2SCharles.Forsyth 	char nip[4];
462*74a4d8c2SCharles.Forsyth 	char *p;
463*74a4d8c2SCharles.Forsyth 	int i;
464*74a4d8c2SCharles.Forsyth 
465*74a4d8c2SCharles.Forsyth 	p = from;
466*74a4d8c2SCharles.Forsyth 	while(*p == ' ')
467*74a4d8c2SCharles.Forsyth 		++p;
468*74a4d8c2SCharles.Forsyth 	for(i = 0; i < 6; i++){
469*74a4d8c2SCharles.Forsyth 		if(*p == 0)
470*74a4d8c2SCharles.Forsyth 			return -1;
471*74a4d8c2SCharles.Forsyth 		nip[0] = *p++;
472*74a4d8c2SCharles.Forsyth 		if(*p == 0)
473*74a4d8c2SCharles.Forsyth 			return -1;
474*74a4d8c2SCharles.Forsyth 		nip[1] = *p++;
475*74a4d8c2SCharles.Forsyth 		nip[2] = 0;
476*74a4d8c2SCharles.Forsyth 		to[i] = strtoul(nip, 0, 16);
477*74a4d8c2SCharles.Forsyth 		if(*p == ':')
478*74a4d8c2SCharles.Forsyth 			p++;
479*74a4d8c2SCharles.Forsyth 	}
480*74a4d8c2SCharles.Forsyth 	return 0;
481*74a4d8c2SCharles.Forsyth }
482*74a4d8c2SCharles.Forsyth 
483*74a4d8c2SCharles.Forsyth int
isaconfig(char * class,int ctlrno,ISAConf * isa)484*74a4d8c2SCharles.Forsyth isaconfig(char *class, int ctlrno, ISAConf *isa)
485*74a4d8c2SCharles.Forsyth {
486*74a4d8c2SCharles.Forsyth 	char cc[NAMELEN], *p, *q, *r;
487*74a4d8c2SCharles.Forsyth 	int n;
488*74a4d8c2SCharles.Forsyth 
489*74a4d8c2SCharles.Forsyth 	sprint(cc, "%s%d", class, ctlrno);
490*74a4d8c2SCharles.Forsyth 	for(n = 0; n < nconf; n++){
491*74a4d8c2SCharles.Forsyth 		if(cistrncmp(confname[n], cc, NAMELEN))
492*74a4d8c2SCharles.Forsyth 			continue;
493*74a4d8c2SCharles.Forsyth 		isa->nopt = 0;
494*74a4d8c2SCharles.Forsyth 		p = confval[n];
495*74a4d8c2SCharles.Forsyth 		while(*p){
496*74a4d8c2SCharles.Forsyth 			while(*p == ' ' || *p == '\t')
497*74a4d8c2SCharles.Forsyth 				p++;
498*74a4d8c2SCharles.Forsyth 			if(*p == '\0')
499*74a4d8c2SCharles.Forsyth 				break;
500*74a4d8c2SCharles.Forsyth 			if(cistrncmp(p, "type=", 5) == 0){
501*74a4d8c2SCharles.Forsyth 				p += 5;
502*74a4d8c2SCharles.Forsyth 				for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){
503*74a4d8c2SCharles.Forsyth 					if(*p == '\0' || *p == ' ' || *p == '\t')
504*74a4d8c2SCharles.Forsyth 						break;
505*74a4d8c2SCharles.Forsyth 					*q = *p++;
506*74a4d8c2SCharles.Forsyth 				}
507*74a4d8c2SCharles.Forsyth 				*q = '\0';
508*74a4d8c2SCharles.Forsyth 			}
509*74a4d8c2SCharles.Forsyth 			else if(cistrncmp(p, "port=", 5) == 0)
510*74a4d8c2SCharles.Forsyth 				isa->port = strtoul(p+5, &p, 0);
511*74a4d8c2SCharles.Forsyth 			else if(cistrncmp(p, "irq=", 4) == 0)
512*74a4d8c2SCharles.Forsyth 				isa->irq = strtoul(p+4, &p, 0);
513*74a4d8c2SCharles.Forsyth 			else if(cistrncmp(p, "mem=", 4) == 0)
514*74a4d8c2SCharles.Forsyth 				isa->mem = strtoul(p+4, &p, 0);
515*74a4d8c2SCharles.Forsyth 			else if(cistrncmp(p, "size=", 5) == 0)
516*74a4d8c2SCharles.Forsyth 				isa->size = strtoul(p+5, &p, 0);
517*74a4d8c2SCharles.Forsyth 			else if(cistrncmp(p, "ea=", 3) == 0){
518*74a4d8c2SCharles.Forsyth 				if(parseether(isa->ea, p+3) == -1)
519*74a4d8c2SCharles.Forsyth 					memset(isa->ea, 0, 6);
520*74a4d8c2SCharles.Forsyth 			}
521*74a4d8c2SCharles.Forsyth 			else if(isa->nopt < NISAOPT){
522*74a4d8c2SCharles.Forsyth 				r = isa->opt[isa->nopt];
523*74a4d8c2SCharles.Forsyth 				while(*p && *p != ' ' && *p != '\t'){
524*74a4d8c2SCharles.Forsyth 					*r++ = *p++;
525*74a4d8c2SCharles.Forsyth 					if(r-isa->opt[isa->nopt] >= ISAOPTLEN-1)
526*74a4d8c2SCharles.Forsyth 						break;
527*74a4d8c2SCharles.Forsyth 				}
528*74a4d8c2SCharles.Forsyth 				*r = '\0';
529*74a4d8c2SCharles.Forsyth 				isa->nopt++;
530*74a4d8c2SCharles.Forsyth 			}
531*74a4d8c2SCharles.Forsyth 			while(*p && *p != ' ' && *p != '\t')
532*74a4d8c2SCharles.Forsyth 				p++;
533*74a4d8c2SCharles.Forsyth 		}
534*74a4d8c2SCharles.Forsyth 		return 1;
535*74a4d8c2SCharles.Forsyth 	}
536*74a4d8c2SCharles.Forsyth 	return 0;
537*74a4d8c2SCharles.Forsyth }
538