1 /* @(#)xpart.c 1.25 09/07/11 Copyright 1991-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)xpart.c 1.25 09/07/11 Copyright 1991-2009 J. Schilling";
6 #endif
7 /*
8 * Routines to handle external partition info (database)
9 *
10 * Copyright (c) 1991-2009 J. Schilling
11 *
12 * XXX #ifdef HAVE_DKIO ist vorerst nur ein Hack
13 */
14 /*
15 * The contents of this file are subject to the terms of the
16 * Common Development and Distribution License, Version 1.0 only
17 * (the "License"). You may not use this file except in compliance
18 * with the License.
19 *
20 * See the file CDDL.Schily.txt in this distribution for details.
21 * A copy of the CDDL is also available via the Internet at
22 * http://www.opensource.org/licenses/cddl1.txt
23 *
24 * When distributing Covered Code, include this CDDL HEADER in each
25 * file and include the License file CDDL.Schily.txt from this distribution.
26 */
27
28 #include <schily/stdio.h>
29 #include <schily/stdlib.h>
30 #include <schily/standard.h>
31 #include <schily/utypes.h>
32 #include <schily/schily.h>
33 #include "dsklabel.h"
34 #ifndef HAVE_DKIO
35 # undef SVR4
36 #endif
37 #ifdef SVR4
38 #include <sys/vtoc.h>
39 #endif
40 #include <schily/string.h>
41 #include "fmt.h"
42
43 LOCAL struct dk_label * save_part __PR((struct dk_label *));
44 LOCAL int do_part __PR((char *, char *, struct dk_label *));
45 LOCAL void set_labelitem __PR((struct dk_label *, char *));
46 LOCAL BOOL set_onepart __PR((char *, struct dk_label *));
47 LOCAL BOOL set_labelvar __PR((char *, struct dk_label *));
48
49 #ifdef FMT
50 extern int xdebug;
51 extern int save_mp;
52 #else
53 int xdebug = 1;
54 #endif
55
56 #ifndef FMT
main(ac,av)57 main(ac, av)
58 int ac;
59 char **av;
60 {
61 char *name;
62 struct dk_label d_xlabel;
63
64 if (ac > 1)
65 name = av[1];
66 else
67 name = "Berthold 100MB (Quantum)";
68
69 if (!opendatfile("sformat.dat"))
70 return;
71
72 ext_part(scgp, name, (char *)0, &d_xlabel, 0);
73
74 closedatfile();
75 }
76 #endif
77
78 #define MAXLABELS 20
79
80 LOCAL struct dk_label *
save_part(lp)81 save_part(lp)
82 struct dk_label *lp;
83 {
84 struct dk_label *rp;
85
86 rp = (struct dk_label *)malloc(sizeof (*lp));
87 if (rp == 0) {
88 errmsg("No space for label.\n");
89 return ((struct dk_label *)0);
90 }
91 movebytes(lp, rp, sizeof (*lp));
92 return (rp);
93 }
94
95 EXPORT BOOL
ext_part(scgp,dname,pname,defpname,lp,def_func,dp)96 ext_part(scgp, dname, pname, defpname, lp, def_func, dp)
97 SCSI *scgp;
98 char *dname;
99 char *pname;
100 char *defpname;
101 struct dk_label *lp;
102 BOOL (*def_func) __PR((SCSI *scgp, struct disk *, struct dk_label *));
103 struct disk *dp;
104 {
105 struct dk_label tlabel;
106 struct dk_label *label[MAXLABELS];
107 int nlabel = 0;
108 int def;
109 int this;
110 int i;
111 int ret;
112
113 if (xdebug)
114 printf("ext_part(\"%s\", \"%s\", \"%s\")\n",
115 dname, pname, defpname);
116
117 for (i = 0; i < MAXLABELS; i++)
118 label[i] = 0;
119
120 if (rewinddatfile() < 0)
121 goto defpart;
122
123 while (scanfortable("partition", NULL)) {
124 if (xdebug) printf("ext_part: curword: '%s'\n", curword());
125 ret = do_part(dname, pname, &tlabel);
126 if (xdebug) printf("ext_part: do_part() = %d\n", ret);
127 if (pname && ret > 0) {
128 movebytes(&tlabel, lp, sizeof (tlabel));
129 return (TRUE);
130 }
131 if (ret > 0) {
132 label[nlabel] = save_part(&tlabel);
133 if (label[nlabel] == 0)
134 break;
135 nlabel++;
136 }
137 }
138 defpart:
139 if (nlabel == 0 && def_func) {
140 if (def_func && (*def_func)(scgp, dp, &tlabel)) {
141 label[nlabel] = save_part(&tlabel);
142 if (label[nlabel] == 0)
143 return (FALSE);
144 nlabel++;
145 }
146 }
147 if (nlabel == 0) {
148 error("No label found for this disk.\n");
149 return (FALSE);
150 }
151 def = -1;
152 if (defpname) for (i = 0; i < nlabel; i++) {
153 if (streql(defpname, getasciilabel(label[i])))
154 def = i;
155 }
156 if (getasciilabel(lp)) {
157 for (i = 0; i < nlabel; i++) {
158 if (label_cmp(label[i], lp) >= 1)
159 break;
160 }
161 if (i < nlabel) {
162 this = i;
163 } else {
164 label[nlabel] = lp;
165 this = nlabel++;
166 }
167 } else {
168 this = 0;
169 }
170 do {
171 for (i = 0; i < nlabel; i++) {
172 char *name;
173
174 name = getasciilabel(label[i]);
175 printf("%s%2d)%s\t\"%s\"\n",
176 i == this ? "*": " ", i,
177 i == def ? "+" : " ",
178 name);
179 }
180 if (nlabel == 1)
181 this = 0;
182 else
183 getint("Select partition", &this, 0, nlabel-1);
184 if (yes("Print partition table? ")) {
185 printf("\n");
186 prpartab(stdout, dname, label[this]);
187 printf("\n");
188 printparts(label[this]);
189 }
190 } while (nlabel != 1 && !yes("Use selection %d \"%s\"? ",
191 this, getasciilabel(label[this])));
192 movebytes(label[this], lp, sizeof (tlabel));
193
194 for (i = 0; i < nlabel; i++) {
195 if (label[i] != lp)
196 free(label[i]);
197 }
198 return (TRUE);
199 }
200
201
202 /*---------------------------------------------------------------------------
203 |
204 | Parst einen Partition Eintrag in der Steuerungsdatei
205 |
206 +---------------------------------------------------------------------------*/
207
208 LOCAL int
do_part(dname,pname,lp)209 do_part(dname, pname, lp)
210 char *dname;
211 char *pname;
212 struct dk_label *lp;
213 {
214 char *word;
215 char lname[sizeof (lp->dkl_asciilabel)];
216 char dnbuf[128];
217 BOOL disk_ok = FALSE;
218
219 label_null(lp);
220 if (xdebug) printf("do_part: line: %d curword: '%s'\n",
221 getlineno(), curword());
222 word = curword();
223 if (pname && !streql(pname, word))
224 return (FALSE);
225 if (strlen(word) >= sizeof (lp->dkl_asciilabel))
226 datfileerr("Label '%s' too long\n", word);
227 strncpy(lname, word, sizeof (lp->dkl_asciilabel)-1);
228 lname[sizeof (lp->dkl_asciilabel)-1] = '\0';
229
230 (void) garbage(skipwhite(peekword()));
231 if (!nextline())
232 return (EOF);
233
234 while ((word = scanforline(NULL, NULL)) != NULL) {
235 if (!disk_ok)
236 dnbuf[0] = '\0';
237 set_labelitem(lp, dnbuf);
238 if (!disk_ok && *dnbuf) {
239 if (xdebug) {
240 printf("name: %.28s\n", dname);
241 printf("DATA: %.28s\n", dnbuf);
242 }
243 if (streql(dnbuf, dname))
244 disk_ok = TRUE;
245 }
246 }
247 if (xdebug) printf("disk_ok: %d\n", disk_ok);
248 if (!labelgeom_ok(lp, 1))
249 return (FALSE);
250 if (disk_ok) {
251 setasciilabel(lp, lname);
252 if (xdebug) printf("label: <%s>\n", lp->dkl_asciilabel);
253 lp->dkl_magic = DKL_MAGIC;
254 lp->dkl_cksum = 0;
255 lp->dkl_cksum = do_cksum(lp);
256 if (xdebug) prpartab(stdout, dname, lp);
257 }
258 return (disk_ok);
259 }
260
261 LOCAL void
set_labelitem(lp,dname)262 set_labelitem(lp, dname)
263 struct dk_label *lp;
264 char *dname;
265 {
266 char *word;
267
268 for (word = curword(); *word; word = nextword()) {
269 if (streql(word, ":"))
270 continue;
271 if (streql(word, "disk")) {
272 if (!set_stringvar("Disk Name", dname, 79))
273 break;
274 } else if (word[1] == '\0' &&
275 strchr("abcdefgh01234567", word[0])) {
276 if (!set_onepart(word, lp))
277 break;
278 } else if (!set_labelvar(word, lp))
279 break;
280 }
281 (void) nextword();
282 }
283
284 LOCAL BOOL
set_onepart(word,lp)285 set_onepart(word, lp)
286 char *word;
287 struct dk_label *lp;
288 {
289 int n = *word - 'a';
290 long l;
291 struct strval *vtag;
292 struct strval *vflag;
293 extern struct strval vtags[];
294 extern struct strval vflags[];
295 #ifdef SVR4
296 extern struct dk_map2 default_vtmap[];
297 #endif
298
299 if (n < 0 || n > 9)
300 n = *word - '0'; /* allow Solaris 2.x partition names */
301
302 if (xdebug) printf("part: '%s' :", word);
303
304 if (!checkequal())
305 return (FALSE);
306
307 if (!isval(word = nextword()))
308 return (FALSE);
309
310 if ((vtag = namestrval(word, vtags)) != 0) {
311 if (!checkcomma())
312 return (FALSE);
313 if (!isval(word = nextword()))
314 return (FALSE);
315 }
316 if ((vflag = namestrval(word, vflags)) != 0) {
317 if (!checkcomma())
318 return (FALSE);
319 if (!isval(word = nextword()))
320 return (FALSE);
321 }
322 #ifdef SVR4
323 lp->dkl_vtoc.v_version = V_VERSION;
324 lp->dkl_vtoc.v_nparts = NDKMAP;
325 lp->dkl_vtoc.v_sanity = VTOC_SANE;
326 lp->dkl_vtoc.v_part[n].p_tag = default_vtmap[n].p_tag;
327 lp->dkl_vtoc.v_part[n].p_flag = default_vtmap[n].p_flag;
328
329 if (vtag || vflag) {
330 if (vtag)
331 lp->dkl_vtoc.v_part[n].p_tag = vtag->s_val;
332 if (vflag)
333 lp->dkl_vtoc.v_part[n].p_flag = vflag->s_val;
334 }
335 #endif
336 if (*astol(word, &l) != '\0') {
337 datfileerr("not a number '%s'", word);
338 return (FALSE);
339 }
340 lp->dkl_map[n].dkl_cylno = l;
341
342 if (!checkcomma())
343 return (FALSE);
344 if (!isval(word = nextword()))
345 return (FALSE);
346 if (*astol(word, &l) != '\0') {
347 datfileerr("not a number '%s'", word);
348 return (FALSE);
349 }
350 lp->dkl_map[n].dkl_nblk = l;
351
352 if (xdebug) printf("%ld, %ld\n",
353 (long)lp->dkl_map[n].dkl_cylno,
354 (long)lp->dkl_map[n].dkl_nblk);
355 return (TRUE);
356 }
357
358 LOCAL BOOL
set_labelvar(word,lp)359 set_labelvar(word, lp)
360 char *word;
361 struct dk_label *lp;
362 {
363 unsigned short *valp;
364 int i;
365
366 if (xdebug) printf("labelvar: '%s' :", word);
367
368 if (streql(word, "lapc"))
369 valp = &lp->dkl_apc;
370 else if (streql(word, "ncyl"))
371 valp = &lp->dkl_ncyl;
372 else if (streql(word, "lncyl"))
373 valp = &lp->dkl_ncyl;
374 else if (streql(word, "lacyl"))
375 valp = &lp->dkl_acyl;
376 else if (streql(word, "lhead"))
377 valp = &lp->dkl_nhead;
378 else if (streql(word, "lspt"))
379 valp = &lp->dkl_nsect;
380 else {
381 skip_illvar("label", word);
382 return (FALSE);
383 }
384
385 if (!checkequal())
386 return (FALSE);
387
388 if (!isval(word = nextword()))
389 return (FALSE);
390 if (*astoi(word, &i) != '\0') {
391 datfileerr("not a number '%s'", word);
392 return (FALSE);
393 }
394 *valp = i;
395
396 if (xdebug) printf("%d\n", *valp);
397 return (TRUE);
398 }
399