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