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