xref: /csrg-svn/sys/i386/stand/disktab.c (revision 41075)
1*41075Swilliam /*-
2*41075Swilliam  * Copyright (c) 1990 The Regents of the University of California.
3*41075Swilliam  * All rights reserved.
4*41075Swilliam  *
5*41075Swilliam  * This code is derived from software contributed to Berkeley by
6*41075Swilliam  * William Jolitz.
7*41075Swilliam  *
8*41075Swilliam  * %sccs.include.noredist.c%
9*41075Swilliam  *
10*41075Swilliam  *	@(#)disktab.c	7.1 (Berkeley) 04/24/90
11*41075Swilliam  */
12*41075Swilliam 
13*41075Swilliam #include <disktab.h>
14*41075Swilliam 
15*41075Swilliam #define	BUFSIZ	1024
16*41075Swilliam 
17*41075Swilliam static	char *dgetstr();
18*41075Swilliam 
19*41075Swilliam struct disktab *
getdiskbyname(name)20*41075Swilliam getdiskbyname(name)
21*41075Swilliam 	char *name;
22*41075Swilliam {
23*41075Swilliam 	static struct disktab disk;
24*41075Swilliam 	static char localbuf[100], *cp = localbuf;
25*41075Swilliam 	register struct	disktab *dp = &disk;
26*41075Swilliam 	register struct partition *pp;
27*41075Swilliam 	char p, psize[3], pbsize[3], pfsize[3], posize[3];
28*41075Swilliam 	char buf[BUFSIZ];
29*41075Swilliam 
30*41075Swilliam 	if (dgetent(buf, name) <= 0)
31*41075Swilliam 		return ((struct disktab *)0);
32*41075Swilliam 	dp->d_name = cp;
33*41075Swilliam 	strcpy(cp, name);
34*41075Swilliam 	cp += strlen(name) + 1;
35*41075Swilliam 	dp->d_type = dgetstr("ty", &cp);
36*41075Swilliam 	dp->d_secsize = dgetnum("se");
37*41075Swilliam 	if (dp->d_secsize < 0)
38*41075Swilliam 		dp->d_secsize = 512;
39*41075Swilliam 	dp->d_ntracks = dgetnum("nt");
40*41075Swilliam 	dp->d_nsectors = dgetnum("ns");
41*41075Swilliam 	dp->d_ncylinders = dgetnum("nc");
42*41075Swilliam 	dp->d_secpercyl = dgetnum("sc");
43*41075Swilliam 	dp->d_rpm = dgetnum("rm");
44*41075Swilliam 	if (dp->d_rpm < 0)
45*41075Swilliam 		dp->d_rpm = 3600;
46*41075Swilliam 	if (strcmp(dp->d_type, "st506") == 0 ||
47*41075Swilliam 	    strcmp(dp->d_type, "ST506") == 0) {
48*41075Swilliam 		dp->d_precomp = dgetnum("wp");
49*41075Swilliam 		if (dp->d_precomp < 0)
50*41075Swilliam 			dp->d_precomp = 1023;
51*41075Swilliam 	}
52*41075Swilliam 	if (strcmp(dp->d_type, "scsi") == 0 ||
53*41075Swilliam 	    strcmp(dp->d_type, "SCSI") == 0)
54*41075Swilliam 		dp->d_blind = dgetflag("bm");
55*41075Swilliam 	strcpy(psize, "px");
56*41075Swilliam 	strcpy(pbsize, "bx");
57*41075Swilliam 	strcpy(pfsize, "fx");
58*41075Swilliam 	strcpy(posize, "ox");
59*41075Swilliam 	for (p = 'a'; p < 'i'; p++) {
60*41075Swilliam 		psize[1] = pbsize[1] = pfsize[1] = posize[1] = p;
61*41075Swilliam 		pp = &dp->d_partitions[p - 'a'];
62*41075Swilliam 		pp->p_size = dgetnum(psize);
63*41075Swilliam 		if (pp->p_size == -1)
64*41075Swilliam 			pp->p_size = 0;
65*41075Swilliam 		pp->p_bsize = dgetnum(pbsize);
66*41075Swilliam 		if (pp->p_bsize == -1)
67*41075Swilliam 			pp->p_bsize = 0;
68*41075Swilliam 		pp->p_fsize = dgetnum(pfsize);
69*41075Swilliam 		if (pp->p_fsize == -1)
70*41075Swilliam 			pp->p_fsize = 0;
71*41075Swilliam 		pp->p_offset = dgetnum(posize);
72*41075Swilliam 		if (pp->p_offset == -1)
73*41075Swilliam 			pp->p_offset = 0;
74*41075Swilliam 	}
75*41075Swilliam 	return (dp);
76*41075Swilliam }
77*41075Swilliam 
78*41075Swilliam #include <ctype.h>
79*41075Swilliam 
80*41075Swilliam static	char *tbuf;
81*41075Swilliam static	char *dskip();
82*41075Swilliam static	char *ddecode();
83*41075Swilliam 
84*41075Swilliam /*
85*41075Swilliam  * Get an entry for disk name in buffer bp,
86*41075Swilliam  * from the diskcap file.  Parse is very rudimentary;
87*41075Swilliam  * we just notice escaped newlines.
88*41075Swilliam  */
89*41075Swilliam extern char *standdisk;
90*41075Swilliam static
dgetent(bp,name)91*41075Swilliam dgetent(bp, name)
92*41075Swilliam 	char *bp, *name;
93*41075Swilliam {
94*41075Swilliam 	register char *cp;
95*41075Swilliam 	register int c;
96*41075Swilliam 	register int i = 0, cnt = 0;
97*41075Swilliam 	char ibuf[BUFSIZ];
98*41075Swilliam 	int tf;
99*41075Swilliam 
100*41075Swilliam 	tbuf = bp;
101*41075Swilliam 	tf = open(standdisk, 0);
102*41075Swilliam 	if (tf < 0)
103*41075Swilliam 		return (-1);
104*41075Swilliam 	for (;;) {
105*41075Swilliam 		cp = bp;
106*41075Swilliam 		for (;;) {
107*41075Swilliam 			if (i == cnt) {
108*41075Swilliam 				cnt = read(tf, ibuf, BUFSIZ);
109*41075Swilliam 				if (cnt <= 0) {
110*41075Swilliam 					close(tf);
111*41075Swilliam 					return (0);
112*41075Swilliam 				}
113*41075Swilliam 				i = 0;
114*41075Swilliam 			}
115*41075Swilliam 			c = ibuf[i++];
116*41075Swilliam 			if (c == '\n') {
117*41075Swilliam 				if (cp > bp && cp[-1] == '\\'){
118*41075Swilliam 					cp--;
119*41075Swilliam 					continue;
120*41075Swilliam 				}
121*41075Swilliam 				break;
122*41075Swilliam 			}
123*41075Swilliam 			if (cp >= bp+BUFSIZ) {
124*41075Swilliam 				write(2,"Disktab entry too long\n", 23);
125*41075Swilliam 				break;
126*41075Swilliam 			} else
127*41075Swilliam 				*cp++ = c;
128*41075Swilliam 		}
129*41075Swilliam 		*cp = 0;
130*41075Swilliam 
131*41075Swilliam 		/*
132*41075Swilliam 		 * The real work for the match.
133*41075Swilliam 		 */
134*41075Swilliam 		if (dnamatch(name)) {
135*41075Swilliam 			close(tf);
136*41075Swilliam 			return (1);
137*41075Swilliam 		}
138*41075Swilliam 	}
139*41075Swilliam }
140*41075Swilliam 
141*41075Swilliam /*
142*41075Swilliam  * Dnamatch deals with name matching.  The first field of the disktab
143*41075Swilliam  * entry is a sequence of names separated by |'s, so we compare
144*41075Swilliam  * against each such name.  The normal : terminator after the last
145*41075Swilliam  * name (before the first field) stops us.
146*41075Swilliam  */
147*41075Swilliam static
dnamatch(np)148*41075Swilliam dnamatch(np)
149*41075Swilliam 	char *np;
150*41075Swilliam {
151*41075Swilliam 	register char *Np, *Bp;
152*41075Swilliam 
153*41075Swilliam 	Bp = tbuf;
154*41075Swilliam 	if (*Bp == '#')
155*41075Swilliam 		return (0);
156*41075Swilliam 	for (;;) {
157*41075Swilliam 		for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
158*41075Swilliam 			continue;
159*41075Swilliam 		if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
160*41075Swilliam 			return (1);
161*41075Swilliam 		while (*Bp && *Bp != ':' && *Bp != '|')
162*41075Swilliam 			Bp++;
163*41075Swilliam 		if (*Bp == 0 || *Bp == ':')
164*41075Swilliam 			return (0);
165*41075Swilliam 		Bp++;
166*41075Swilliam 	}
167*41075Swilliam }
168*41075Swilliam 
169*41075Swilliam /*
170*41075Swilliam  * Skip to the next field.  Notice that this is very dumb, not
171*41075Swilliam  * knowing about \: escapes or any such.  If necessary, :'s can be put
172*41075Swilliam  * into the diskcap file in octal.
173*41075Swilliam  */
174*41075Swilliam static char *
dskip(bp)175*41075Swilliam dskip(bp)
176*41075Swilliam 	register char *bp;
177*41075Swilliam {
178*41075Swilliam 
179*41075Swilliam 	while (*bp && *bp != ':')
180*41075Swilliam 		bp++;
181*41075Swilliam 	if (*bp == ':')
182*41075Swilliam 		bp++;
183*41075Swilliam 	return (bp);
184*41075Swilliam }
185*41075Swilliam 
186*41075Swilliam /*
187*41075Swilliam  * Return the (numeric) option id.
188*41075Swilliam  * Numeric options look like
189*41075Swilliam  *	li#80
190*41075Swilliam  * i.e. the option string is separated from the numeric value by
191*41075Swilliam  * a # character.  If the option is not found we return -1.
192*41075Swilliam  * Note that we handle octal numbers beginning with 0.
193*41075Swilliam  */
194*41075Swilliam static
dgetnum(id)195*41075Swilliam dgetnum(id)
196*41075Swilliam 	char *id;
197*41075Swilliam {
198*41075Swilliam 	register int i, base;
199*41075Swilliam 	register char *bp = tbuf;
200*41075Swilliam 
201*41075Swilliam 	for (;;) {
202*41075Swilliam 		bp = dskip(bp);
203*41075Swilliam 		if (*bp == 0)
204*41075Swilliam 			return (-1);
205*41075Swilliam 		if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
206*41075Swilliam 			continue;
207*41075Swilliam 		if (*bp == '@')
208*41075Swilliam 			return (-1);
209*41075Swilliam 		if (*bp != '#')
210*41075Swilliam 			continue;
211*41075Swilliam 		bp++;
212*41075Swilliam 		base = 10;
213*41075Swilliam 		if (*bp == '0')
214*41075Swilliam 			base = 8;
215*41075Swilliam 		i = 0;
216*41075Swilliam 		while (isdigit(*bp))
217*41075Swilliam 			i *= base, i += *bp++ - '0';
218*41075Swilliam 		return (i);
219*41075Swilliam 	}
220*41075Swilliam }
221*41075Swilliam 
222*41075Swilliam /*
223*41075Swilliam  * Handle a flag option.
224*41075Swilliam  * Flag options are given "naked", i.e. followed by a : or the end
225*41075Swilliam  * of the buffer.  Return 1 if we find the option, or 0 if it is
226*41075Swilliam  * not given.
227*41075Swilliam  */
228*41075Swilliam static
dgetflag(id)229*41075Swilliam dgetflag(id)
230*41075Swilliam 	char *id;
231*41075Swilliam {
232*41075Swilliam 	register char *bp = tbuf;
233*41075Swilliam 
234*41075Swilliam 	for (;;) {
235*41075Swilliam 		bp = dskip(bp);
236*41075Swilliam 		if (!*bp)
237*41075Swilliam 			return (0);
238*41075Swilliam 		if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
239*41075Swilliam 			if (!*bp || *bp == ':')
240*41075Swilliam 				return (1);
241*41075Swilliam 			else if (*bp == '@')
242*41075Swilliam 				return (0);
243*41075Swilliam 		}
244*41075Swilliam 	}
245*41075Swilliam }
246*41075Swilliam 
247*41075Swilliam /*
248*41075Swilliam  * Get a string valued option.
249*41075Swilliam  * These are given as
250*41075Swilliam  *	cl=^Z
251*41075Swilliam  * Much decoding is done on the strings, and the strings are
252*41075Swilliam  * placed in area, which is a ref parameter which is updated.
253*41075Swilliam  * No checking on area overflow.
254*41075Swilliam  */
255*41075Swilliam static char *
dgetstr(id,area)256*41075Swilliam dgetstr(id, area)
257*41075Swilliam 	char *id, **area;
258*41075Swilliam {
259*41075Swilliam 	register char *bp = tbuf;
260*41075Swilliam 
261*41075Swilliam 	for (;;) {
262*41075Swilliam 		bp = dskip(bp);
263*41075Swilliam 		if (!*bp)
264*41075Swilliam 			return (0);
265*41075Swilliam 		if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
266*41075Swilliam 			continue;
267*41075Swilliam 		if (*bp == '@')
268*41075Swilliam 			return (0);
269*41075Swilliam 		if (*bp != '=')
270*41075Swilliam 			continue;
271*41075Swilliam 		bp++;
272*41075Swilliam 		return (ddecode(bp, area));
273*41075Swilliam 	}
274*41075Swilliam }
275*41075Swilliam 
276*41075Swilliam /*
277*41075Swilliam  * Tdecode does the grung work to decode the
278*41075Swilliam  * string capability escapes.
279*41075Swilliam  */
280*41075Swilliam static char *
ddecode(str,area)281*41075Swilliam ddecode(str, area)
282*41075Swilliam 	register char *str;
283*41075Swilliam 	char **area;
284*41075Swilliam {
285*41075Swilliam 	register char *cp;
286*41075Swilliam 	register int c;
287*41075Swilliam 	register char *dp;
288*41075Swilliam 	int i;
289*41075Swilliam 
290*41075Swilliam 	cp = *area;
291*41075Swilliam 	while ((c = *str++) && c != ':') {
292*41075Swilliam 		switch (c) {
293*41075Swilliam 
294*41075Swilliam 		case '^':
295*41075Swilliam 			c = *str++ & 037;
296*41075Swilliam 			break;
297*41075Swilliam 
298*41075Swilliam 		case '\\':
299*41075Swilliam 			dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
300*41075Swilliam 			c = *str++;
301*41075Swilliam nextc:
302*41075Swilliam 			if (*dp++ == c) {
303*41075Swilliam 				c = *dp++;
304*41075Swilliam 				break;
305*41075Swilliam 			}
306*41075Swilliam 			dp++;
307*41075Swilliam 			if (*dp)
308*41075Swilliam 				goto nextc;
309*41075Swilliam 			if (isdigit(c)) {
310*41075Swilliam 				c -= '0', i = 2;
311*41075Swilliam 				do
312*41075Swilliam 					c <<= 3, c |= *str++ - '0';
313*41075Swilliam 				while (--i && isdigit(*str));
314*41075Swilliam 			}
315*41075Swilliam 			break;
316*41075Swilliam 		}
317*41075Swilliam 		*cp++ = c;
318*41075Swilliam 	}
319*41075Swilliam 	*cp++ = 0;
320*41075Swilliam 	str = *area;
321*41075Swilliam 	*area = cp;
322*41075Swilliam 	return (str);
323*41075Swilliam }
324