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