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