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