xref: /illumos-gate/usr/src/lib/libpkg/common/gpkgmap.c (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland 
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*5c51f124SMoriah Waterland  * Use is subject to license terms.
25*5c51f124SMoriah Waterland  */
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28*5c51f124SMoriah Waterland /* All Rights Reserved */
29*5c51f124SMoriah Waterland 
30*5c51f124SMoriah Waterland 
31*5c51f124SMoriah Waterland 
32*5c51f124SMoriah Waterland #include <stdio.h>
33*5c51f124SMoriah Waterland #include <limits.h>
34*5c51f124SMoriah Waterland #include <stdlib.h>
35*5c51f124SMoriah Waterland #include <unistd.h>
36*5c51f124SMoriah Waterland #include <string.h>
37*5c51f124SMoriah Waterland #include <ctype.h>
38*5c51f124SMoriah Waterland #include <fcntl.h>
39*5c51f124SMoriah Waterland #include <sys/types.h>
40*5c51f124SMoriah Waterland #include <sys/stat.h>
41*5c51f124SMoriah Waterland #include <errno.h>
42*5c51f124SMoriah Waterland #include "pkgstrct.h"
43*5c51f124SMoriah Waterland #include "pkglib.h"
44*5c51f124SMoriah Waterland #include "pkglibmsgs.h"
45*5c51f124SMoriah Waterland #include "pkglocale.h"
46*5c51f124SMoriah Waterland 
47*5c51f124SMoriah Waterland #define	ERR_CANT_READ_LCLPATH		"unable to read local pathname"
48*5c51f124SMoriah Waterland #define	ERR_BAD_VOLUME_NUMBER		"bad volume number"
49*5c51f124SMoriah Waterland #define	ERR_CANNOT_READ_PATHNAME_FIELD	"unable to read pathname field"
50*5c51f124SMoriah Waterland #define	ERR_CANNOT_READ_CONTENT_INFO	"unable to read content info"
51*5c51f124SMoriah Waterland #define	ERR_EXTRA_TOKENS_PRESENT	"extra tokens on input line"
52*5c51f124SMoriah Waterland #define	ERR_CANNOT_READ_CLASS_TOKEN	"unable to read class token"
53*5c51f124SMoriah Waterland #define	ERR_BAD_LINK_SPEC		"missing or invalid link specification"
54*5c51f124SMoriah Waterland #define	ERR_UNKNOWN_FTYPE		"unknown ftype"
55*5c51f124SMoriah Waterland #define	ERR_NO_LINKSOURCE		"no link source specified"
56*5c51f124SMoriah Waterland #define	ERR_CANNOT_READ_MM_DEVNUMS	"unable to read major/minor "\
57*5c51f124SMoriah Waterland 					"device numbers"
58*5c51f124SMoriah Waterland static int	eatwhite(FILE *fp);
59*5c51f124SMoriah Waterland static int	getend(FILE *fp);
60*5c51f124SMoriah Waterland static int	getstr(FILE *fp, char *sep, int n, char *str);
61*5c51f124SMoriah Waterland static int	getnum(FILE *fp, int base, long *d, long bad);
62*5c51f124SMoriah Waterland static int	getlnum(FILE *fp, int base, fsblkcnt_t *d, long bad);
63*5c51f124SMoriah Waterland static int	getvalmode(FILE *fp, mode_t *d, long bad, int map);
64*5c51f124SMoriah Waterland 
65*5c51f124SMoriah Waterland static int	getendvfp(char **cp);
66*5c51f124SMoriah Waterland static void	findendvfp(char **cp);
67*5c51f124SMoriah Waterland static int	getstrvfp(char **cp, char *sep, int n, char *str);
68*5c51f124SMoriah Waterland static int	getvalmodevfp(char **cp, mode_t *d, long bad, int map);
69*5c51f124SMoriah Waterland int		getnumvfp(char **cp, int base, long *d, long bad);
70*5c51f124SMoriah Waterland int		getlnumvfp(char **cp, int base, fsblkcnt_t *d, long bad);
71*5c51f124SMoriah Waterland 
72*5c51f124SMoriah Waterland static char	mypath[PATH_MAX];
73*5c51f124SMoriah Waterland static char	mylocal[PATH_MAX];
74*5c51f124SMoriah Waterland static int	mapmode = MAPNONE;
75*5c51f124SMoriah Waterland static char	*maptype = "";
76*5c51f124SMoriah Waterland static mode_t	d_mode = BADMODE;
77*5c51f124SMoriah Waterland static char 	*d_owner = BADOWNER;
78*5c51f124SMoriah Waterland static char	*d_group = BADGROUP;
79*5c51f124SMoriah Waterland 
80*5c51f124SMoriah Waterland /*
81*5c51f124SMoriah Waterland  * These determine how gpkgmap() deals with mode, owner and group defaults.
82*5c51f124SMoriah Waterland  * It is assumed that the owner and group arguments represent static fields
83*5c51f124SMoriah Waterland  * which will persist until attrdefault() is called.
84*5c51f124SMoriah Waterland  */
85*5c51f124SMoriah Waterland void
86*5c51f124SMoriah Waterland attrpreset(int mode, char *owner, char *group)
87*5c51f124SMoriah Waterland {
88*5c51f124SMoriah Waterland 	d_mode = mode;
89*5c51f124SMoriah Waterland 	d_owner = owner;
90*5c51f124SMoriah Waterland 	d_group = group;
91*5c51f124SMoriah Waterland }
92*5c51f124SMoriah Waterland 
93*5c51f124SMoriah Waterland void
94*5c51f124SMoriah Waterland attrdefault()
95*5c51f124SMoriah Waterland {
96*5c51f124SMoriah Waterland 	d_mode = NOMODE;
97*5c51f124SMoriah Waterland 	d_owner = NOOWNER;
98*5c51f124SMoriah Waterland 	d_group = NOGROUP;
99*5c51f124SMoriah Waterland }
100*5c51f124SMoriah Waterland 
101*5c51f124SMoriah Waterland /*
102*5c51f124SMoriah Waterland  * This determines how gpkgmap() deals with environment variables in the
103*5c51f124SMoriah Waterland  * mode, owner and group. Path is evaluated at a higher level based upon
104*5c51f124SMoriah Waterland  * other circumstances.
105*5c51f124SMoriah Waterland  */
106*5c51f124SMoriah Waterland void
107*5c51f124SMoriah Waterland setmapmode(int mode)
108*5c51f124SMoriah Waterland {
109*5c51f124SMoriah Waterland 	if (mode >= 0 || mode <= 3) {
110*5c51f124SMoriah Waterland 		mapmode = mode;
111*5c51f124SMoriah Waterland 		if (mode == MAPBUILD)
112*5c51f124SMoriah Waterland 			maptype = " build";
113*5c51f124SMoriah Waterland 		else if (mode == MAPINSTALL)
114*5c51f124SMoriah Waterland 			maptype = " install";
115*5c51f124SMoriah Waterland 		else
116*5c51f124SMoriah Waterland 			maptype = "";
117*5c51f124SMoriah Waterland 	}
118*5c51f124SMoriah Waterland }
119*5c51f124SMoriah Waterland 
120*5c51f124SMoriah Waterland /* This is the external query interface for mapmode. */
121*5c51f124SMoriah Waterland int
122*5c51f124SMoriah Waterland getmapmode(void)
123*5c51f124SMoriah Waterland {
124*5c51f124SMoriah Waterland 	return (mapmode);
125*5c51f124SMoriah Waterland }
126*5c51f124SMoriah Waterland 
127*5c51f124SMoriah Waterland /*
128*5c51f124SMoriah Waterland  * Unpack the pkgmap or the contents file or whatever file is in that format.
129*5c51f124SMoriah Waterland  * Based upon mapmode, environment parameters will be resolved for mode,
130*5c51f124SMoriah Waterland  * owner and group.
131*5c51f124SMoriah Waterland  */
132*5c51f124SMoriah Waterland 
133*5c51f124SMoriah Waterland int
134*5c51f124SMoriah Waterland gpkgmap(struct cfent *ept, FILE *fp)
135*5c51f124SMoriah Waterland {
136*5c51f124SMoriah Waterland 	int		c;
137*5c51f124SMoriah Waterland 	boolean_t	first_char = B_TRUE;
138*5c51f124SMoriah Waterland 
139*5c51f124SMoriah Waterland 	setErrstr(NULL);
140*5c51f124SMoriah Waterland 	ept->volno = 0;
141*5c51f124SMoriah Waterland 	ept->ftype = BADFTYPE;
142*5c51f124SMoriah Waterland 	(void) strcpy(ept->pkg_class, BADCLASS);
143*5c51f124SMoriah Waterland 	ept->pkg_class_idx = -1;
144*5c51f124SMoriah Waterland 	ept->path = NULL;
145*5c51f124SMoriah Waterland 	ept->ainfo.local = NULL;
146*5c51f124SMoriah Waterland 	/* default attributes were supplied, so don't reset */
147*5c51f124SMoriah Waterland 	ept->ainfo.mode = d_mode;
148*5c51f124SMoriah Waterland 	(void) strcpy(ept->ainfo.owner, d_owner);
149*5c51f124SMoriah Waterland 	(void) strcpy(ept->ainfo.group, d_group);
150*5c51f124SMoriah Waterland #ifdef SUNOS41
151*5c51f124SMoriah Waterland 	ept->ainfo.xmajor = BADMAJOR;
152*5c51f124SMoriah Waterland 	ept->ainfo.xminor = BADMINOR;
153*5c51f124SMoriah Waterland #else
154*5c51f124SMoriah Waterland 	ept->ainfo.major = BADMAJOR;
155*5c51f124SMoriah Waterland 	ept->ainfo.minor = BADMINOR;
156*5c51f124SMoriah Waterland #endif
157*5c51f124SMoriah Waterland 	ept->cinfo.cksum = ept->cinfo.modtime = ept->cinfo.size = (-1L);
158*5c51f124SMoriah Waterland 
159*5c51f124SMoriah Waterland 	ept->npkgs = 0;
160*5c51f124SMoriah Waterland 
161*5c51f124SMoriah Waterland 	if (!fp)
162*5c51f124SMoriah Waterland 		return (-1);
163*5c51f124SMoriah Waterland readline:
164*5c51f124SMoriah Waterland 	c = eatwhite(fp);
165*5c51f124SMoriah Waterland 
166*5c51f124SMoriah Waterland 	/*
167*5c51f124SMoriah Waterland 	 * If the first character is not a digit, we assume that the
168*5c51f124SMoriah Waterland 	 * volume number is 1.
169*5c51f124SMoriah Waterland 	 */
170*5c51f124SMoriah Waterland 	if (first_char && !isdigit(c)) {
171*5c51f124SMoriah Waterland 		ept->volno = 1;
172*5c51f124SMoriah Waterland 	}
173*5c51f124SMoriah Waterland 	first_char = B_FALSE;
174*5c51f124SMoriah Waterland 
175*5c51f124SMoriah Waterland 	switch (c) {
176*5c51f124SMoriah Waterland 	    case EOF:
177*5c51f124SMoriah Waterland 		return (0);
178*5c51f124SMoriah Waterland 
179*5c51f124SMoriah Waterland 	    case '0':
180*5c51f124SMoriah Waterland 	    case '1':
181*5c51f124SMoriah Waterland 	    case '2':
182*5c51f124SMoriah Waterland 	    case '3':
183*5c51f124SMoriah Waterland 	    case '4':
184*5c51f124SMoriah Waterland 	    case '5':
185*5c51f124SMoriah Waterland 	    case '6':
186*5c51f124SMoriah Waterland 	    case '7':
187*5c51f124SMoriah Waterland 	    case '8':
188*5c51f124SMoriah Waterland 	    case '9':
189*5c51f124SMoriah Waterland 		if (ept->volno) {
190*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BAD_VOLUME_NUMBER));
191*5c51f124SMoriah Waterland 			goto error;
192*5c51f124SMoriah Waterland 		}
193*5c51f124SMoriah Waterland 		do {
194*5c51f124SMoriah Waterland 			ept->volno = (ept->volno*10)+c-'0';
195*5c51f124SMoriah Waterland 			c = getc(fp);
196*5c51f124SMoriah Waterland 		} while (isdigit(c));
197*5c51f124SMoriah Waterland 		if (ept->volno == 0)
198*5c51f124SMoriah Waterland 			ept->volno = 1;
199*5c51f124SMoriah Waterland 
200*5c51f124SMoriah Waterland 		goto readline;
201*5c51f124SMoriah Waterland 
202*5c51f124SMoriah Waterland 	    case ':':
203*5c51f124SMoriah Waterland 	    case '#':
204*5c51f124SMoriah Waterland 		(void) getend(fp);
205*5c51f124SMoriah Waterland 		/*FALLTHRU*/
206*5c51f124SMoriah Waterland 	    case '\n':
207*5c51f124SMoriah Waterland 		/*
208*5c51f124SMoriah Waterland 		 * Since we are going to scan the next line,
209*5c51f124SMoriah Waterland 		 * we need to reset volume number and first_char.
210*5c51f124SMoriah Waterland 		 */
211*5c51f124SMoriah Waterland 		ept->volno = 0;
212*5c51f124SMoriah Waterland 		first_char = B_TRUE;
213*5c51f124SMoriah Waterland 		goto readline;
214*5c51f124SMoriah Waterland 
215*5c51f124SMoriah Waterland 	    case 'i':
216*5c51f124SMoriah Waterland 		ept->ftype = (char)c;
217*5c51f124SMoriah Waterland 		c = eatwhite(fp);
218*5c51f124SMoriah Waterland 		/*FALLTHRU*/
219*5c51f124SMoriah Waterland 	    case '.':
220*5c51f124SMoriah Waterland 	    case '/':
221*5c51f124SMoriah Waterland 		(void) ungetc(c, fp);
222*5c51f124SMoriah Waterland 
223*5c51f124SMoriah Waterland 		if (getstr(fp, "=", PATH_MAX, mypath)) {
224*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
225*5c51f124SMoriah Waterland 			goto error;
226*5c51f124SMoriah Waterland 		}
227*5c51f124SMoriah Waterland 		ept->path = mypath;
228*5c51f124SMoriah Waterland 		c = getc(fp);
229*5c51f124SMoriah Waterland 		if (c == '=') {
230*5c51f124SMoriah Waterland 			if (getstr(fp, NULL, PATH_MAX, mylocal)) {
231*5c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_CANT_READ_LCLPATH));
232*5c51f124SMoriah Waterland 				goto error;
233*5c51f124SMoriah Waterland 			}
234*5c51f124SMoriah Waterland 			ept->ainfo.local = mylocal;
235*5c51f124SMoriah Waterland 		} else
236*5c51f124SMoriah Waterland 			(void) ungetc(c, fp);
237*5c51f124SMoriah Waterland 
238*5c51f124SMoriah Waterland 		if (ept->ftype == 'i') {
239*5c51f124SMoriah Waterland 			/* content info might exist */
240*5c51f124SMoriah Waterland 			if (!getlnum(fp, 10, (fsblkcnt_t *)&ept->cinfo.size,
241*5c51f124SMoriah Waterland 			    BADCONT) &&
242*5c51f124SMoriah Waterland 			    (getnum(fp, 10, (long *)&ept->cinfo.cksum,
243*5c51f124SMoriah Waterland 			    BADCONT) ||
244*5c51f124SMoriah Waterland 			    getnum(fp, 10, (long *)&ept->cinfo.modtime,
245*5c51f124SMoriah Waterland 			    BADCONT))) {
246*5c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
247*5c51f124SMoriah Waterland 				goto error;
248*5c51f124SMoriah Waterland 			}
249*5c51f124SMoriah Waterland 		}
250*5c51f124SMoriah Waterland 		if (getend(fp)) {
251*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
252*5c51f124SMoriah Waterland 			return (-1);
253*5c51f124SMoriah Waterland 		}
254*5c51f124SMoriah Waterland 		return (1);
255*5c51f124SMoriah Waterland 
256*5c51f124SMoriah Waterland 	    case '?':
257*5c51f124SMoriah Waterland 	    case 'f':
258*5c51f124SMoriah Waterland 	    case 'v':
259*5c51f124SMoriah Waterland 	    case 'e':
260*5c51f124SMoriah Waterland 	    case 'l':
261*5c51f124SMoriah Waterland 	    case 's':
262*5c51f124SMoriah Waterland 	    case 'p':
263*5c51f124SMoriah Waterland 	    case 'c':
264*5c51f124SMoriah Waterland 	    case 'b':
265*5c51f124SMoriah Waterland 	    case 'd':
266*5c51f124SMoriah Waterland 	    case 'x':
267*5c51f124SMoriah Waterland 		ept->ftype = (char)c;
268*5c51f124SMoriah Waterland 		if (getstr(fp, NULL, CLSSIZ, ept->pkg_class)) {
269*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_CLASS_TOKEN));
270*5c51f124SMoriah Waterland 			goto error;
271*5c51f124SMoriah Waterland 		}
272*5c51f124SMoriah Waterland 		if (getstr(fp, "=", PATH_MAX, mypath)) {
273*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
274*5c51f124SMoriah Waterland 			goto error;
275*5c51f124SMoriah Waterland 		}
276*5c51f124SMoriah Waterland 		ept->path = mypath;
277*5c51f124SMoriah Waterland 
278*5c51f124SMoriah Waterland 		c = getc(fp);
279*5c51f124SMoriah Waterland 		if (c == '=') {
280*5c51f124SMoriah Waterland 			/* local path */
281*5c51f124SMoriah Waterland 			if (getstr(fp, NULL, PATH_MAX, mylocal)) {
282*5c51f124SMoriah Waterland 				if (ept->ftype == 's' || ept->ftype == 'l') {
283*5c51f124SMoriah Waterland 					setErrstr(pkg_gt(ERR_READLINK));
284*5c51f124SMoriah Waterland 				} else {
285*5c51f124SMoriah Waterland 					setErrstr(
286*5c51f124SMoriah Waterland 						pkg_gt(ERR_CANT_READ_LCLPATH));
287*5c51f124SMoriah Waterland 				}
288*5c51f124SMoriah Waterland 				goto error;
289*5c51f124SMoriah Waterland 			}
290*5c51f124SMoriah Waterland 			ept->ainfo.local = mylocal;
291*5c51f124SMoriah Waterland 		} else if (strchr("sl", ept->ftype)) {
292*5c51f124SMoriah Waterland 			if ((c != EOF) && (c != '\n'))
293*5c51f124SMoriah Waterland 				(void) getend(fp);
294*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BAD_LINK_SPEC));
295*5c51f124SMoriah Waterland 			return (-1);
296*5c51f124SMoriah Waterland 		} else
297*5c51f124SMoriah Waterland 			(void) ungetc(c, fp);
298*5c51f124SMoriah Waterland 		break;
299*5c51f124SMoriah Waterland 
300*5c51f124SMoriah Waterland 	    default:
301*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_UNKNOWN_FTYPE));
302*5c51f124SMoriah Waterland error:
303*5c51f124SMoriah Waterland 		(void) getend(fp);
304*5c51f124SMoriah Waterland 		return (-1);
305*5c51f124SMoriah Waterland 	}
306*5c51f124SMoriah Waterland 
307*5c51f124SMoriah Waterland 	if (strchr("sl", ept->ftype) && (ept->ainfo.local == NULL)) {
308*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_NO_LINKSOURCE));
309*5c51f124SMoriah Waterland 		goto error;
310*5c51f124SMoriah Waterland 	}
311*5c51f124SMoriah Waterland 
312*5c51f124SMoriah Waterland 	if (strchr("cb", ept->ftype)) {
313*5c51f124SMoriah Waterland #ifdef SUNOS41
314*5c51f124SMoriah Waterland 		ept->ainfo.xmajor = BADMAJOR;
315*5c51f124SMoriah Waterland 		ept->ainfo.xminor = BADMINOR;
316*5c51f124SMoriah Waterland 		if (getnum(fp, 10, (long *)&ept->ainfo.xmajor, BADMAJOR) ||
317*5c51f124SMoriah Waterland 		    getnum(fp, 10, (long *)&ept->ainfo.xminor, BADMINOR))
318*5c51f124SMoriah Waterland #else
319*5c51f124SMoriah Waterland 		ept->ainfo.major = BADMAJOR;
320*5c51f124SMoriah Waterland 		ept->ainfo.minor = BADMINOR;
321*5c51f124SMoriah Waterland 		if (getnum(fp, 10, (long *)&ept->ainfo.major, BADMAJOR) ||
322*5c51f124SMoriah Waterland 		    getnum(fp, 10, (long *)&ept->ainfo.minor, BADMINOR))
323*5c51f124SMoriah Waterland #endif
324*5c51f124SMoriah Waterland 		{
325*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_MM_DEVNUMS));
326*5c51f124SMoriah Waterland 			goto error;
327*5c51f124SMoriah Waterland 		}
328*5c51f124SMoriah Waterland 	}
329*5c51f124SMoriah Waterland 
330*5c51f124SMoriah Waterland 	/*
331*5c51f124SMoriah Waterland 	 * Links and information files don't have attributes associated with
332*5c51f124SMoriah Waterland 	 * them. The following either resolves potential variables or passes
333*5c51f124SMoriah Waterland 	 * them through. Mode is tested for validity to some degree. BAD???
334*5c51f124SMoriah Waterland 	 * is returned to indicate that no meaningful mode was provided. A
335*5c51f124SMoriah Waterland 	 * higher authority will decide if that's OK or not. CUR??? means that
336*5c51f124SMoriah Waterland 	 * the prototype file specifically requires a wildcard ('?') for
337*5c51f124SMoriah Waterland 	 * that entry. We issue an error if attributes were entered wrong.
338*5c51f124SMoriah Waterland 	 * We just return BAD??? if there was no entry at all.
339*5c51f124SMoriah Waterland 	 */
340*5c51f124SMoriah Waterland 	if (strchr("cbdxpfve", ept->ftype)) {
341*5c51f124SMoriah Waterland 		int retval;
342*5c51f124SMoriah Waterland 
343*5c51f124SMoriah Waterland 		if ((retval = getvalmode(fp, &(ept->ainfo.mode), CURMODE,
344*5c51f124SMoriah Waterland 		    (mapmode != MAPNONE))) == 1)
345*5c51f124SMoriah Waterland 			goto end;	/* nothing else on the line */
346*5c51f124SMoriah Waterland 		else if (retval == 2)
347*5c51f124SMoriah Waterland 			goto error;	/* mode is too no good */
348*5c51f124SMoriah Waterland 
349*5c51f124SMoriah Waterland 		/* owner & group should be here */
350*5c51f124SMoriah Waterland 		if ((retval = getstr(fp, NULL, ATRSIZ,
351*5c51f124SMoriah Waterland 		    ept->ainfo.owner)) == 1)
352*5c51f124SMoriah Waterland 			goto end;	/* no owner or group - warning */
353*5c51f124SMoriah Waterland 		if (retval == -1) {
354*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_OWNTOOLONG));
355*5c51f124SMoriah Waterland 			goto error;
356*5c51f124SMoriah Waterland 		}
357*5c51f124SMoriah Waterland 
358*5c51f124SMoriah Waterland 		if ((retval = getstr(fp, NULL, ATRSIZ,
359*5c51f124SMoriah Waterland 		    ept->ainfo.group)) == 1)
360*5c51f124SMoriah Waterland 			goto end;	/* no group - warning */
361*5c51f124SMoriah Waterland 		if (retval == -1) {
362*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_GRPTOOLONG));
363*5c51f124SMoriah Waterland 			goto error;
364*5c51f124SMoriah Waterland 		}
365*5c51f124SMoriah Waterland 
366*5c51f124SMoriah Waterland 		/* Resolve the parameters if required. */
367*5c51f124SMoriah Waterland 		if (mapmode != MAPNONE) {
368*5c51f124SMoriah Waterland 			if (mapvar(mapmode, ept->ainfo.owner)) {
369*5c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
370*5c51f124SMoriah Waterland 					getErrbufSize(),
371*5c51f124SMoriah Waterland 					pkg_gt(ERR_NOVAR),
372*5c51f124SMoriah Waterland 					maptype, ept->ainfo.owner);
373*5c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
374*5c51f124SMoriah Waterland 				goto error;
375*5c51f124SMoriah Waterland 			}
376*5c51f124SMoriah Waterland 			if (mapvar(mapmode, ept->ainfo.group)) {
377*5c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
378*5c51f124SMoriah Waterland 					getErrbufSize(), pkg_gt(ERR_NOVAR),
379*5c51f124SMoriah Waterland 					maptype, ept->ainfo.group);
380*5c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
381*5c51f124SMoriah Waterland 				goto error;
382*5c51f124SMoriah Waterland 			}
383*5c51f124SMoriah Waterland 		}
384*5c51f124SMoriah Waterland 	}
385*5c51f124SMoriah Waterland 
386*5c51f124SMoriah Waterland 	if (strchr("ifve", ept->ftype)) {
387*5c51f124SMoriah Waterland 		/* look for content description */
388*5c51f124SMoriah Waterland 		if (!getlnum(fp, 10, (fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
389*5c51f124SMoriah Waterland 		(getnum(fp, 10, (long *)&ept->cinfo.cksum, BADCONT) ||
390*5c51f124SMoriah Waterland 		getnum(fp, 10, (long *)&ept->cinfo.modtime, BADCONT))) {
391*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
392*5c51f124SMoriah Waterland 			goto error;
393*5c51f124SMoriah Waterland 		}
394*5c51f124SMoriah Waterland 	}
395*5c51f124SMoriah Waterland 
396*5c51f124SMoriah Waterland 	if (ept->ftype == 'i')
397*5c51f124SMoriah Waterland 		goto end;
398*5c51f124SMoriah Waterland 
399*5c51f124SMoriah Waterland end:
400*5c51f124SMoriah Waterland 	if (getend(fp) && ept->pinfo) {
401*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
402*5c51f124SMoriah Waterland 		return (-1);
403*5c51f124SMoriah Waterland 	}
404*5c51f124SMoriah Waterland 
405*5c51f124SMoriah Waterland done:
406*5c51f124SMoriah Waterland 	return (1);
407*5c51f124SMoriah Waterland }
408*5c51f124SMoriah Waterland 
409*5c51f124SMoriah Waterland /*
410*5c51f124SMoriah Waterland  * Get and validate the mode attribute. This returns an error if
411*5c51f124SMoriah Waterland  *	1. the mode string is too long
412*5c51f124SMoriah Waterland  *	2. the mode string includes alpha characters
413*5c51f124SMoriah Waterland  *	3. the mode string is not octal
414*5c51f124SMoriah Waterland  *	4. mode string is an install parameter
415*5c51f124SMoriah Waterland  *	5. mode is an unresolved build parameter and MAPBUILD is
416*5c51f124SMoriah Waterland  *	   in effect.
417*5c51f124SMoriah Waterland  * If the mode is a build parameter, it is
418*5c51f124SMoriah Waterland  *	1. returned as is if MAPNONE is in effect
419*5c51f124SMoriah Waterland  *	2. evaluated if MAPBUILD is in effect
420*5c51f124SMoriah Waterland  *
421*5c51f124SMoriah Waterland  * NOTE : We use "mapmode!=MAPBUILD" to gather that it is install
422*5c51f124SMoriah Waterland  * time. At install time we just fix a mode with bad bits set by
423*5c51f124SMoriah Waterland  * setting it to CURMODE. This should be an error in a few releases
424*5c51f124SMoriah Waterland  * (2.8 maybe) but faulty modes are so common in existing packages
425*5c51f124SMoriah Waterland  * that this is a reasonable exception. -- JST 1994-11-9
426*5c51f124SMoriah Waterland  *
427*5c51f124SMoriah Waterland  * RETURNS
428*5c51f124SMoriah Waterland  *	0 if mode is being returned as a valid value
429*5c51f124SMoriah Waterland  *	1 if no attributes are present on the line
430*5c51f124SMoriah Waterland  *	2 if there was a fundamental error
431*5c51f124SMoriah Waterland  */
432*5c51f124SMoriah Waterland static int
433*5c51f124SMoriah Waterland getvalmode(FILE *fp, mode_t *d, long bad, int map)
434*5c51f124SMoriah Waterland {
435*5c51f124SMoriah Waterland 	char tempmode[20];
436*5c51f124SMoriah Waterland 	mode_t tempmode_t;
437*5c51f124SMoriah Waterland 	int retval;
438*5c51f124SMoriah Waterland 
439*5c51f124SMoriah Waterland 	if ((retval = getstr(fp, NULL, ATRSIZ, tempmode)) == 1)
440*5c51f124SMoriah Waterland 		return (1);
441*5c51f124SMoriah Waterland 	else if (retval == -1) {
442*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_MODELONG));
443*5c51f124SMoriah Waterland 		return (2);
444*5c51f124SMoriah Waterland 	} else {
445*5c51f124SMoriah Waterland 		/*
446*5c51f124SMoriah Waterland 		 * If it isn't a '?' (meaning go with whatever mode is
447*5c51f124SMoriah Waterland 		 * there), validate the mode and convert it to a mode_t. The
448*5c51f124SMoriah Waterland 		 * "bad" variable here is a misnomer. It doesn't necessarily
449*5c51f124SMoriah Waterland 		 * mean bad.
450*5c51f124SMoriah Waterland 		 */
451*5c51f124SMoriah Waterland 		if (tempmode[0] == '?') {
452*5c51f124SMoriah Waterland 			*d = WILDCARD;
453*5c51f124SMoriah Waterland 		} else {
454*5c51f124SMoriah Waterland 			/*
455*5c51f124SMoriah Waterland 			 * Mode may not be an install parameter or a
456*5c51f124SMoriah Waterland 			 * non-build parameter.
457*5c51f124SMoriah Waterland 			 */
458*5c51f124SMoriah Waterland 			if (tempmode[0] == '$' &&
459*5c51f124SMoriah Waterland 			    (isupper(tempmode[1]) || !islower(tempmode[1]))) {
460*5c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_IMODE));
461*5c51f124SMoriah Waterland 				return (2);
462*5c51f124SMoriah Waterland 			}
463*5c51f124SMoriah Waterland 
464*5c51f124SMoriah Waterland 			if ((map) && (mapvar(mapmode, tempmode))) {
465*5c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
466*5c51f124SMoriah Waterland 						getErrbufSize(),
467*5c51f124SMoriah Waterland 						pkg_gt(ERR_NOVAR),
468*5c51f124SMoriah Waterland 						maptype, tempmode);
469*5c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
470*5c51f124SMoriah Waterland 				return (2);
471*5c51f124SMoriah Waterland 			}
472*5c51f124SMoriah Waterland 
473*5c51f124SMoriah Waterland 
474*5c51f124SMoriah Waterland 			if (tempmode[0] == '$') {
475*5c51f124SMoriah Waterland 				*d = BADMODE;	/* may be a problem */
476*5c51f124SMoriah Waterland 			} else {
477*5c51f124SMoriah Waterland 				/*
478*5c51f124SMoriah Waterland 				 * At this point it's supposed to be
479*5c51f124SMoriah Waterland 				 * something we can convert to a number.
480*5c51f124SMoriah Waterland 				 */
481*5c51f124SMoriah Waterland 				int n = 0;
482*5c51f124SMoriah Waterland 
483*5c51f124SMoriah Waterland 				/*
484*5c51f124SMoriah Waterland 				 * We reject it if it contains nonnumbers or
485*5c51f124SMoriah Waterland 				 * it's not octal.
486*5c51f124SMoriah Waterland 				 */
487*5c51f124SMoriah Waterland 				while (tempmode[n] && !isspace(tempmode[n])) {
488*5c51f124SMoriah Waterland 					if (!isdigit(tempmode[n])) {
489*5c51f124SMoriah Waterland 						setErrstr(
490*5c51f124SMoriah Waterland 							pkg_gt(ERR_MODEALPHA));
491*5c51f124SMoriah Waterland 						return (2);
492*5c51f124SMoriah Waterland 					}
493*5c51f124SMoriah Waterland 
494*5c51f124SMoriah Waterland 					if (strchr("89abcdefABCDEF",
495*5c51f124SMoriah Waterland 					    tempmode[n])) {
496*5c51f124SMoriah Waterland 						setErrstr(
497*5c51f124SMoriah Waterland 							pkg_gt(ERR_BASEINVAL));
498*5c51f124SMoriah Waterland 						return (2);
499*5c51f124SMoriah Waterland 					}
500*5c51f124SMoriah Waterland 					n++;
501*5c51f124SMoriah Waterland 				}
502*5c51f124SMoriah Waterland 
503*5c51f124SMoriah Waterland 				tempmode_t = strtol(tempmode, NULL, 8);
504*5c51f124SMoriah Waterland 
505*5c51f124SMoriah Waterland 				/*
506*5c51f124SMoriah Waterland 				 * We reject it if it contains inappropriate
507*5c51f124SMoriah Waterland 				 * bits.
508*5c51f124SMoriah Waterland 				 */
509*5c51f124SMoriah Waterland 				if (tempmode_t & ~(S_IAMB |
510*5c51f124SMoriah Waterland 				    S_ISUID | S_ISGID | S_ISVTX)) {
511*5c51f124SMoriah Waterland 					if (mapmode != MAPBUILD) {
512*5c51f124SMoriah Waterland 						tempmode_t = bad;
513*5c51f124SMoriah Waterland 					} else {
514*5c51f124SMoriah Waterland 						setErrstr(pkg_gt(ERR_MODEBITS));
515*5c51f124SMoriah Waterland 						return (2);
516*5c51f124SMoriah Waterland 					}
517*5c51f124SMoriah Waterland 				}
518*5c51f124SMoriah Waterland 				*d = tempmode_t;
519*5c51f124SMoriah Waterland 			}
520*5c51f124SMoriah Waterland 		}
521*5c51f124SMoriah Waterland 		return (0);
522*5c51f124SMoriah Waterland 	}
523*5c51f124SMoriah Waterland }
524*5c51f124SMoriah Waterland 
525*5c51f124SMoriah Waterland static int
526*5c51f124SMoriah Waterland getnum(FILE *fp, int base, long *d, long bad)
527*5c51f124SMoriah Waterland {
528*5c51f124SMoriah Waterland 	int c, b;
529*5c51f124SMoriah Waterland 
530*5c51f124SMoriah Waterland 	/* leading white space ignored */
531*5c51f124SMoriah Waterland 	c = eatwhite(fp);
532*5c51f124SMoriah Waterland 	if (c == '?') {
533*5c51f124SMoriah Waterland 		*d = bad;
534*5c51f124SMoriah Waterland 		return (0);
535*5c51f124SMoriah Waterland 	}
536*5c51f124SMoriah Waterland 
537*5c51f124SMoriah Waterland 	if ((c == EOF) || (c == '\n') || !isdigit(c)) {
538*5c51f124SMoriah Waterland 		(void) ungetc(c, fp);
539*5c51f124SMoriah Waterland 		return (1);
540*5c51f124SMoriah Waterland 	}
541*5c51f124SMoriah Waterland 
542*5c51f124SMoriah Waterland 	*d = 0;
543*5c51f124SMoriah Waterland 	while (isdigit(c)) {
544*5c51f124SMoriah Waterland 		b = (c & 017);
545*5c51f124SMoriah Waterland 		if (b >= base)
546*5c51f124SMoriah Waterland 			return (2);
547*5c51f124SMoriah Waterland 		*d = (*d * base) + b;
548*5c51f124SMoriah Waterland 		c = getc(fp);
549*5c51f124SMoriah Waterland 	}
550*5c51f124SMoriah Waterland 	(void) ungetc(c, fp);
551*5c51f124SMoriah Waterland 	return (0);
552*5c51f124SMoriah Waterland }
553*5c51f124SMoriah Waterland 
554*5c51f124SMoriah Waterland static int
555*5c51f124SMoriah Waterland getlnum(FILE *fp, int base, fsblkcnt_t *d, long bad)
556*5c51f124SMoriah Waterland {
557*5c51f124SMoriah Waterland 	int c, b;
558*5c51f124SMoriah Waterland 
559*5c51f124SMoriah Waterland 	/* leading white space ignored */
560*5c51f124SMoriah Waterland 	c = eatwhite(fp);
561*5c51f124SMoriah Waterland 	if (c == '?') {
562*5c51f124SMoriah Waterland 		*d = bad;
563*5c51f124SMoriah Waterland 		return (0);
564*5c51f124SMoriah Waterland 	}
565*5c51f124SMoriah Waterland 
566*5c51f124SMoriah Waterland 	if ((c == EOF) || (c == '\n') || !isdigit(c)) {
567*5c51f124SMoriah Waterland 		(void) ungetc(c, fp);
568*5c51f124SMoriah Waterland 		return (1);
569*5c51f124SMoriah Waterland 	}
570*5c51f124SMoriah Waterland 
571*5c51f124SMoriah Waterland 	*d = 0;
572*5c51f124SMoriah Waterland 	while (isdigit(c)) {
573*5c51f124SMoriah Waterland 		b = (c & 017);
574*5c51f124SMoriah Waterland 		if (b >= base)
575*5c51f124SMoriah Waterland 			return (2);
576*5c51f124SMoriah Waterland 		*d = (*d * base) + b;
577*5c51f124SMoriah Waterland 		c = getc(fp);
578*5c51f124SMoriah Waterland 	}
579*5c51f124SMoriah Waterland 	(void) ungetc(c, fp);
580*5c51f124SMoriah Waterland 	return (0);
581*5c51f124SMoriah Waterland }
582*5c51f124SMoriah Waterland 
583*5c51f124SMoriah Waterland /*
584*5c51f124SMoriah Waterland  *  Get a string from the file. Returns
585*5c51f124SMoriah Waterland  *	0 if all OK
586*5c51f124SMoriah Waterland  *	1 if nothing there
587*5c51f124SMoriah Waterland  *	-1 if string is too long
588*5c51f124SMoriah Waterland  */
589*5c51f124SMoriah Waterland static int
590*5c51f124SMoriah Waterland getstr(FILE *fp, char *sep, int n, char *str)
591*5c51f124SMoriah Waterland {
592*5c51f124SMoriah Waterland 	int c;
593*5c51f124SMoriah Waterland 
594*5c51f124SMoriah Waterland 	/* leading white space ignored */
595*5c51f124SMoriah Waterland 	c = eatwhite(fp);
596*5c51f124SMoriah Waterland 	if ((c == EOF) || (c == '\n')) {
597*5c51f124SMoriah Waterland 		(void) ungetc(c, fp);
598*5c51f124SMoriah Waterland 		return (1); /* nothing there */
599*5c51f124SMoriah Waterland 	}
600*5c51f124SMoriah Waterland 
601*5c51f124SMoriah Waterland 	/* fill up string until space, tab, or separator */
602*5c51f124SMoriah Waterland 	while (!strchr(" \t", c) && (!sep || !strchr(sep, c))) {
603*5c51f124SMoriah Waterland 		if (n-- < 1) {
604*5c51f124SMoriah Waterland 			*str = '\0';
605*5c51f124SMoriah Waterland 			return (-1); /* too long */
606*5c51f124SMoriah Waterland 		}
607*5c51f124SMoriah Waterland 		*str++ = (char)c;
608*5c51f124SMoriah Waterland 		c = getc(fp);
609*5c51f124SMoriah Waterland 		if ((c == EOF) || (c == '\n'))
610*5c51f124SMoriah Waterland 			break; /* no more on this line */
611*5c51f124SMoriah Waterland 	}
612*5c51f124SMoriah Waterland 	*str = '\0';
613*5c51f124SMoriah Waterland 	(void) ungetc(c, fp);
614*5c51f124SMoriah Waterland 
615*5c51f124SMoriah Waterland 	return (0);
616*5c51f124SMoriah Waterland }
617*5c51f124SMoriah Waterland 
618*5c51f124SMoriah Waterland static int
619*5c51f124SMoriah Waterland getend(FILE *fp)
620*5c51f124SMoriah Waterland {
621*5c51f124SMoriah Waterland 	int c;
622*5c51f124SMoriah Waterland 	int n;
623*5c51f124SMoriah Waterland 
624*5c51f124SMoriah Waterland 	n = 0;
625*5c51f124SMoriah Waterland 	do {
626*5c51f124SMoriah Waterland 		if ((c = getc(fp)) == EOF)
627*5c51f124SMoriah Waterland 			return (n);
628*5c51f124SMoriah Waterland 		if (!isspace(c))
629*5c51f124SMoriah Waterland 			n++;
630*5c51f124SMoriah Waterland 	} while (c != '\n');
631*5c51f124SMoriah Waterland 	return (n);
632*5c51f124SMoriah Waterland }
633*5c51f124SMoriah Waterland 
634*5c51f124SMoriah Waterland static int
635*5c51f124SMoriah Waterland eatwhite(FILE *fp)
636*5c51f124SMoriah Waterland {
637*5c51f124SMoriah Waterland 	int c;
638*5c51f124SMoriah Waterland 
639*5c51f124SMoriah Waterland 	/* this test works around a side effect of getc() */
640*5c51f124SMoriah Waterland 	if (feof(fp))
641*5c51f124SMoriah Waterland 		return (EOF);
642*5c51f124SMoriah Waterland 	do
643*5c51f124SMoriah Waterland 		c = getc(fp);
644*5c51f124SMoriah Waterland 	while ((c == ' ') || (c == '\t'));
645*5c51f124SMoriah Waterland 	return (c);
646*5c51f124SMoriah Waterland }
647*5c51f124SMoriah Waterland 
648*5c51f124SMoriah Waterland int
649*5c51f124SMoriah Waterland gpkgmapvfp(struct cfent *ept, VFP_T *vfp)
650*5c51f124SMoriah Waterland {
651*5c51f124SMoriah Waterland 	int		c;
652*5c51f124SMoriah Waterland 	boolean_t	first_char = B_TRUE;
653*5c51f124SMoriah Waterland 	(void) strlcpy(ept->pkg_class, BADCLASS, sizeof (ept->pkg_class));
654*5c51f124SMoriah Waterland 	(void) strlcpy(ept->ainfo.owner, d_owner, sizeof (ept->ainfo.owner));
655*5c51f124SMoriah Waterland 	(void) strlcpy(ept->ainfo.group, d_group, sizeof (ept->ainfo.group));
656*5c51f124SMoriah Waterland 
657*5c51f124SMoriah Waterland 	setErrstr(NULL);
658*5c51f124SMoriah Waterland 	ept->volno = 0;
659*5c51f124SMoriah Waterland 	ept->ftype = BADFTYPE;
660*5c51f124SMoriah Waterland 	ept->pkg_class_idx = -1;
661*5c51f124SMoriah Waterland 	ept->path = NULL;
662*5c51f124SMoriah Waterland 	ept->ainfo.local = NULL;
663*5c51f124SMoriah Waterland 	ept->ainfo.mode = d_mode;
664*5c51f124SMoriah Waterland 	ept->ainfo.major = BADMAJOR;
665*5c51f124SMoriah Waterland 	ept->ainfo.minor = BADMINOR;
666*5c51f124SMoriah Waterland 	ept->cinfo.cksum = (-1L);
667*5c51f124SMoriah Waterland 	ept->cinfo.modtime = (-1L);
668*5c51f124SMoriah Waterland 	ept->cinfo.size = (-1L);
669*5c51f124SMoriah Waterland 
670*5c51f124SMoriah Waterland 	ept->npkgs = 0;
671*5c51f124SMoriah Waterland 
672*5c51f124SMoriah Waterland 	/* return error if no vfp specified */
673*5c51f124SMoriah Waterland 
674*5c51f124SMoriah Waterland 	if (vfp == (VFP_T *)NULL) {
675*5c51f124SMoriah Waterland 		return (-1);
676*5c51f124SMoriah Waterland 	}
677*5c51f124SMoriah Waterland 
678*5c51f124SMoriah Waterland readline:
679*5c51f124SMoriah Waterland 	while (((c = vfpGetcNoInc(vfp)) != '\0') && (isspace(vfpGetc(vfp))))
680*5c51f124SMoriah Waterland 		;
681*5c51f124SMoriah Waterland 
682*5c51f124SMoriah Waterland 	/*
683*5c51f124SMoriah Waterland 	 * If the first character is not a digit, we assume that the
684*5c51f124SMoriah Waterland 	 * volume number is 1.
685*5c51f124SMoriah Waterland 	 */
686*5c51f124SMoriah Waterland 	if (first_char && !isdigit(c)) {
687*5c51f124SMoriah Waterland 		ept->volno = 1;
688*5c51f124SMoriah Waterland 	}
689*5c51f124SMoriah Waterland 	first_char = B_FALSE;
690*5c51f124SMoriah Waterland 
691*5c51f124SMoriah Waterland 	/*
692*5c51f124SMoriah Waterland 	 * In case of hsfs the zero-padding of partial pages
693*5c51f124SMoriah Waterland 	 * returned by mmap is not done properly. A separate bug has been filed
694*5c51f124SMoriah Waterland 	 * on this.
695*5c51f124SMoriah Waterland 	 */
696*5c51f124SMoriah Waterland 
697*5c51f124SMoriah Waterland 	if (vfp->_vfpCurr && (vfp->_vfpCurr > vfp->_vfpEnd)) {
698*5c51f124SMoriah Waterland 		return (0);
699*5c51f124SMoriah Waterland 	}
700*5c51f124SMoriah Waterland 
701*5c51f124SMoriah Waterland 	switch (c) {
702*5c51f124SMoriah Waterland 	    case '\0':
703*5c51f124SMoriah Waterland 		return (0);
704*5c51f124SMoriah Waterland 
705*5c51f124SMoriah Waterland 	    case '0':
706*5c51f124SMoriah Waterland 	    case '1':
707*5c51f124SMoriah Waterland 	    case '2':
708*5c51f124SMoriah Waterland 	    case '3':
709*5c51f124SMoriah Waterland 	    case '4':
710*5c51f124SMoriah Waterland 	    case '5':
711*5c51f124SMoriah Waterland 	    case '6':
712*5c51f124SMoriah Waterland 	    case '7':
713*5c51f124SMoriah Waterland 	    case '8':
714*5c51f124SMoriah Waterland 	    case '9':
715*5c51f124SMoriah Waterland 		if (ept->volno) {
716*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BAD_VOLUME_NUMBER));
717*5c51f124SMoriah Waterland 			goto error;
718*5c51f124SMoriah Waterland 		}
719*5c51f124SMoriah Waterland 		do {
720*5c51f124SMoriah Waterland 			ept->volno = (ept->volno*10)+c-'0';
721*5c51f124SMoriah Waterland 			c = vfpGetc(vfp);
722*5c51f124SMoriah Waterland 		} while (isdigit(c));
723*5c51f124SMoriah Waterland 		if (ept->volno == 0) {
724*5c51f124SMoriah Waterland 			ept->volno = 1;
725*5c51f124SMoriah Waterland 		}
726*5c51f124SMoriah Waterland 
727*5c51f124SMoriah Waterland 		goto readline;
728*5c51f124SMoriah Waterland 
729*5c51f124SMoriah Waterland 	    case ':':
730*5c51f124SMoriah Waterland 	    case '#':
731*5c51f124SMoriah Waterland 		(void) findendvfp(&vfpGetCurrCharPtr(vfp));
732*5c51f124SMoriah Waterland 		/*FALLTHRU*/
733*5c51f124SMoriah Waterland 	    case '\n':
734*5c51f124SMoriah Waterland 		/*
735*5c51f124SMoriah Waterland 		 * Since we are going to scan the next line,
736*5c51f124SMoriah Waterland 		 * we need to reset volume number and first_char.
737*5c51f124SMoriah Waterland 		 */
738*5c51f124SMoriah Waterland 		ept->volno = 0;
739*5c51f124SMoriah Waterland 		first_char = B_TRUE;
740*5c51f124SMoriah Waterland 		goto readline;
741*5c51f124SMoriah Waterland 
742*5c51f124SMoriah Waterland 	    case 'i':
743*5c51f124SMoriah Waterland 		ept->ftype = (char)c;
744*5c51f124SMoriah Waterland 		while (((c = vfpGetcNoInc(vfp)) != '\0') &&
745*5c51f124SMoriah Waterland 						(isspace(vfpGetc(vfp))))
746*5c51f124SMoriah Waterland 			;
747*5c51f124SMoriah Waterland 		/*FALLTHRU*/
748*5c51f124SMoriah Waterland 	    case '.':
749*5c51f124SMoriah Waterland 	    case '/':
750*5c51f124SMoriah Waterland 		vfpDecCurrPtr(vfp);
751*5c51f124SMoriah Waterland 
752*5c51f124SMoriah Waterland 		if (getstrvfp(&vfpGetCurrCharPtr(vfp), "=", PATH_MAX, mypath)) {
753*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
754*5c51f124SMoriah Waterland 			goto error;
755*5c51f124SMoriah Waterland 		}
756*5c51f124SMoriah Waterland 		ept->path = mypath;
757*5c51f124SMoriah Waterland 		c = vfpGetc(vfp);
758*5c51f124SMoriah Waterland 		if (c == '=') {
759*5c51f124SMoriah Waterland 			if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, PATH_MAX,
760*5c51f124SMoriah Waterland 							mylocal)) {
761*5c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_CANT_READ_LCLPATH));
762*5c51f124SMoriah Waterland 				goto error;
763*5c51f124SMoriah Waterland 			}
764*5c51f124SMoriah Waterland 			ept->ainfo.local = mylocal;
765*5c51f124SMoriah Waterland 		} else {
766*5c51f124SMoriah Waterland 			vfpDecCurrPtr(vfp);
767*5c51f124SMoriah Waterland 		}
768*5c51f124SMoriah Waterland 
769*5c51f124SMoriah Waterland 		if (ept->ftype == 'i') {
770*5c51f124SMoriah Waterland 			/* content info might exist */
771*5c51f124SMoriah Waterland 			if (!getlnumvfp(&vfpGetCurrCharPtr(vfp), 10,
772*5c51f124SMoriah Waterland 				(fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
773*5c51f124SMoriah Waterland 			    (getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
774*5c51f124SMoriah Waterland 				(long *)&ept->cinfo.cksum, BADCONT) ||
775*5c51f124SMoriah Waterland 			    getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
776*5c51f124SMoriah Waterland 				(long *)&ept->cinfo.modtime, BADCONT))) {
777*5c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
778*5c51f124SMoriah Waterland 				goto error;
779*5c51f124SMoriah Waterland 			}
780*5c51f124SMoriah Waterland 		}
781*5c51f124SMoriah Waterland 
782*5c51f124SMoriah Waterland 		if (getendvfp(&vfpGetCurrCharPtr(vfp))) {
783*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
784*5c51f124SMoriah Waterland 			return (-1);
785*5c51f124SMoriah Waterland 		}
786*5c51f124SMoriah Waterland 		return (1);
787*5c51f124SMoriah Waterland 
788*5c51f124SMoriah Waterland 	    case '?':
789*5c51f124SMoriah Waterland 	    case 'f':
790*5c51f124SMoriah Waterland 	    case 'v':
791*5c51f124SMoriah Waterland 	    case 'e':
792*5c51f124SMoriah Waterland 	    case 'l':
793*5c51f124SMoriah Waterland 	    case 's':
794*5c51f124SMoriah Waterland 	    case 'p':
795*5c51f124SMoriah Waterland 	    case 'c':
796*5c51f124SMoriah Waterland 	    case 'b':
797*5c51f124SMoriah Waterland 	    case 'd':
798*5c51f124SMoriah Waterland 	    case 'x':
799*5c51f124SMoriah Waterland 		ept->ftype = (char)c;
800*5c51f124SMoriah Waterland 		if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL,
801*5c51f124SMoriah Waterland 						CLSSIZ, ept->pkg_class)) {
802*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_CLASS_TOKEN));
803*5c51f124SMoriah Waterland 			goto error;
804*5c51f124SMoriah Waterland 		}
805*5c51f124SMoriah Waterland 		if (getstrvfp(&vfpGetCurrCharPtr(vfp), "=", PATH_MAX, mypath)) {
806*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
807*5c51f124SMoriah Waterland 			goto error;
808*5c51f124SMoriah Waterland 		}
809*5c51f124SMoriah Waterland 		ept->path = mypath;
810*5c51f124SMoriah Waterland 
811*5c51f124SMoriah Waterland 		c = vfpGetc(vfp);
812*5c51f124SMoriah Waterland 		if (c == '=') {
813*5c51f124SMoriah Waterland 			/* local path */
814*5c51f124SMoriah Waterland 			if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL,
815*5c51f124SMoriah Waterland 							PATH_MAX, mylocal)) {
816*5c51f124SMoriah Waterland 				if (ept->ftype == 's' || ept->ftype == 'l') {
817*5c51f124SMoriah Waterland 					setErrstr(pkg_gt(ERR_READLINK));
818*5c51f124SMoriah Waterland 				} else {
819*5c51f124SMoriah Waterland 					setErrstr(
820*5c51f124SMoriah Waterland 						pkg_gt(ERR_CANT_READ_LCLPATH));
821*5c51f124SMoriah Waterland 				}
822*5c51f124SMoriah Waterland 				goto error;
823*5c51f124SMoriah Waterland 			}
824*5c51f124SMoriah Waterland 			ept->ainfo.local = mylocal;
825*5c51f124SMoriah Waterland 		} else if ((ept->ftype == 's') || (ept->ftype == 'l')) {
826*5c51f124SMoriah Waterland 			if ((c != '\0') && (c != '\n'))
827*5c51f124SMoriah Waterland 				(void) findendvfp(&vfpGetCurrCharPtr(vfp));
828*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BAD_LINK_SPEC));
829*5c51f124SMoriah Waterland 			return (-1);
830*5c51f124SMoriah Waterland 		} else {
831*5c51f124SMoriah Waterland 			vfpDecCurrPtr(vfp);
832*5c51f124SMoriah Waterland 		}
833*5c51f124SMoriah Waterland 		break;
834*5c51f124SMoriah Waterland 
835*5c51f124SMoriah Waterland 	    default:
836*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_UNKNOWN_FTYPE));
837*5c51f124SMoriah Waterland error:
838*5c51f124SMoriah Waterland 		(void) findendvfp(&vfpGetCurrCharPtr(vfp));
839*5c51f124SMoriah Waterland 		return (-1);
840*5c51f124SMoriah Waterland 	}
841*5c51f124SMoriah Waterland 
842*5c51f124SMoriah Waterland 	if (((ept->ftype == 's') || (ept->ftype == 'l')) &&
843*5c51f124SMoriah Waterland 					(ept->ainfo.local == NULL)) {
844*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_NO_LINKSOURCE));
845*5c51f124SMoriah Waterland 		goto error;
846*5c51f124SMoriah Waterland 	}
847*5c51f124SMoriah Waterland 
848*5c51f124SMoriah Waterland 	if (((ept->ftype == 'c') || (ept->ftype == 'b'))) {
849*5c51f124SMoriah Waterland 		ept->ainfo.major = BADMAJOR;
850*5c51f124SMoriah Waterland 		ept->ainfo.minor = BADMINOR;
851*5c51f124SMoriah Waterland 
852*5c51f124SMoriah Waterland 		if (getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
853*5c51f124SMoriah Waterland 				(long *)&ept->ainfo.major, BADMAJOR) ||
854*5c51f124SMoriah Waterland 		    getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
855*5c51f124SMoriah Waterland 				(long *)&ept->ainfo.minor, BADMINOR)) {
856*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_MM_DEVNUMS));
857*5c51f124SMoriah Waterland 			goto error;
858*5c51f124SMoriah Waterland 		}
859*5c51f124SMoriah Waterland 	}
860*5c51f124SMoriah Waterland 
861*5c51f124SMoriah Waterland 	/*
862*5c51f124SMoriah Waterland 	 * Links and information files don't have attributes associated with
863*5c51f124SMoriah Waterland 	 * them. The following either resolves potential variables or passes
864*5c51f124SMoriah Waterland 	 * them through. Mode is tested for validity to some degree. BAD???
865*5c51f124SMoriah Waterland 	 * is returned to indicate that no meaningful mode was provided. A
866*5c51f124SMoriah Waterland 	 * higher authority will decide if that's OK or not. CUR??? means that
867*5c51f124SMoriah Waterland 	 * the prototype file specifically requires a wildcard ('?') for
868*5c51f124SMoriah Waterland 	 * that entry. We issue an error if attributes were entered wrong.
869*5c51f124SMoriah Waterland 	 * We just return BAD??? if there was no entry at all.
870*5c51f124SMoriah Waterland 	 */
871*5c51f124SMoriah Waterland 	if ((ept->ftype == 'd') || (ept->ftype == 'x') || (ept->ftype == 'c') ||
872*5c51f124SMoriah Waterland 		(ept->ftype == 'b') || (ept->ftype == 'p') ||
873*5c51f124SMoriah Waterland 		(ept->ftype == 'f') || (ept->ftype == 'v') ||
874*5c51f124SMoriah Waterland 		(ept->ftype == 'e')) {
875*5c51f124SMoriah Waterland 		int retval;
876*5c51f124SMoriah Waterland 
877*5c51f124SMoriah Waterland 		retval = getvalmodevfp(&vfpGetCurrCharPtr(vfp),
878*5c51f124SMoriah Waterland 				&(ept->ainfo.mode),
879*5c51f124SMoriah Waterland 				CURMODE, (mapmode != MAPNONE));
880*5c51f124SMoriah Waterland 
881*5c51f124SMoriah Waterland 		if (retval == 1) {
882*5c51f124SMoriah Waterland 			goto end;	/* nothing else on the line */
883*5c51f124SMoriah Waterland 		} else if (retval == 2) {
884*5c51f124SMoriah Waterland 			goto error;	/* mode is too no good */
885*5c51f124SMoriah Waterland 		}
886*5c51f124SMoriah Waterland 
887*5c51f124SMoriah Waterland 		/* owner & group should be here */
888*5c51f124SMoriah Waterland 		if ((retval = getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, ATRSIZ,
889*5c51f124SMoriah Waterland 		    ept->ainfo.owner)) == 1)
890*5c51f124SMoriah Waterland 			goto end;	/* no owner or group - warning */
891*5c51f124SMoriah Waterland 		if (retval == -1) {
892*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_OWNTOOLONG));
893*5c51f124SMoriah Waterland 			goto error;
894*5c51f124SMoriah Waterland 		}
895*5c51f124SMoriah Waterland 
896*5c51f124SMoriah Waterland 		if ((retval = getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, ATRSIZ,
897*5c51f124SMoriah Waterland 		    ept->ainfo.group)) == 1)
898*5c51f124SMoriah Waterland 			goto end;	/* no group - warning */
899*5c51f124SMoriah Waterland 		if (retval == -1) {
900*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_GRPTOOLONG));
901*5c51f124SMoriah Waterland 			goto error;
902*5c51f124SMoriah Waterland 		}
903*5c51f124SMoriah Waterland 
904*5c51f124SMoriah Waterland 		/* Resolve the parameters if required. */
905*5c51f124SMoriah Waterland 		if (mapmode != MAPNONE) {
906*5c51f124SMoriah Waterland 			if (mapvar(mapmode, ept->ainfo.owner)) {
907*5c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
908*5c51f124SMoriah Waterland 					getErrbufSize(), pkg_gt(ERR_NOVAR),
909*5c51f124SMoriah Waterland 					maptype, ept->ainfo.owner);
910*5c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
911*5c51f124SMoriah Waterland 				goto error;
912*5c51f124SMoriah Waterland 			}
913*5c51f124SMoriah Waterland 			if (mapvar(mapmode, ept->ainfo.group)) {
914*5c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
915*5c51f124SMoriah Waterland 					getErrbufSize(), pkg_gt(ERR_NOVAR),
916*5c51f124SMoriah Waterland 					maptype, ept->ainfo.group);
917*5c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
918*5c51f124SMoriah Waterland 				goto error;
919*5c51f124SMoriah Waterland 			}
920*5c51f124SMoriah Waterland 		}
921*5c51f124SMoriah Waterland 	}
922*5c51f124SMoriah Waterland 
923*5c51f124SMoriah Waterland 	if ((ept->ftype == 'i') || (ept->ftype == 'f') ||
924*5c51f124SMoriah Waterland 			(ept->ftype == 'v') || (ept->ftype == 'e')) {
925*5c51f124SMoriah Waterland 		/* look for content description */
926*5c51f124SMoriah Waterland 		if (!getlnumvfp(&vfpGetCurrCharPtr(vfp), 10,
927*5c51f124SMoriah Waterland 				(fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
928*5c51f124SMoriah Waterland 		(getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
929*5c51f124SMoriah Waterland 				(long *)&ept->cinfo.cksum, BADCONT) ||
930*5c51f124SMoriah Waterland 		getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
931*5c51f124SMoriah Waterland 				(long *)&ept->cinfo.modtime, BADCONT))) {
932*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
933*5c51f124SMoriah Waterland 			goto error;
934*5c51f124SMoriah Waterland 		}
935*5c51f124SMoriah Waterland 	}
936*5c51f124SMoriah Waterland 
937*5c51f124SMoriah Waterland 	if (ept->ftype == 'i')
938*5c51f124SMoriah Waterland 		goto end;
939*5c51f124SMoriah Waterland 
940*5c51f124SMoriah Waterland end:
941*5c51f124SMoriah Waterland 	if (getendvfp(&vfpGetCurrCharPtr(vfp)) && ept->pinfo) {
942*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
943*5c51f124SMoriah Waterland 		return (-1);
944*5c51f124SMoriah Waterland 	}
945*5c51f124SMoriah Waterland 
946*5c51f124SMoriah Waterland done:
947*5c51f124SMoriah Waterland 	return (1);
948*5c51f124SMoriah Waterland }
949*5c51f124SMoriah Waterland 
950*5c51f124SMoriah Waterland /*
951*5c51f124SMoriah Waterland  * Get and validate the mode attribute. This returns an error if
952*5c51f124SMoriah Waterland  *	1. the mode string is too long
953*5c51f124SMoriah Waterland  *	2. the mode string includes alpha characters
954*5c51f124SMoriah Waterland  *	3. the mode string is not octal
955*5c51f124SMoriah Waterland  *	4. mode string is an install parameter
956*5c51f124SMoriah Waterland  *	5. mode is an unresolved build parameter and MAPBUILD is
957*5c51f124SMoriah Waterland  *	   in effect.
958*5c51f124SMoriah Waterland  * If the mode is a build parameter, it is
959*5c51f124SMoriah Waterland  *	1. returned as is if MAPNONE is in effect
960*5c51f124SMoriah Waterland  *	2. evaluated if MAPBUILD is in effect
961*5c51f124SMoriah Waterland  *
962*5c51f124SMoriah Waterland  * NOTE : We use "mapmode!=MAPBUILD" to gather that it is install
963*5c51f124SMoriah Waterland  * time. At install time we just fix a mode with bad bits set by
964*5c51f124SMoriah Waterland  * setting it to CURMODE. This should be an error in a few releases
965*5c51f124SMoriah Waterland  * (2.8 maybe) but faulty modes are so common in existing packages
966*5c51f124SMoriah Waterland  * that this is a reasonable exception. -- JST 1994-11-9
967*5c51f124SMoriah Waterland  *
968*5c51f124SMoriah Waterland  * RETURNS
969*5c51f124SMoriah Waterland  *	0 if mode is being returned as a valid value
970*5c51f124SMoriah Waterland  *	1 if no attributes are present on the line
971*5c51f124SMoriah Waterland  *	2 if there was a fundamental error
972*5c51f124SMoriah Waterland  */
973*5c51f124SMoriah Waterland static int
974*5c51f124SMoriah Waterland getvalmodevfp(char **cp, mode_t *d, long bad, int map)
975*5c51f124SMoriah Waterland {
976*5c51f124SMoriah Waterland 	char	tempmode[ATRSIZ+1];
977*5c51f124SMoriah Waterland 	mode_t	tempmode_t;
978*5c51f124SMoriah Waterland 	int	retval;
979*5c51f124SMoriah Waterland 	int	n;
980*5c51f124SMoriah Waterland 
981*5c51f124SMoriah Waterland 	if ((retval = getstrvfp(cp, NULL, sizeof (tempmode), tempmode)) == 1) {
982*5c51f124SMoriah Waterland 		return (1);
983*5c51f124SMoriah Waterland 	} else if (retval == -1) {
984*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_MODELONG));
985*5c51f124SMoriah Waterland 		return (2);
986*5c51f124SMoriah Waterland 	}
987*5c51f124SMoriah Waterland 
988*5c51f124SMoriah Waterland 	/*
989*5c51f124SMoriah Waterland 	 * If it isn't a '?' (meaning go with whatever mode is
990*5c51f124SMoriah Waterland 	 * there), validate the mode and convert it to a mode_t. The
991*5c51f124SMoriah Waterland 	 * "bad" variable here is a misnomer. It doesn't necessarily
992*5c51f124SMoriah Waterland 	 * mean bad.
993*5c51f124SMoriah Waterland 	 */
994*5c51f124SMoriah Waterland 	if (tempmode[0] == '?') {
995*5c51f124SMoriah Waterland 		*d = WILDCARD;
996*5c51f124SMoriah Waterland 		return (0);
997*5c51f124SMoriah Waterland 	}
998*5c51f124SMoriah Waterland 
999*5c51f124SMoriah Waterland 	/*
1000*5c51f124SMoriah Waterland 	 * Mode may not be an install parameter or a
1001*5c51f124SMoriah Waterland 	 * non-build parameter.
1002*5c51f124SMoriah Waterland 	 */
1003*5c51f124SMoriah Waterland 
1004*5c51f124SMoriah Waterland 	if (tempmode[0] == '$' &&
1005*5c51f124SMoriah Waterland 	    (isupper(tempmode[1]) || !islower(tempmode[1]))) {
1006*5c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_IMODE));
1007*5c51f124SMoriah Waterland 		return (2);
1008*5c51f124SMoriah Waterland 	}
1009*5c51f124SMoriah Waterland 
1010*5c51f124SMoriah Waterland 	if ((map) && (mapvar(mapmode, tempmode))) {
1011*5c51f124SMoriah Waterland 		(void) snprintf(getErrbufAddr(), getErrbufSize(),
1012*5c51f124SMoriah Waterland 				pkg_gt(ERR_NOVAR), maptype, tempmode);
1013*5c51f124SMoriah Waterland 		setErrstr(getErrbufAddr());
1014*5c51f124SMoriah Waterland 		return (2);
1015*5c51f124SMoriah Waterland 	}
1016*5c51f124SMoriah Waterland 
1017*5c51f124SMoriah Waterland 	if (tempmode[0] == '$') {
1018*5c51f124SMoriah Waterland 		*d = BADMODE;	/* may be a problem */
1019*5c51f124SMoriah Waterland 		return (0);
1020*5c51f124SMoriah Waterland 	}
1021*5c51f124SMoriah Waterland 
1022*5c51f124SMoriah Waterland 	/* it's supposed to be something we can convert to a number */
1023*5c51f124SMoriah Waterland 
1024*5c51f124SMoriah Waterland 	n = 0;
1025*5c51f124SMoriah Waterland 
1026*5c51f124SMoriah Waterland 	/* reject it if it contains nonnumbers or it's not octal */
1027*5c51f124SMoriah Waterland 
1028*5c51f124SMoriah Waterland 	while (tempmode[n] && !isspace(tempmode[n])) {
1029*5c51f124SMoriah Waterland 		if (!isdigit(tempmode[n])) {
1030*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_MODEALPHA));
1031*5c51f124SMoriah Waterland 			return (2);
1032*5c51f124SMoriah Waterland 		}
1033*5c51f124SMoriah Waterland 
1034*5c51f124SMoriah Waterland 		if (strchr("89abcdefABCDEF", tempmode[n])) {
1035*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BASEINVAL));
1036*5c51f124SMoriah Waterland 			return (2);
1037*5c51f124SMoriah Waterland 		}
1038*5c51f124SMoriah Waterland 		n++;
1039*5c51f124SMoriah Waterland 	}
1040*5c51f124SMoriah Waterland 
1041*5c51f124SMoriah Waterland 	tempmode_t = strtol(tempmode, NULL, 8);
1042*5c51f124SMoriah Waterland 
1043*5c51f124SMoriah Waterland 	/*
1044*5c51f124SMoriah Waterland 	 * We reject it if it contains inappropriate
1045*5c51f124SMoriah Waterland 	 * bits.
1046*5c51f124SMoriah Waterland 	 */
1047*5c51f124SMoriah Waterland 	if (tempmode_t & (~(S_IAMB | S_ISUID | S_ISGID | S_ISVTX))) {
1048*5c51f124SMoriah Waterland 		if (mapmode == MAPBUILD) {
1049*5c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_MODEBITS));
1050*5c51f124SMoriah Waterland 			return (2);
1051*5c51f124SMoriah Waterland 		}
1052*5c51f124SMoriah Waterland 		tempmode_t = bad;
1053*5c51f124SMoriah Waterland 	}
1054*5c51f124SMoriah Waterland 
1055*5c51f124SMoriah Waterland 	*d = tempmode_t;
1056*5c51f124SMoriah Waterland 
1057*5c51f124SMoriah Waterland 	return (0);
1058*5c51f124SMoriah Waterland }
1059*5c51f124SMoriah Waterland 
1060*5c51f124SMoriah Waterland int
1061*5c51f124SMoriah Waterland getnumvfp(char **cp, int base, long *d, long bad)
1062*5c51f124SMoriah Waterland {
1063*5c51f124SMoriah Waterland 	int c;
1064*5c51f124SMoriah Waterland 	char	*p = *cp;
1065*5c51f124SMoriah Waterland 
1066*5c51f124SMoriah Waterland 	if (*p == '\0') {
1067*5c51f124SMoriah Waterland 		return (0);
1068*5c51f124SMoriah Waterland 	}
1069*5c51f124SMoriah Waterland 
1070*5c51f124SMoriah Waterland 	/* leading white space ignored */
1071*5c51f124SMoriah Waterland 	while (((c = *p) != '\0') && (isspace(*p++)))
1072*5c51f124SMoriah Waterland 		;
1073*5c51f124SMoriah Waterland 	if (c == '?') {
1074*5c51f124SMoriah Waterland 		*d = bad;
1075*5c51f124SMoriah Waterland 		*cp = p;
1076*5c51f124SMoriah Waterland 		return (0);
1077*5c51f124SMoriah Waterland 	}
1078*5c51f124SMoriah Waterland 
1079*5c51f124SMoriah Waterland 	if ((c == '\0') || (c == '\n') || !isdigit(c)) {
1080*5c51f124SMoriah Waterland 		p--;
1081*5c51f124SMoriah Waterland 		*cp = p;
1082*5c51f124SMoriah Waterland 		return (1);
1083*5c51f124SMoriah Waterland 	}
1084*5c51f124SMoriah Waterland 
1085*5c51f124SMoriah Waterland 	*d = 0;
1086*5c51f124SMoriah Waterland 	while (isdigit(c)) {
1087*5c51f124SMoriah Waterland 		*d = (*d * base) + (c & 017);
1088*5c51f124SMoriah Waterland 		c = *p++;
1089*5c51f124SMoriah Waterland 	}
1090*5c51f124SMoriah Waterland 	p--;
1091*5c51f124SMoriah Waterland 	*cp = p;
1092*5c51f124SMoriah Waterland 	return (0);
1093*5c51f124SMoriah Waterland }
1094*5c51f124SMoriah Waterland 
1095*5c51f124SMoriah Waterland int
1096*5c51f124SMoriah Waterland getlnumvfp(char **cp, int base, fsblkcnt_t *d, long bad)
1097*5c51f124SMoriah Waterland {
1098*5c51f124SMoriah Waterland 	int c;
1099*5c51f124SMoriah Waterland 	char	*p = *cp;
1100*5c51f124SMoriah Waterland 
1101*5c51f124SMoriah Waterland 	if (*p == '\0') {
1102*5c51f124SMoriah Waterland 		return (0);
1103*5c51f124SMoriah Waterland 	}
1104*5c51f124SMoriah Waterland 
1105*5c51f124SMoriah Waterland 	/* leading white space ignored */
1106*5c51f124SMoriah Waterland 	while (((c = *p) != '\0') && (isspace(*p++)))
1107*5c51f124SMoriah Waterland 		;
1108*5c51f124SMoriah Waterland 	if (c == '?') {
1109*5c51f124SMoriah Waterland 		*d = bad;
1110*5c51f124SMoriah Waterland 		*cp = p;
1111*5c51f124SMoriah Waterland 		return (0);
1112*5c51f124SMoriah Waterland 	}
1113*5c51f124SMoriah Waterland 
1114*5c51f124SMoriah Waterland 	if ((c == '\0') || (c == '\n') || !isdigit(c)) {
1115*5c51f124SMoriah Waterland 		p--;
1116*5c51f124SMoriah Waterland 		*cp = p;
1117*5c51f124SMoriah Waterland 		return (1);
1118*5c51f124SMoriah Waterland 	}
1119*5c51f124SMoriah Waterland 
1120*5c51f124SMoriah Waterland 	*d = 0;
1121*5c51f124SMoriah Waterland 	while (isdigit(c)) {
1122*5c51f124SMoriah Waterland 		*d = (*d * base) + (c & 017);
1123*5c51f124SMoriah Waterland 		c = *p++;
1124*5c51f124SMoriah Waterland 	}
1125*5c51f124SMoriah Waterland 	p--;
1126*5c51f124SMoriah Waterland 	*cp = p;
1127*5c51f124SMoriah Waterland 	return (0);
1128*5c51f124SMoriah Waterland }
1129*5c51f124SMoriah Waterland 
1130*5c51f124SMoriah Waterland static int
1131*5c51f124SMoriah Waterland getstrvfp(char **cp, char *sep, int n, char *str)
1132*5c51f124SMoriah Waterland {
1133*5c51f124SMoriah Waterland 	char	delims[256];
1134*5c51f124SMoriah Waterland 	int	c;
1135*5c51f124SMoriah Waterland 	char	*p = *cp;
1136*5c51f124SMoriah Waterland 	char	*p1;
1137*5c51f124SMoriah Waterland 	size_t	len;
1138*5c51f124SMoriah Waterland 
1139*5c51f124SMoriah Waterland 	if (*p == '\0') {
1140*5c51f124SMoriah Waterland 		return (1);
1141*5c51f124SMoriah Waterland 	}
1142*5c51f124SMoriah Waterland 
1143*5c51f124SMoriah Waterland 	/* leading white space ignored */
1144*5c51f124SMoriah Waterland 
1145*5c51f124SMoriah Waterland 	while (((c = *p) != '\0') && (isspace(*p++)))
1146*5c51f124SMoriah Waterland 		;
1147*5c51f124SMoriah Waterland 	if ((c == '\0') || (c == '\n')) {
1148*5c51f124SMoriah Waterland 		p--;
1149*5c51f124SMoriah Waterland 		*cp = p;
1150*5c51f124SMoriah Waterland 		return (1); /* nothing there */
1151*5c51f124SMoriah Waterland 	}
1152*5c51f124SMoriah Waterland 
1153*5c51f124SMoriah Waterland 	p--;
1154*5c51f124SMoriah Waterland 
1155*5c51f124SMoriah Waterland 	/* generate complete list of delimiters to scan for */
1156*5c51f124SMoriah Waterland 
1157*5c51f124SMoriah Waterland 	(void) strlcpy(delims, " \t\n", sizeof (delims));
1158*5c51f124SMoriah Waterland 	if ((sep != (char *)NULL) && (*sep != '\0')) {
1159*5c51f124SMoriah Waterland 		(void) strlcat(delims, sep, sizeof (delims));
1160*5c51f124SMoriah Waterland 	}
1161*5c51f124SMoriah Waterland 
1162*5c51f124SMoriah Waterland 	/* compute length based on delimiter found or not */
1163*5c51f124SMoriah Waterland 
1164*5c51f124SMoriah Waterland 	p1 = strpbrk(p, delims);
1165*5c51f124SMoriah Waterland 	if (p1 == (char *)NULL) {
1166*5c51f124SMoriah Waterland 		len = strlen(p);
1167*5c51f124SMoriah Waterland 	} else {
1168*5c51f124SMoriah Waterland 		len = (ptrdiff_t)p1 - (ptrdiff_t)p;
1169*5c51f124SMoriah Waterland 	}
1170*5c51f124SMoriah Waterland 
1171*5c51f124SMoriah Waterland 	/* if string will fit in result buffer copy string and return success */
1172*5c51f124SMoriah Waterland 
1173*5c51f124SMoriah Waterland 	if (len < n) {
1174*5c51f124SMoriah Waterland 		(void) memcpy(str, p, len);
1175*5c51f124SMoriah Waterland 		str[len] = '\0';
1176*5c51f124SMoriah Waterland 		p += len;
1177*5c51f124SMoriah Waterland 		*cp = p;
1178*5c51f124SMoriah Waterland 		return (0);
1179*5c51f124SMoriah Waterland 	}
1180*5c51f124SMoriah Waterland 
1181*5c51f124SMoriah Waterland 	/* result buffer too small; copy partial string, return error */
1182*5c51f124SMoriah Waterland 	(void) memcpy(str, p, n-1);
1183*5c51f124SMoriah Waterland 	str[n-1] = '\0';
1184*5c51f124SMoriah Waterland 	p += n;
1185*5c51f124SMoriah Waterland 	*cp = p;
1186*5c51f124SMoriah Waterland 	return (-1);
1187*5c51f124SMoriah Waterland }
1188*5c51f124SMoriah Waterland 
1189*5c51f124SMoriah Waterland /*
1190*5c51f124SMoriah Waterland  * Name:	getendvfp
1191*5c51f124SMoriah Waterland  * Description:	Locate the end of the current line given a pointer into a buffer
1192*5c51f124SMoriah Waterland  *		containing characters that is null terminated.
1193*5c51f124SMoriah Waterland  * Arguments:	char **cp - pointer to pointer to null-terminated string buffer
1194*5c51f124SMoriah Waterland  * Returns:	int == 0 -- no non-space characters preceeded the newline
1195*5c51f124SMoriah Waterland  *		    != 0 -- one or more non-space characters preceeded newline
1196*5c51f124SMoriah Waterland  * Effects:	cp is updated to point to the first character PAST the first new
1197*5c51f124SMoriah Waterland  *		line character found. If no newline character is found, cp is
1198*5c51f124SMoriah Waterland  *		updated to point to the '\0' at the end of the buffer.
1199*5c51f124SMoriah Waterland  */
1200*5c51f124SMoriah Waterland 
1201*5c51f124SMoriah Waterland static int
1202*5c51f124SMoriah Waterland getendvfp(char **cp)
1203*5c51f124SMoriah Waterland {
1204*5c51f124SMoriah Waterland 	int	n;
1205*5c51f124SMoriah Waterland 	char	*p = *cp;
1206*5c51f124SMoriah Waterland 
1207*5c51f124SMoriah Waterland 	n = 0;
1208*5c51f124SMoriah Waterland 
1209*5c51f124SMoriah Waterland 	/* if at end of buffer return no more characters left */
1210*5c51f124SMoriah Waterland 
1211*5c51f124SMoriah Waterland 	if (*p == '\0') {
1212*5c51f124SMoriah Waterland 		return (0);
1213*5c51f124SMoriah Waterland 	}
1214*5c51f124SMoriah Waterland 
1215*5c51f124SMoriah Waterland 	/* find the first null or end of line character */
1216*5c51f124SMoriah Waterland 
1217*5c51f124SMoriah Waterland 	while ((*p != '\0') && (*p != '\n')) {
1218*5c51f124SMoriah Waterland 		if (n == 0) {
1219*5c51f124SMoriah Waterland 			if (!isspace(*p)) {
1220*5c51f124SMoriah Waterland 				n++;
1221*5c51f124SMoriah Waterland 			}
1222*5c51f124SMoriah Waterland 		}
1223*5c51f124SMoriah Waterland 		p++;
1224*5c51f124SMoriah Waterland 	}
1225*5c51f124SMoriah Waterland 
1226*5c51f124SMoriah Waterland 	/* if at newline, increment pointer to first character past newline */
1227*5c51f124SMoriah Waterland 
1228*5c51f124SMoriah Waterland 	if (*p == '\n') {
1229*5c51f124SMoriah Waterland 		p++;
1230*5c51f124SMoriah Waterland 	}
1231*5c51f124SMoriah Waterland 
1232*5c51f124SMoriah Waterland 	/* set return pointer to null or first character past newline */
1233*5c51f124SMoriah Waterland 
1234*5c51f124SMoriah Waterland 	*cp = p;
1235*5c51f124SMoriah Waterland 
1236*5c51f124SMoriah Waterland 	/* return space/nospace indicator */
1237*5c51f124SMoriah Waterland 
1238*5c51f124SMoriah Waterland 	return (n);
1239*5c51f124SMoriah Waterland }
1240*5c51f124SMoriah Waterland 
1241*5c51f124SMoriah Waterland /*
1242*5c51f124SMoriah Waterland  * Name:	findendvfp
1243*5c51f124SMoriah Waterland  * Description:	Locate the end of the current line given a pointer into a buffer
1244*5c51f124SMoriah Waterland  *		containing characters that is null terminated.
1245*5c51f124SMoriah Waterland  * Arguments:	char **cp - pointer to pointer to null-terminated string buffer
1246*5c51f124SMoriah Waterland  * Returns:	none
1247*5c51f124SMoriah Waterland  * Effects:	cp is updated to point to the first character PAST the first new
1248*5c51f124SMoriah Waterland  *		line character found. If no newline character is found, cp is
1249*5c51f124SMoriah Waterland  *		updated to point to the '\0' at the end of the buffer.
1250*5c51f124SMoriah Waterland  */
1251*5c51f124SMoriah Waterland 
1252*5c51f124SMoriah Waterland static void
1253*5c51f124SMoriah Waterland findendvfp(char **cp)
1254*5c51f124SMoriah Waterland {
1255*5c51f124SMoriah Waterland 	char	*p1;
1256*5c51f124SMoriah Waterland 	char	*p = *cp;
1257*5c51f124SMoriah Waterland 
1258*5c51f124SMoriah Waterland 	/* if at end of buffer return no more characters left */
1259*5c51f124SMoriah Waterland 
1260*5c51f124SMoriah Waterland 	if (*p == '\0') {
1261*5c51f124SMoriah Waterland 		return;
1262*5c51f124SMoriah Waterland 	}
1263*5c51f124SMoriah Waterland 
1264*5c51f124SMoriah Waterland 	/* find the end of the line */
1265*5c51f124SMoriah Waterland 
1266*5c51f124SMoriah Waterland 	p1 = strchr(p, '\n');
1267*5c51f124SMoriah Waterland 	if (p1 != (char *)NULL) {
1268*5c51f124SMoriah Waterland 		*cp = ++p1;
1269*5c51f124SMoriah Waterland 		return;
1270*5c51f124SMoriah Waterland 	}
1271*5c51f124SMoriah Waterland 
1272*5c51f124SMoriah Waterland 	/* no newline found - point to null terminator */
1273*5c51f124SMoriah Waterland 
1274*5c51f124SMoriah Waterland 	*cp = strchr(p, '\0');
1275*5c51f124SMoriah Waterland }
1276