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