xref: /illumos-gate/usr/src/lib/libpkg/common/gpkgmap.c (revision 4f35a7b5)
15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland  * CDDL HEADER START
35c51f124SMoriah Waterland  *
45c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland  *
85c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland  * See the License for the specific language governing permissions
115c51f124SMoriah Waterland  * and limitations under the License.
125c51f124SMoriah Waterland  *
135c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland  *
195c51f124SMoriah Waterland  * CDDL HEADER END
205c51f124SMoriah Waterland  */
215c51f124SMoriah Waterland 
2232991bedSPeter Tribble /*
2332991bedSPeter Tribble  * Copyright (c) 2017 Peter Tribble.
2432991bedSPeter Tribble  */
2532991bedSPeter Tribble 
265c51f124SMoriah Waterland /*
275c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
285c51f124SMoriah Waterland  * Use is subject to license terms.
295c51f124SMoriah Waterland  */
305c51f124SMoriah Waterland 
315c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
325c51f124SMoriah Waterland /* All Rights Reserved */
335c51f124SMoriah Waterland 
345c51f124SMoriah Waterland 
355c51f124SMoriah Waterland 
365c51f124SMoriah Waterland #include <stdio.h>
375c51f124SMoriah Waterland #include <limits.h>
385c51f124SMoriah Waterland #include <stdlib.h>
395c51f124SMoriah Waterland #include <unistd.h>
405c51f124SMoriah Waterland #include <string.h>
415c51f124SMoriah Waterland #include <ctype.h>
425c51f124SMoriah Waterland #include <fcntl.h>
435c51f124SMoriah Waterland #include <sys/types.h>
445c51f124SMoriah Waterland #include <sys/stat.h>
455c51f124SMoriah Waterland #include <errno.h>
465c51f124SMoriah Waterland #include "pkgstrct.h"
475c51f124SMoriah Waterland #include "pkglib.h"
485c51f124SMoriah Waterland #include "pkglibmsgs.h"
495c51f124SMoriah Waterland #include "pkglocale.h"
505c51f124SMoriah Waterland 
515c51f124SMoriah Waterland #define	ERR_CANT_READ_LCLPATH		"unable to read local pathname"
525c51f124SMoriah Waterland #define	ERR_BAD_VOLUME_NUMBER		"bad volume number"
535c51f124SMoriah Waterland #define	ERR_CANNOT_READ_PATHNAME_FIELD	"unable to read pathname field"
545c51f124SMoriah Waterland #define	ERR_CANNOT_READ_CONTENT_INFO	"unable to read content info"
555c51f124SMoriah Waterland #define	ERR_EXTRA_TOKENS_PRESENT	"extra tokens on input line"
565c51f124SMoriah Waterland #define	ERR_CANNOT_READ_CLASS_TOKEN	"unable to read class token"
575c51f124SMoriah Waterland #define	ERR_BAD_LINK_SPEC		"missing or invalid link specification"
585c51f124SMoriah Waterland #define	ERR_UNKNOWN_FTYPE		"unknown ftype"
595c51f124SMoriah Waterland #define	ERR_NO_LINKSOURCE		"no link source specified"
605c51f124SMoriah Waterland #define	ERR_CANNOT_READ_MM_DEVNUMS	"unable to read major/minor "\
615c51f124SMoriah Waterland 					"device numbers"
625c51f124SMoriah Waterland static int	eatwhite(FILE *fp);
635c51f124SMoriah Waterland static int	getend(FILE *fp);
645c51f124SMoriah Waterland static int	getstr(FILE *fp, char *sep, int n, char *str);
655c51f124SMoriah Waterland static int	getnum(FILE *fp, int base, long *d, long bad);
665c51f124SMoriah Waterland static int	getlnum(FILE *fp, int base, fsblkcnt_t *d, long bad);
675c51f124SMoriah Waterland static int	getvalmode(FILE *fp, mode_t *d, long bad, int map);
685c51f124SMoriah Waterland 
695c51f124SMoriah Waterland static int	getendvfp(char **cp);
705c51f124SMoriah Waterland static void	findendvfp(char **cp);
715c51f124SMoriah Waterland static int	getstrvfp(char **cp, char *sep, int n, char *str);
725c51f124SMoriah Waterland static int	getvalmodevfp(char **cp, mode_t *d, long bad, int map);
735c51f124SMoriah Waterland int		getnumvfp(char **cp, int base, long *d, long bad);
745c51f124SMoriah Waterland int		getlnumvfp(char **cp, int base, fsblkcnt_t *d, long bad);
755c51f124SMoriah Waterland 
765c51f124SMoriah Waterland static char	mypath[PATH_MAX];
775c51f124SMoriah Waterland static char	mylocal[PATH_MAX];
785c51f124SMoriah Waterland static int	mapmode = MAPNONE;
795c51f124SMoriah Waterland static char	*maptype = "";
805c51f124SMoriah Waterland static mode_t	d_mode = BADMODE;
81*4f35a7b5SToomas Soome static char	*d_owner = BADOWNER;
825c51f124SMoriah Waterland static char	*d_group = BADGROUP;
835c51f124SMoriah Waterland 
845c51f124SMoriah Waterland /*
855c51f124SMoriah Waterland  * These determine how gpkgmap() deals with mode, owner and group defaults.
865c51f124SMoriah Waterland  * It is assumed that the owner and group arguments represent static fields
875c51f124SMoriah Waterland  * which will persist until attrdefault() is called.
885c51f124SMoriah Waterland  */
895c51f124SMoriah Waterland void
attrpreset(int mode,char * owner,char * group)905c51f124SMoriah Waterland attrpreset(int mode, char *owner, char *group)
915c51f124SMoriah Waterland {
925c51f124SMoriah Waterland 	d_mode = mode;
935c51f124SMoriah Waterland 	d_owner = owner;
945c51f124SMoriah Waterland 	d_group = group;
955c51f124SMoriah Waterland }
965c51f124SMoriah Waterland 
975c51f124SMoriah Waterland void
attrdefault()985c51f124SMoriah Waterland attrdefault()
995c51f124SMoriah Waterland {
1005c51f124SMoriah Waterland 	d_mode = NOMODE;
1015c51f124SMoriah Waterland 	d_owner = NOOWNER;
1025c51f124SMoriah Waterland 	d_group = NOGROUP;
1035c51f124SMoriah Waterland }
1045c51f124SMoriah Waterland 
1055c51f124SMoriah Waterland /*
1065c51f124SMoriah Waterland  * This determines how gpkgmap() deals with environment variables in the
1075c51f124SMoriah Waterland  * mode, owner and group. Path is evaluated at a higher level based upon
1085c51f124SMoriah Waterland  * other circumstances.
1095c51f124SMoriah Waterland  */
1105c51f124SMoriah Waterland void
setmapmode(int mode)1115c51f124SMoriah Waterland setmapmode(int mode)
1125c51f124SMoriah Waterland {
1135c51f124SMoriah Waterland 	if (mode >= 0 || mode <= 3) {
1145c51f124SMoriah Waterland 		mapmode = mode;
1155c51f124SMoriah Waterland 		if (mode == MAPBUILD)
1165c51f124SMoriah Waterland 			maptype = " build";
1175c51f124SMoriah Waterland 		else if (mode == MAPINSTALL)
1185c51f124SMoriah Waterland 			maptype = " install";
1195c51f124SMoriah Waterland 		else
1205c51f124SMoriah Waterland 			maptype = "";
1215c51f124SMoriah Waterland 	}
1225c51f124SMoriah Waterland }
1235c51f124SMoriah Waterland 
1245c51f124SMoriah Waterland /* This is the external query interface for mapmode. */
1255c51f124SMoriah Waterland int
getmapmode(void)1265c51f124SMoriah Waterland getmapmode(void)
1275c51f124SMoriah Waterland {
1285c51f124SMoriah Waterland 	return (mapmode);
1295c51f124SMoriah Waterland }
1305c51f124SMoriah Waterland 
1315c51f124SMoriah Waterland /*
1325c51f124SMoriah Waterland  * Unpack the pkgmap or the contents file or whatever file is in that format.
1335c51f124SMoriah Waterland  * Based upon mapmode, environment parameters will be resolved for mode,
1345c51f124SMoriah Waterland  * owner and group.
1355c51f124SMoriah Waterland  */
1365c51f124SMoriah Waterland 
1375c51f124SMoriah Waterland int
gpkgmap(struct cfent * ept,FILE * fp)1385c51f124SMoriah Waterland gpkgmap(struct cfent *ept, FILE *fp)
1395c51f124SMoriah Waterland {
1405c51f124SMoriah Waterland 	int		c;
1415c51f124SMoriah Waterland 	boolean_t	first_char = B_TRUE;
1425c51f124SMoriah Waterland 
1435c51f124SMoriah Waterland 	setErrstr(NULL);
1445c51f124SMoriah Waterland 	ept->volno = 0;
1455c51f124SMoriah Waterland 	ept->ftype = BADFTYPE;
1465c51f124SMoriah Waterland 	(void) strcpy(ept->pkg_class, BADCLASS);
1475c51f124SMoriah Waterland 	ept->pkg_class_idx = -1;
1485c51f124SMoriah Waterland 	ept->path = NULL;
1495c51f124SMoriah Waterland 	ept->ainfo.local = NULL;
1505c51f124SMoriah Waterland 	/* default attributes were supplied, so don't reset */
1515c51f124SMoriah Waterland 	ept->ainfo.mode = d_mode;
1525c51f124SMoriah Waterland 	(void) strcpy(ept->ainfo.owner, d_owner);
1535c51f124SMoriah Waterland 	(void) strcpy(ept->ainfo.group, d_group);
1545c51f124SMoriah Waterland 	ept->ainfo.major = BADMAJOR;
1555c51f124SMoriah Waterland 	ept->ainfo.minor = BADMINOR;
156*4f35a7b5SToomas Soome 	ept->cinfo.cksum = -1L;
157*4f35a7b5SToomas Soome 	ept->cinfo.modtime = -1L;
158*4f35a7b5SToomas Soome 	ept->cinfo.size = -1L;
1595c51f124SMoriah Waterland 
1605c51f124SMoriah Waterland 	ept->npkgs = 0;
1615c51f124SMoriah Waterland 
1625c51f124SMoriah Waterland 	if (!fp)
1635c51f124SMoriah Waterland 		return (-1);
1645c51f124SMoriah Waterland readline:
1655c51f124SMoriah Waterland 	c = eatwhite(fp);
1665c51f124SMoriah Waterland 
1675c51f124SMoriah Waterland 	/*
1685c51f124SMoriah Waterland 	 * If the first character is not a digit, we assume that the
1695c51f124SMoriah Waterland 	 * volume number is 1.
1705c51f124SMoriah Waterland 	 */
1715c51f124SMoriah Waterland 	if (first_char && !isdigit(c)) {
1725c51f124SMoriah Waterland 		ept->volno = 1;
1735c51f124SMoriah Waterland 	}
1745c51f124SMoriah Waterland 	first_char = B_FALSE;
1755c51f124SMoriah Waterland 
1765c51f124SMoriah Waterland 	switch (c) {
177*4f35a7b5SToomas Soome 	case EOF:
1785c51f124SMoriah Waterland 		return (0);
1795c51f124SMoriah Waterland 
180*4f35a7b5SToomas Soome 	case '0':
181*4f35a7b5SToomas Soome 	case '1':
182*4f35a7b5SToomas Soome 	case '2':
183*4f35a7b5SToomas Soome 	case '3':
184*4f35a7b5SToomas Soome 	case '4':
185*4f35a7b5SToomas Soome 	case '5':
186*4f35a7b5SToomas Soome 	case '6':
187*4f35a7b5SToomas Soome 	case '7':
188*4f35a7b5SToomas Soome 	case '8':
189*4f35a7b5SToomas Soome 	case '9':
1905c51f124SMoriah Waterland 		if (ept->volno) {
1915c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BAD_VOLUME_NUMBER));
1925c51f124SMoriah Waterland 			goto error;
1935c51f124SMoriah Waterland 		}
1945c51f124SMoriah Waterland 		do {
1955c51f124SMoriah Waterland 			ept->volno = (ept->volno*10)+c-'0';
1965c51f124SMoriah Waterland 			c = getc(fp);
1975c51f124SMoriah Waterland 		} while (isdigit(c));
1985c51f124SMoriah Waterland 		if (ept->volno == 0)
1995c51f124SMoriah Waterland 			ept->volno = 1;
2005c51f124SMoriah Waterland 
2015c51f124SMoriah Waterland 		goto readline;
2025c51f124SMoriah Waterland 
203*4f35a7b5SToomas Soome 	case ':':
204*4f35a7b5SToomas Soome 	case '#':
2055c51f124SMoriah Waterland 		(void) getend(fp);
2065c51f124SMoriah Waterland 		/*FALLTHRU*/
207*4f35a7b5SToomas Soome 	case '\n':
2085c51f124SMoriah Waterland 		/*
2095c51f124SMoriah Waterland 		 * Since we are going to scan the next line,
2105c51f124SMoriah Waterland 		 * we need to reset volume number and first_char.
2115c51f124SMoriah Waterland 		 */
2125c51f124SMoriah Waterland 		ept->volno = 0;
2135c51f124SMoriah Waterland 		first_char = B_TRUE;
2145c51f124SMoriah Waterland 		goto readline;
2155c51f124SMoriah Waterland 
216*4f35a7b5SToomas Soome 	case 'i':
2175c51f124SMoriah Waterland 		ept->ftype = (char)c;
2185c51f124SMoriah Waterland 		c = eatwhite(fp);
2195c51f124SMoriah Waterland 		/*FALLTHRU*/
220*4f35a7b5SToomas Soome 	case '.':
221*4f35a7b5SToomas Soome 	case '/':
2225c51f124SMoriah Waterland 		(void) ungetc(c, fp);
2235c51f124SMoriah Waterland 
2245c51f124SMoriah Waterland 		if (getstr(fp, "=", PATH_MAX, mypath)) {
2255c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
2265c51f124SMoriah Waterland 			goto error;
2275c51f124SMoriah Waterland 		}
2285c51f124SMoriah Waterland 		ept->path = mypath;
2295c51f124SMoriah Waterland 		c = getc(fp);
2305c51f124SMoriah Waterland 		if (c == '=') {
2315c51f124SMoriah Waterland 			if (getstr(fp, NULL, PATH_MAX, mylocal)) {
2325c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_CANT_READ_LCLPATH));
2335c51f124SMoriah Waterland 				goto error;
2345c51f124SMoriah Waterland 			}
2355c51f124SMoriah Waterland 			ept->ainfo.local = mylocal;
2365c51f124SMoriah Waterland 		} else
2375c51f124SMoriah Waterland 			(void) ungetc(c, fp);
2385c51f124SMoriah Waterland 
2395c51f124SMoriah Waterland 		if (ept->ftype == 'i') {
2405c51f124SMoriah Waterland 			/* content info might exist */
2415c51f124SMoriah Waterland 			if (!getlnum(fp, 10, (fsblkcnt_t *)&ept->cinfo.size,
2425c51f124SMoriah Waterland 			    BADCONT) &&
2435c51f124SMoriah Waterland 			    (getnum(fp, 10, (long *)&ept->cinfo.cksum,
2445c51f124SMoriah Waterland 			    BADCONT) ||
2455c51f124SMoriah Waterland 			    getnum(fp, 10, (long *)&ept->cinfo.modtime,
2465c51f124SMoriah Waterland 			    BADCONT))) {
2475c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
2485c51f124SMoriah Waterland 				goto error;
2495c51f124SMoriah Waterland 			}
2505c51f124SMoriah Waterland 		}
2515c51f124SMoriah Waterland 		if (getend(fp)) {
2525c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
2535c51f124SMoriah Waterland 			return (-1);
2545c51f124SMoriah Waterland 		}
2555c51f124SMoriah Waterland 		return (1);
2565c51f124SMoriah Waterland 
257*4f35a7b5SToomas Soome 	case '?':
258*4f35a7b5SToomas Soome 	case 'f':
259*4f35a7b5SToomas Soome 	case 'v':
260*4f35a7b5SToomas Soome 	case 'e':
261*4f35a7b5SToomas Soome 	case 'l':
262*4f35a7b5SToomas Soome 	case 's':
263*4f35a7b5SToomas Soome 	case 'p':
264*4f35a7b5SToomas Soome 	case 'c':
265*4f35a7b5SToomas Soome 	case 'b':
266*4f35a7b5SToomas Soome 	case 'd':
267*4f35a7b5SToomas Soome 	case 'x':
2685c51f124SMoriah Waterland 		ept->ftype = (char)c;
2695c51f124SMoriah Waterland 		if (getstr(fp, NULL, CLSSIZ, ept->pkg_class)) {
2705c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_CLASS_TOKEN));
2715c51f124SMoriah Waterland 			goto error;
2725c51f124SMoriah Waterland 		}
2735c51f124SMoriah Waterland 		if (getstr(fp, "=", PATH_MAX, mypath)) {
2745c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
2755c51f124SMoriah Waterland 			goto error;
2765c51f124SMoriah Waterland 		}
2775c51f124SMoriah Waterland 		ept->path = mypath;
2785c51f124SMoriah Waterland 
2795c51f124SMoriah Waterland 		c = getc(fp);
2805c51f124SMoriah Waterland 		if (c == '=') {
2815c51f124SMoriah Waterland 			/* local path */
2825c51f124SMoriah Waterland 			if (getstr(fp, NULL, PATH_MAX, mylocal)) {
2835c51f124SMoriah Waterland 				if (ept->ftype == 's' || ept->ftype == 'l') {
2845c51f124SMoriah Waterland 					setErrstr(pkg_gt(ERR_READLINK));
2855c51f124SMoriah Waterland 				} else {
2865c51f124SMoriah Waterland 					setErrstr(
287*4f35a7b5SToomas Soome 					    pkg_gt(ERR_CANT_READ_LCLPATH));
2885c51f124SMoriah Waterland 				}
2895c51f124SMoriah Waterland 				goto error;
2905c51f124SMoriah Waterland 			}
2915c51f124SMoriah Waterland 			ept->ainfo.local = mylocal;
2925c51f124SMoriah Waterland 		} else if (strchr("sl", ept->ftype)) {
2935c51f124SMoriah Waterland 			if ((c != EOF) && (c != '\n'))
2945c51f124SMoriah Waterland 				(void) getend(fp);
2955c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BAD_LINK_SPEC));
2965c51f124SMoriah Waterland 			return (-1);
2975c51f124SMoriah Waterland 		} else
2985c51f124SMoriah Waterland 			(void) ungetc(c, fp);
2995c51f124SMoriah Waterland 		break;
3005c51f124SMoriah Waterland 
301*4f35a7b5SToomas Soome 	default:
3025c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_UNKNOWN_FTYPE));
3035c51f124SMoriah Waterland error:
3045c51f124SMoriah Waterland 		(void) getend(fp);
3055c51f124SMoriah Waterland 		return (-1);
3065c51f124SMoriah Waterland 	}
3075c51f124SMoriah Waterland 
3085c51f124SMoriah Waterland 	if (strchr("sl", ept->ftype) && (ept->ainfo.local == NULL)) {
3095c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_NO_LINKSOURCE));
3105c51f124SMoriah Waterland 		goto error;
3115c51f124SMoriah Waterland 	}
3125c51f124SMoriah Waterland 
3135c51f124SMoriah Waterland 	if (strchr("cb", ept->ftype)) {
3145c51f124SMoriah Waterland 		ept->ainfo.major = BADMAJOR;
3155c51f124SMoriah Waterland 		ept->ainfo.minor = BADMINOR;
3165c51f124SMoriah Waterland 		if (getnum(fp, 10, (long *)&ept->ainfo.major, BADMAJOR) ||
3174656d474SGarrett D'Amore 		    getnum(fp, 10, (long *)&ept->ainfo.minor, BADMINOR)) {
3185c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_MM_DEVNUMS));
3195c51f124SMoriah Waterland 			goto error;
3205c51f124SMoriah Waterland 		}
3215c51f124SMoriah Waterland 	}
3225c51f124SMoriah Waterland 
3235c51f124SMoriah Waterland 	/*
3245c51f124SMoriah Waterland 	 * Links and information files don't have attributes associated with
3255c51f124SMoriah Waterland 	 * them. The following either resolves potential variables or passes
3265c51f124SMoriah Waterland 	 * them through. Mode is tested for validity to some degree. BAD???
3275c51f124SMoriah Waterland 	 * is returned to indicate that no meaningful mode was provided. A
3285c51f124SMoriah Waterland 	 * higher authority will decide if that's OK or not. CUR??? means that
3295c51f124SMoriah Waterland 	 * the prototype file specifically requires a wildcard ('?') for
3305c51f124SMoriah Waterland 	 * that entry. We issue an error if attributes were entered wrong.
3315c51f124SMoriah Waterland 	 * We just return BAD??? if there was no entry at all.
3325c51f124SMoriah Waterland 	 */
3335c51f124SMoriah Waterland 	if (strchr("cbdxpfve", ept->ftype)) {
3345c51f124SMoriah Waterland 		int retval;
3355c51f124SMoriah Waterland 
3365c51f124SMoriah Waterland 		if ((retval = getvalmode(fp, &(ept->ainfo.mode), CURMODE,
3375c51f124SMoriah Waterland 		    (mapmode != MAPNONE))) == 1)
3385c51f124SMoriah Waterland 			goto end;	/* nothing else on the line */
3395c51f124SMoriah Waterland 		else if (retval == 2)
3405c51f124SMoriah Waterland 			goto error;	/* mode is too no good */
3415c51f124SMoriah Waterland 
3425c51f124SMoriah Waterland 		/* owner & group should be here */
3435c51f124SMoriah Waterland 		if ((retval = getstr(fp, NULL, ATRSIZ,
3445c51f124SMoriah Waterland 		    ept->ainfo.owner)) == 1)
3455c51f124SMoriah Waterland 			goto end;	/* no owner or group - warning */
3465c51f124SMoriah Waterland 		if (retval == -1) {
3475c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_OWNTOOLONG));
3485c51f124SMoriah Waterland 			goto error;
3495c51f124SMoriah Waterland 		}
3505c51f124SMoriah Waterland 
3515c51f124SMoriah Waterland 		if ((retval = getstr(fp, NULL, ATRSIZ,
3525c51f124SMoriah Waterland 		    ept->ainfo.group)) == 1)
3535c51f124SMoriah Waterland 			goto end;	/* no group - warning */
3545c51f124SMoriah Waterland 		if (retval == -1) {
3555c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_GRPTOOLONG));
3565c51f124SMoriah Waterland 			goto error;
3575c51f124SMoriah Waterland 		}
3585c51f124SMoriah Waterland 
3595c51f124SMoriah Waterland 		/* Resolve the parameters if required. */
3605c51f124SMoriah Waterland 		if (mapmode != MAPNONE) {
3615c51f124SMoriah Waterland 			if (mapvar(mapmode, ept->ainfo.owner)) {
3625c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
363*4f35a7b5SToomas Soome 				    getErrbufSize(),
364*4f35a7b5SToomas Soome 				    pkg_gt(ERR_NOVAR),
365*4f35a7b5SToomas Soome 				    maptype, ept->ainfo.owner);
3665c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
3675c51f124SMoriah Waterland 				goto error;
3685c51f124SMoriah Waterland 			}
3695c51f124SMoriah Waterland 			if (mapvar(mapmode, ept->ainfo.group)) {
3705c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
371*4f35a7b5SToomas Soome 				    getErrbufSize(), pkg_gt(ERR_NOVAR),
372*4f35a7b5SToomas Soome 				    maptype, ept->ainfo.group);
3735c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
3745c51f124SMoriah Waterland 				goto error;
3755c51f124SMoriah Waterland 			}
3765c51f124SMoriah Waterland 		}
3775c51f124SMoriah Waterland 	}
3785c51f124SMoriah Waterland 
3795c51f124SMoriah Waterland 	if (strchr("ifve", ept->ftype)) {
3805c51f124SMoriah Waterland 		/* look for content description */
3815c51f124SMoriah Waterland 		if (!getlnum(fp, 10, (fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
382*4f35a7b5SToomas Soome 		    (getnum(fp, 10, (long *)&ept->cinfo.cksum, BADCONT) ||
383*4f35a7b5SToomas Soome 		    getnum(fp, 10, (long *)&ept->cinfo.modtime, BADCONT))) {
3845c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
3855c51f124SMoriah Waterland 			goto error;
3865c51f124SMoriah Waterland 		}
3875c51f124SMoriah Waterland 	}
3885c51f124SMoriah Waterland 
3895c51f124SMoriah Waterland 	if (ept->ftype == 'i')
3905c51f124SMoriah Waterland 		goto end;
3915c51f124SMoriah Waterland 
3925c51f124SMoriah Waterland end:
3935c51f124SMoriah Waterland 	if (getend(fp) && ept->pinfo) {
3945c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
3955c51f124SMoriah Waterland 		return (-1);
3965c51f124SMoriah Waterland 	}
3975c51f124SMoriah Waterland 
3985c51f124SMoriah Waterland 	return (1);
3995c51f124SMoriah Waterland }
4005c51f124SMoriah Waterland 
4015c51f124SMoriah Waterland /*
4025c51f124SMoriah Waterland  * Get and validate the mode attribute. This returns an error if
4035c51f124SMoriah Waterland  *	1. the mode string is too long
4045c51f124SMoriah Waterland  *	2. the mode string includes alpha characters
4055c51f124SMoriah Waterland  *	3. the mode string is not octal
4065c51f124SMoriah Waterland  *	4. mode string is an install parameter
4075c51f124SMoriah Waterland  *	5. mode is an unresolved build parameter and MAPBUILD is
4085c51f124SMoriah Waterland  *	   in effect.
4095c51f124SMoriah Waterland  * If the mode is a build parameter, it is
4105c51f124SMoriah Waterland  *	1. returned as is if MAPNONE is in effect
4115c51f124SMoriah Waterland  *	2. evaluated if MAPBUILD is in effect
4125c51f124SMoriah Waterland  *
4135c51f124SMoriah Waterland  * NOTE : We use "mapmode!=MAPBUILD" to gather that it is install
4145c51f124SMoriah Waterland  * time. At install time we just fix a mode with bad bits set by
4155c51f124SMoriah Waterland  * setting it to CURMODE. This should be an error in a few releases
4165c51f124SMoriah Waterland  * (2.8 maybe) but faulty modes are so common in existing packages
4175c51f124SMoriah Waterland  * that this is a reasonable exception. -- JST 1994-11-9
4185c51f124SMoriah Waterland  *
4195c51f124SMoriah Waterland  * RETURNS
4205c51f124SMoriah Waterland  *	0 if mode is being returned as a valid value
4215c51f124SMoriah Waterland  *	1 if no attributes are present on the line
4225c51f124SMoriah Waterland  *	2 if there was a fundamental error
4235c51f124SMoriah Waterland  */
4245c51f124SMoriah Waterland static int
getvalmode(FILE * fp,mode_t * d,long bad,int map)4255c51f124SMoriah Waterland getvalmode(FILE *fp, mode_t *d, long bad, int map)
4265c51f124SMoriah Waterland {
4275c51f124SMoriah Waterland 	char tempmode[20];
4285c51f124SMoriah Waterland 	mode_t tempmode_t;
4295c51f124SMoriah Waterland 	int retval;
4305c51f124SMoriah Waterland 
4315c51f124SMoriah Waterland 	if ((retval = getstr(fp, NULL, ATRSIZ, tempmode)) == 1)
4325c51f124SMoriah Waterland 		return (1);
4335c51f124SMoriah Waterland 	else if (retval == -1) {
4345c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_MODELONG));
4355c51f124SMoriah Waterland 		return (2);
4365c51f124SMoriah Waterland 	} else {
4375c51f124SMoriah Waterland 		/*
4385c51f124SMoriah Waterland 		 * If it isn't a '?' (meaning go with whatever mode is
4395c51f124SMoriah Waterland 		 * there), validate the mode and convert it to a mode_t. The
4405c51f124SMoriah Waterland 		 * "bad" variable here is a misnomer. It doesn't necessarily
4415c51f124SMoriah Waterland 		 * mean bad.
4425c51f124SMoriah Waterland 		 */
4435c51f124SMoriah Waterland 		if (tempmode[0] == '?') {
4445c51f124SMoriah Waterland 			*d = WILDCARD;
4455c51f124SMoriah Waterland 		} else {
4465c51f124SMoriah Waterland 			/*
4475c51f124SMoriah Waterland 			 * Mode may not be an install parameter or a
4485c51f124SMoriah Waterland 			 * non-build parameter.
4495c51f124SMoriah Waterland 			 */
4505c51f124SMoriah Waterland 			if (tempmode[0] == '$' &&
4515c51f124SMoriah Waterland 			    (isupper(tempmode[1]) || !islower(tempmode[1]))) {
4525c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_IMODE));
4535c51f124SMoriah Waterland 				return (2);
4545c51f124SMoriah Waterland 			}
4555c51f124SMoriah Waterland 
4565c51f124SMoriah Waterland 			if ((map) && (mapvar(mapmode, tempmode))) {
4575c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
458*4f35a7b5SToomas Soome 				    getErrbufSize(),
459*4f35a7b5SToomas Soome 				    pkg_gt(ERR_NOVAR),
460*4f35a7b5SToomas Soome 				    maptype, tempmode);
4615c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
4625c51f124SMoriah Waterland 				return (2);
4635c51f124SMoriah Waterland 			}
4645c51f124SMoriah Waterland 
4655c51f124SMoriah Waterland 
4665c51f124SMoriah Waterland 			if (tempmode[0] == '$') {
4675c51f124SMoriah Waterland 				*d = BADMODE;	/* may be a problem */
4685c51f124SMoriah Waterland 			} else {
4695c51f124SMoriah Waterland 				/*
4705c51f124SMoriah Waterland 				 * At this point it's supposed to be
4715c51f124SMoriah Waterland 				 * something we can convert to a number.
4725c51f124SMoriah Waterland 				 */
4735c51f124SMoriah Waterland 				int n = 0;
4745c51f124SMoriah Waterland 
4755c51f124SMoriah Waterland 				/*
4765c51f124SMoriah Waterland 				 * We reject it if it contains nonnumbers or
4775c51f124SMoriah Waterland 				 * it's not octal.
4785c51f124SMoriah Waterland 				 */
4795c51f124SMoriah Waterland 				while (tempmode[n] && !isspace(tempmode[n])) {
4805c51f124SMoriah Waterland 					if (!isdigit(tempmode[n])) {
4815c51f124SMoriah Waterland 						setErrstr(
482*4f35a7b5SToomas Soome 						    pkg_gt(ERR_MODEALPHA));
4835c51f124SMoriah Waterland 						return (2);
4845c51f124SMoriah Waterland 					}
4855c51f124SMoriah Waterland 
4865c51f124SMoriah Waterland 					if (strchr("89abcdefABCDEF",
4875c51f124SMoriah Waterland 					    tempmode[n])) {
4885c51f124SMoriah Waterland 						setErrstr(
489*4f35a7b5SToomas Soome 						    pkg_gt(ERR_BASEINVAL));
4905c51f124SMoriah Waterland 						return (2);
4915c51f124SMoriah Waterland 					}
4925c51f124SMoriah Waterland 					n++;
4935c51f124SMoriah Waterland 				}
4945c51f124SMoriah Waterland 
4955c51f124SMoriah Waterland 				tempmode_t = strtol(tempmode, NULL, 8);
4965c51f124SMoriah Waterland 
4975c51f124SMoriah Waterland 				/*
4985c51f124SMoriah Waterland 				 * We reject it if it contains inappropriate
4995c51f124SMoriah Waterland 				 * bits.
5005c51f124SMoriah Waterland 				 */
5015c51f124SMoriah Waterland 				if (tempmode_t & ~(S_IAMB |
5025c51f124SMoriah Waterland 				    S_ISUID | S_ISGID | S_ISVTX)) {
5035c51f124SMoriah Waterland 					if (mapmode != MAPBUILD) {
5045c51f124SMoriah Waterland 						tempmode_t = bad;
5055c51f124SMoriah Waterland 					} else {
5065c51f124SMoriah Waterland 						setErrstr(pkg_gt(ERR_MODEBITS));
5075c51f124SMoriah Waterland 						return (2);
5085c51f124SMoriah Waterland 					}
5095c51f124SMoriah Waterland 				}
5105c51f124SMoriah Waterland 				*d = tempmode_t;
5115c51f124SMoriah Waterland 			}
5125c51f124SMoriah Waterland 		}
5135c51f124SMoriah Waterland 		return (0);
5145c51f124SMoriah Waterland 	}
5155c51f124SMoriah Waterland }
5165c51f124SMoriah Waterland 
5175c51f124SMoriah Waterland static int
getnum(FILE * fp,int base,long * d,long bad)5185c51f124SMoriah Waterland getnum(FILE *fp, int base, long *d, long bad)
5195c51f124SMoriah Waterland {
5205c51f124SMoriah Waterland 	int c, b;
5215c51f124SMoriah Waterland 
5225c51f124SMoriah Waterland 	/* leading white space ignored */
5235c51f124SMoriah Waterland 	c = eatwhite(fp);
5245c51f124SMoriah Waterland 	if (c == '?') {
5255c51f124SMoriah Waterland 		*d = bad;
5265c51f124SMoriah Waterland 		return (0);
5275c51f124SMoriah Waterland 	}
5285c51f124SMoriah Waterland 
5295c51f124SMoriah Waterland 	if ((c == EOF) || (c == '\n') || !isdigit(c)) {
5305c51f124SMoriah Waterland 		(void) ungetc(c, fp);
5315c51f124SMoriah Waterland 		return (1);
5325c51f124SMoriah Waterland 	}
5335c51f124SMoriah Waterland 
5345c51f124SMoriah Waterland 	*d = 0;
5355c51f124SMoriah Waterland 	while (isdigit(c)) {
5365c51f124SMoriah Waterland 		b = (c & 017);
5375c51f124SMoriah Waterland 		if (b >= base)
5385c51f124SMoriah Waterland 			return (2);
5395c51f124SMoriah Waterland 		*d = (*d * base) + b;
5405c51f124SMoriah Waterland 		c = getc(fp);
5415c51f124SMoriah Waterland 	}
5425c51f124SMoriah Waterland 	(void) ungetc(c, fp);
5435c51f124SMoriah Waterland 	return (0);
5445c51f124SMoriah Waterland }
5455c51f124SMoriah Waterland 
5465c51f124SMoriah Waterland static int
getlnum(FILE * fp,int base,fsblkcnt_t * d,long bad)5475c51f124SMoriah Waterland getlnum(FILE *fp, int base, fsblkcnt_t *d, long bad)
5485c51f124SMoriah Waterland {
5495c51f124SMoriah Waterland 	int c, b;
5505c51f124SMoriah Waterland 
5515c51f124SMoriah Waterland 	/* leading white space ignored */
5525c51f124SMoriah Waterland 	c = eatwhite(fp);
5535c51f124SMoriah Waterland 	if (c == '?') {
5545c51f124SMoriah Waterland 		*d = bad;
5555c51f124SMoriah Waterland 		return (0);
5565c51f124SMoriah Waterland 	}
5575c51f124SMoriah Waterland 
5585c51f124SMoriah Waterland 	if ((c == EOF) || (c == '\n') || !isdigit(c)) {
5595c51f124SMoriah Waterland 		(void) ungetc(c, fp);
5605c51f124SMoriah Waterland 		return (1);
5615c51f124SMoriah Waterland 	}
5625c51f124SMoriah Waterland 
5635c51f124SMoriah Waterland 	*d = 0;
5645c51f124SMoriah Waterland 	while (isdigit(c)) {
5655c51f124SMoriah Waterland 		b = (c & 017);
5665c51f124SMoriah Waterland 		if (b >= base)
5675c51f124SMoriah Waterland 			return (2);
5685c51f124SMoriah Waterland 		*d = (*d * base) + b;
5695c51f124SMoriah Waterland 		c = getc(fp);
5705c51f124SMoriah Waterland 	}
5715c51f124SMoriah Waterland 	(void) ungetc(c, fp);
5725c51f124SMoriah Waterland 	return (0);
5735c51f124SMoriah Waterland }
5745c51f124SMoriah Waterland 
5755c51f124SMoriah Waterland /*
5765c51f124SMoriah Waterland  *  Get a string from the file. Returns
5775c51f124SMoriah Waterland  *	0 if all OK
5785c51f124SMoriah Waterland  *	1 if nothing there
5795c51f124SMoriah Waterland  *	-1 if string is too long
5805c51f124SMoriah Waterland  */
5815c51f124SMoriah Waterland static int
getstr(FILE * fp,char * sep,int n,char * str)5825c51f124SMoriah Waterland getstr(FILE *fp, char *sep, int n, char *str)
5835c51f124SMoriah Waterland {
5845c51f124SMoriah Waterland 	int c;
5855c51f124SMoriah Waterland 
5865c51f124SMoriah Waterland 	/* leading white space ignored */
5875c51f124SMoriah Waterland 	c = eatwhite(fp);
5885c51f124SMoriah Waterland 	if ((c == EOF) || (c == '\n')) {
5895c51f124SMoriah Waterland 		(void) ungetc(c, fp);
5905c51f124SMoriah Waterland 		return (1); /* nothing there */
5915c51f124SMoriah Waterland 	}
5925c51f124SMoriah Waterland 
5935c51f124SMoriah Waterland 	/* fill up string until space, tab, or separator */
5945c51f124SMoriah Waterland 	while (!strchr(" \t", c) && (!sep || !strchr(sep, c))) {
5955c51f124SMoriah Waterland 		if (n-- < 1) {
5965c51f124SMoriah Waterland 			*str = '\0';
5975c51f124SMoriah Waterland 			return (-1); /* too long */
5985c51f124SMoriah Waterland 		}
5995c51f124SMoriah Waterland 		*str++ = (char)c;
6005c51f124SMoriah Waterland 		c = getc(fp);
6015c51f124SMoriah Waterland 		if ((c == EOF) || (c == '\n'))
6025c51f124SMoriah Waterland 			break; /* no more on this line */
6035c51f124SMoriah Waterland 	}
6045c51f124SMoriah Waterland 	*str = '\0';
6055c51f124SMoriah Waterland 	(void) ungetc(c, fp);
6065c51f124SMoriah Waterland 
6075c51f124SMoriah Waterland 	return (0);
6085c51f124SMoriah Waterland }
6095c51f124SMoriah Waterland 
6105c51f124SMoriah Waterland static int
getend(FILE * fp)6115c51f124SMoriah Waterland getend(FILE *fp)
6125c51f124SMoriah Waterland {
6135c51f124SMoriah Waterland 	int c;
6145c51f124SMoriah Waterland 	int n;
6155c51f124SMoriah Waterland 
6165c51f124SMoriah Waterland 	n = 0;
6175c51f124SMoriah Waterland 	do {
6185c51f124SMoriah Waterland 		if ((c = getc(fp)) == EOF)
6195c51f124SMoriah Waterland 			return (n);
6205c51f124SMoriah Waterland 		if (!isspace(c))
6215c51f124SMoriah Waterland 			n++;
6225c51f124SMoriah Waterland 	} while (c != '\n');
6235c51f124SMoriah Waterland 	return (n);
6245c51f124SMoriah Waterland }
6255c51f124SMoriah Waterland 
6265c51f124SMoriah Waterland static int
eatwhite(FILE * fp)6275c51f124SMoriah Waterland eatwhite(FILE *fp)
6285c51f124SMoriah Waterland {
6295c51f124SMoriah Waterland 	int c;
6305c51f124SMoriah Waterland 
6315c51f124SMoriah Waterland 	/* this test works around a side effect of getc() */
6325c51f124SMoriah Waterland 	if (feof(fp))
6335c51f124SMoriah Waterland 		return (EOF);
634*4f35a7b5SToomas Soome 	do {
6355c51f124SMoriah Waterland 		c = getc(fp);
636*4f35a7b5SToomas Soome 	} while ((c == ' ') || (c == '\t'));
6375c51f124SMoriah Waterland 	return (c);
6385c51f124SMoriah Waterland }
6395c51f124SMoriah Waterland 
6405c51f124SMoriah Waterland int
gpkgmapvfp(struct cfent * ept,VFP_T * vfp)6415c51f124SMoriah Waterland gpkgmapvfp(struct cfent *ept, VFP_T *vfp)
6425c51f124SMoriah Waterland {
6435c51f124SMoriah Waterland 	int		c;
6445c51f124SMoriah Waterland 	boolean_t	first_char = B_TRUE;
6455c51f124SMoriah Waterland 	(void) strlcpy(ept->pkg_class, BADCLASS, sizeof (ept->pkg_class));
6465c51f124SMoriah Waterland 	(void) strlcpy(ept->ainfo.owner, d_owner, sizeof (ept->ainfo.owner));
6475c51f124SMoriah Waterland 	(void) strlcpy(ept->ainfo.group, d_group, sizeof (ept->ainfo.group));
6485c51f124SMoriah Waterland 
6495c51f124SMoriah Waterland 	setErrstr(NULL);
6505c51f124SMoriah Waterland 	ept->volno = 0;
6515c51f124SMoriah Waterland 	ept->ftype = BADFTYPE;
6525c51f124SMoriah Waterland 	ept->pkg_class_idx = -1;
6535c51f124SMoriah Waterland 	ept->path = NULL;
6545c51f124SMoriah Waterland 	ept->ainfo.local = NULL;
6555c51f124SMoriah Waterland 	ept->ainfo.mode = d_mode;
6565c51f124SMoriah Waterland 	ept->ainfo.major = BADMAJOR;
6575c51f124SMoriah Waterland 	ept->ainfo.minor = BADMINOR;
6585c51f124SMoriah Waterland 	ept->cinfo.cksum = (-1L);
6595c51f124SMoriah Waterland 	ept->cinfo.modtime = (-1L);
6605c51f124SMoriah Waterland 	ept->cinfo.size = (-1L);
6615c51f124SMoriah Waterland 
6625c51f124SMoriah Waterland 	ept->npkgs = 0;
6635c51f124SMoriah Waterland 
6645c51f124SMoriah Waterland 	/* return error if no vfp specified */
6655c51f124SMoriah Waterland 
6665c51f124SMoriah Waterland 	if (vfp == (VFP_T *)NULL) {
6675c51f124SMoriah Waterland 		return (-1);
6685c51f124SMoriah Waterland 	}
6695c51f124SMoriah Waterland 
6705c51f124SMoriah Waterland readline:
6715c51f124SMoriah Waterland 	while (((c = vfpGetcNoInc(vfp)) != '\0') && (isspace(vfpGetc(vfp))))
6725c51f124SMoriah Waterland 		;
6735c51f124SMoriah Waterland 
6745c51f124SMoriah Waterland 	/*
6755c51f124SMoriah Waterland 	 * If the first character is not a digit, we assume that the
6765c51f124SMoriah Waterland 	 * volume number is 1.
6775c51f124SMoriah Waterland 	 */
6785c51f124SMoriah Waterland 	if (first_char && !isdigit(c)) {
6795c51f124SMoriah Waterland 		ept->volno = 1;
6805c51f124SMoriah Waterland 	}
6815c51f124SMoriah Waterland 	first_char = B_FALSE;
6825c51f124SMoriah Waterland 
6835c51f124SMoriah Waterland 	/*
6845c51f124SMoriah Waterland 	 * In case of hsfs the zero-padding of partial pages
6855c51f124SMoriah Waterland 	 * returned by mmap is not done properly. A separate bug has been filed
6865c51f124SMoriah Waterland 	 * on this.
6875c51f124SMoriah Waterland 	 */
6885c51f124SMoriah Waterland 
6895c51f124SMoriah Waterland 	if (vfp->_vfpCurr && (vfp->_vfpCurr > vfp->_vfpEnd)) {
6905c51f124SMoriah Waterland 		return (0);
6915c51f124SMoriah Waterland 	}
6925c51f124SMoriah Waterland 
6935c51f124SMoriah Waterland 	switch (c) {
694*4f35a7b5SToomas Soome 	case '\0':
6955c51f124SMoriah Waterland 		return (0);
6965c51f124SMoriah Waterland 
697*4f35a7b5SToomas Soome 	case '0':
698*4f35a7b5SToomas Soome 	case '1':
699*4f35a7b5SToomas Soome 	case '2':
700*4f35a7b5SToomas Soome 	case '3':
701*4f35a7b5SToomas Soome 	case '4':
702*4f35a7b5SToomas Soome 	case '5':
703*4f35a7b5SToomas Soome 	case '6':
704*4f35a7b5SToomas Soome 	case '7':
705*4f35a7b5SToomas Soome 	case '8':
706*4f35a7b5SToomas Soome 	case '9':
7075c51f124SMoriah Waterland 		if (ept->volno) {
7085c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BAD_VOLUME_NUMBER));
7095c51f124SMoriah Waterland 			goto error;
7105c51f124SMoriah Waterland 		}
7115c51f124SMoriah Waterland 		do {
7125c51f124SMoriah Waterland 			ept->volno = (ept->volno*10)+c-'0';
7135c51f124SMoriah Waterland 			c = vfpGetc(vfp);
7145c51f124SMoriah Waterland 		} while (isdigit(c));
7155c51f124SMoriah Waterland 		if (ept->volno == 0) {
7165c51f124SMoriah Waterland 			ept->volno = 1;
7175c51f124SMoriah Waterland 		}
7185c51f124SMoriah Waterland 
7195c51f124SMoriah Waterland 		goto readline;
7205c51f124SMoriah Waterland 
721*4f35a7b5SToomas Soome 	case ':':
722*4f35a7b5SToomas Soome 	case '#':
7235c51f124SMoriah Waterland 		(void) findendvfp(&vfpGetCurrCharPtr(vfp));
7245c51f124SMoriah Waterland 		/*FALLTHRU*/
725*4f35a7b5SToomas Soome 	case '\n':
7265c51f124SMoriah Waterland 		/*
7275c51f124SMoriah Waterland 		 * Since we are going to scan the next line,
7285c51f124SMoriah Waterland 		 * we need to reset volume number and first_char.
7295c51f124SMoriah Waterland 		 */
7305c51f124SMoriah Waterland 		ept->volno = 0;
7315c51f124SMoriah Waterland 		first_char = B_TRUE;
7325c51f124SMoriah Waterland 		goto readline;
7335c51f124SMoriah Waterland 
734*4f35a7b5SToomas Soome 	case 'i':
7355c51f124SMoriah Waterland 		ept->ftype = (char)c;
7365c51f124SMoriah Waterland 		while (((c = vfpGetcNoInc(vfp)) != '\0') &&
737*4f35a7b5SToomas Soome 		    (isspace(vfpGetc(vfp))))
7385c51f124SMoriah Waterland 			;
7395c51f124SMoriah Waterland 		/*FALLTHRU*/
740*4f35a7b5SToomas Soome 	case '.':
741*4f35a7b5SToomas Soome 	case '/':
7425c51f124SMoriah Waterland 		vfpDecCurrPtr(vfp);
7435c51f124SMoriah Waterland 
7445c51f124SMoriah Waterland 		if (getstrvfp(&vfpGetCurrCharPtr(vfp), "=", PATH_MAX, mypath)) {
7455c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
7465c51f124SMoriah Waterland 			goto error;
7475c51f124SMoriah Waterland 		}
7485c51f124SMoriah Waterland 		ept->path = mypath;
7495c51f124SMoriah Waterland 		c = vfpGetc(vfp);
7505c51f124SMoriah Waterland 		if (c == '=') {
7515c51f124SMoriah Waterland 			if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, PATH_MAX,
752*4f35a7b5SToomas Soome 			    mylocal)) {
7535c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_CANT_READ_LCLPATH));
7545c51f124SMoriah Waterland 				goto error;
7555c51f124SMoriah Waterland 			}
7565c51f124SMoriah Waterland 			ept->ainfo.local = mylocal;
7575c51f124SMoriah Waterland 		} else {
7585c51f124SMoriah Waterland 			vfpDecCurrPtr(vfp);
7595c51f124SMoriah Waterland 		}
7605c51f124SMoriah Waterland 
7615c51f124SMoriah Waterland 		if (ept->ftype == 'i') {
7625c51f124SMoriah Waterland 			/* content info might exist */
7635c51f124SMoriah Waterland 			if (!getlnumvfp(&vfpGetCurrCharPtr(vfp), 10,
764*4f35a7b5SToomas Soome 			    (fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
7655c51f124SMoriah Waterland 			    (getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
766*4f35a7b5SToomas Soome 			    (long *)&ept->cinfo.cksum, BADCONT) ||
7675c51f124SMoriah Waterland 			    getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
768*4f35a7b5SToomas Soome 			    (long *)&ept->cinfo.modtime, BADCONT))) {
7695c51f124SMoriah Waterland 				setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
7705c51f124SMoriah Waterland 				goto error;
7715c51f124SMoriah Waterland 			}
7725c51f124SMoriah Waterland 		}
7735c51f124SMoriah Waterland 
7745c51f124SMoriah Waterland 		if (getendvfp(&vfpGetCurrCharPtr(vfp))) {
7755c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
7765c51f124SMoriah Waterland 			return (-1);
7775c51f124SMoriah Waterland 		}
7785c51f124SMoriah Waterland 		return (1);
7795c51f124SMoriah Waterland 
780*4f35a7b5SToomas Soome 	case '?':
781*4f35a7b5SToomas Soome 	case 'f':
782*4f35a7b5SToomas Soome 	case 'v':
783*4f35a7b5SToomas Soome 	case 'e':
784*4f35a7b5SToomas Soome 	case 'l':
785*4f35a7b5SToomas Soome 	case 's':
786*4f35a7b5SToomas Soome 	case 'p':
787*4f35a7b5SToomas Soome 	case 'c':
788*4f35a7b5SToomas Soome 	case 'b':
789*4f35a7b5SToomas Soome 	case 'd':
790*4f35a7b5SToomas Soome 	case 'x':
7915c51f124SMoriah Waterland 		ept->ftype = (char)c;
7925c51f124SMoriah Waterland 		if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL,
793*4f35a7b5SToomas Soome 		    CLSSIZ, ept->pkg_class)) {
7945c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_CLASS_TOKEN));
7955c51f124SMoriah Waterland 			goto error;
7965c51f124SMoriah Waterland 		}
7975c51f124SMoriah Waterland 		if (getstrvfp(&vfpGetCurrCharPtr(vfp), "=", PATH_MAX, mypath)) {
7985c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_PATHNAME_FIELD));
7995c51f124SMoriah Waterland 			goto error;
8005c51f124SMoriah Waterland 		}
8015c51f124SMoriah Waterland 		ept->path = mypath;
8025c51f124SMoriah Waterland 
8035c51f124SMoriah Waterland 		c = vfpGetc(vfp);
8045c51f124SMoriah Waterland 		if (c == '=') {
8055c51f124SMoriah Waterland 			/* local path */
8065c51f124SMoriah Waterland 			if (getstrvfp(&vfpGetCurrCharPtr(vfp), NULL,
807*4f35a7b5SToomas Soome 			    PATH_MAX, mylocal)) {
8085c51f124SMoriah Waterland 				if (ept->ftype == 's' || ept->ftype == 'l') {
8095c51f124SMoriah Waterland 					setErrstr(pkg_gt(ERR_READLINK));
8105c51f124SMoriah Waterland 				} else {
8115c51f124SMoriah Waterland 					setErrstr(
812*4f35a7b5SToomas Soome 					    pkg_gt(ERR_CANT_READ_LCLPATH));
8135c51f124SMoriah Waterland 				}
8145c51f124SMoriah Waterland 				goto error;
8155c51f124SMoriah Waterland 			}
8165c51f124SMoriah Waterland 			ept->ainfo.local = mylocal;
8175c51f124SMoriah Waterland 		} else if ((ept->ftype == 's') || (ept->ftype == 'l')) {
8185c51f124SMoriah Waterland 			if ((c != '\0') && (c != '\n'))
8195c51f124SMoriah Waterland 				(void) findendvfp(&vfpGetCurrCharPtr(vfp));
8205c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BAD_LINK_SPEC));
8215c51f124SMoriah Waterland 			return (-1);
8225c51f124SMoriah Waterland 		} else {
8235c51f124SMoriah Waterland 			vfpDecCurrPtr(vfp);
8245c51f124SMoriah Waterland 		}
8255c51f124SMoriah Waterland 		break;
8265c51f124SMoriah Waterland 
827*4f35a7b5SToomas Soome 	default:
8285c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_UNKNOWN_FTYPE));
8295c51f124SMoriah Waterland error:
8305c51f124SMoriah Waterland 		(void) findendvfp(&vfpGetCurrCharPtr(vfp));
8315c51f124SMoriah Waterland 		return (-1);
8325c51f124SMoriah Waterland 	}
8335c51f124SMoriah Waterland 
8345c51f124SMoriah Waterland 	if (((ept->ftype == 's') || (ept->ftype == 'l')) &&
835*4f35a7b5SToomas Soome 	    (ept->ainfo.local == NULL)) {
8365c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_NO_LINKSOURCE));
8375c51f124SMoriah Waterland 		goto error;
8385c51f124SMoriah Waterland 	}
8395c51f124SMoriah Waterland 
8405c51f124SMoriah Waterland 	if (((ept->ftype == 'c') || (ept->ftype == 'b'))) {
8415c51f124SMoriah Waterland 		ept->ainfo.major = BADMAJOR;
8425c51f124SMoriah Waterland 		ept->ainfo.minor = BADMINOR;
8435c51f124SMoriah Waterland 
8445c51f124SMoriah Waterland 		if (getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
845*4f35a7b5SToomas Soome 		    (long *)&ept->ainfo.major, BADMAJOR) ||
8465c51f124SMoriah Waterland 		    getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
847*4f35a7b5SToomas Soome 		    (long *)&ept->ainfo.minor, BADMINOR)) {
8485c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_MM_DEVNUMS));
8495c51f124SMoriah Waterland 			goto error;
8505c51f124SMoriah Waterland 		}
8515c51f124SMoriah Waterland 	}
8525c51f124SMoriah Waterland 
8535c51f124SMoriah Waterland 	/*
8545c51f124SMoriah Waterland 	 * Links and information files don't have attributes associated with
8555c51f124SMoriah Waterland 	 * them. The following either resolves potential variables or passes
8565c51f124SMoriah Waterland 	 * them through. Mode is tested for validity to some degree. BAD???
8575c51f124SMoriah Waterland 	 * is returned to indicate that no meaningful mode was provided. A
8585c51f124SMoriah Waterland 	 * higher authority will decide if that's OK or not. CUR??? means that
8595c51f124SMoriah Waterland 	 * the prototype file specifically requires a wildcard ('?') for
8605c51f124SMoriah Waterland 	 * that entry. We issue an error if attributes were entered wrong.
8615c51f124SMoriah Waterland 	 * We just return BAD??? if there was no entry at all.
8625c51f124SMoriah Waterland 	 */
8635c51f124SMoriah Waterland 	if ((ept->ftype == 'd') || (ept->ftype == 'x') || (ept->ftype == 'c') ||
864*4f35a7b5SToomas Soome 	    (ept->ftype == 'b') || (ept->ftype == 'p') ||
865*4f35a7b5SToomas Soome 	    (ept->ftype == 'f') || (ept->ftype == 'v') ||
866*4f35a7b5SToomas Soome 	    (ept->ftype == 'e')) {
8675c51f124SMoriah Waterland 		int retval;
8685c51f124SMoriah Waterland 
8695c51f124SMoriah Waterland 		retval = getvalmodevfp(&vfpGetCurrCharPtr(vfp),
870*4f35a7b5SToomas Soome 		    &(ept->ainfo.mode), CURMODE, (mapmode != MAPNONE));
8715c51f124SMoriah Waterland 
8725c51f124SMoriah Waterland 		if (retval == 1) {
8735c51f124SMoriah Waterland 			goto end;	/* nothing else on the line */
8745c51f124SMoriah Waterland 		} else if (retval == 2) {
8755c51f124SMoriah Waterland 			goto error;	/* mode is too no good */
8765c51f124SMoriah Waterland 		}
8775c51f124SMoriah Waterland 
8785c51f124SMoriah Waterland 		/* owner & group should be here */
8795c51f124SMoriah Waterland 		if ((retval = getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, ATRSIZ,
8805c51f124SMoriah Waterland 		    ept->ainfo.owner)) == 1)
8815c51f124SMoriah Waterland 			goto end;	/* no owner or group - warning */
8825c51f124SMoriah Waterland 		if (retval == -1) {
8835c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_OWNTOOLONG));
8845c51f124SMoriah Waterland 			goto error;
8855c51f124SMoriah Waterland 		}
8865c51f124SMoriah Waterland 
8875c51f124SMoriah Waterland 		if ((retval = getstrvfp(&vfpGetCurrCharPtr(vfp), NULL, ATRSIZ,
8885c51f124SMoriah Waterland 		    ept->ainfo.group)) == 1)
8895c51f124SMoriah Waterland 			goto end;	/* no group - warning */
8905c51f124SMoriah Waterland 		if (retval == -1) {
8915c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_GRPTOOLONG));
8925c51f124SMoriah Waterland 			goto error;
8935c51f124SMoriah Waterland 		}
8945c51f124SMoriah Waterland 
8955c51f124SMoriah Waterland 		/* Resolve the parameters if required. */
8965c51f124SMoriah Waterland 		if (mapmode != MAPNONE) {
8975c51f124SMoriah Waterland 			if (mapvar(mapmode, ept->ainfo.owner)) {
8985c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
899*4f35a7b5SToomas Soome 				    getErrbufSize(), pkg_gt(ERR_NOVAR),
900*4f35a7b5SToomas Soome 				    maptype, ept->ainfo.owner);
9015c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
9025c51f124SMoriah Waterland 				goto error;
9035c51f124SMoriah Waterland 			}
9045c51f124SMoriah Waterland 			if (mapvar(mapmode, ept->ainfo.group)) {
9055c51f124SMoriah Waterland 				(void) snprintf(getErrbufAddr(),
906*4f35a7b5SToomas Soome 				    getErrbufSize(), pkg_gt(ERR_NOVAR),
907*4f35a7b5SToomas Soome 				    maptype, ept->ainfo.group);
9085c51f124SMoriah Waterland 				setErrstr(getErrbufAddr());
9095c51f124SMoriah Waterland 				goto error;
9105c51f124SMoriah Waterland 			}
9115c51f124SMoriah Waterland 		}
9125c51f124SMoriah Waterland 	}
9135c51f124SMoriah Waterland 
9145c51f124SMoriah Waterland 	if ((ept->ftype == 'i') || (ept->ftype == 'f') ||
915*4f35a7b5SToomas Soome 	    (ept->ftype == 'v') || (ept->ftype == 'e')) {
9165c51f124SMoriah Waterland 		/* look for content description */
9175c51f124SMoriah Waterland 		if (!getlnumvfp(&vfpGetCurrCharPtr(vfp), 10,
918*4f35a7b5SToomas Soome 		    (fsblkcnt_t *)&ept->cinfo.size, BADCONT) &&
919*4f35a7b5SToomas Soome 		    (getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
920*4f35a7b5SToomas Soome 		    (long *)&ept->cinfo.cksum, BADCONT) ||
921*4f35a7b5SToomas Soome 		    getnumvfp(&vfpGetCurrCharPtr(vfp), 10,
922*4f35a7b5SToomas Soome 		    (long *)&ept->cinfo.modtime, BADCONT))) {
9235c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_CANNOT_READ_CONTENT_INFO));
9245c51f124SMoriah Waterland 			goto error;
9255c51f124SMoriah Waterland 		}
9265c51f124SMoriah Waterland 	}
9275c51f124SMoriah Waterland 
9285c51f124SMoriah Waterland 	if (ept->ftype == 'i')
9295c51f124SMoriah Waterland 		goto end;
9305c51f124SMoriah Waterland 
9315c51f124SMoriah Waterland end:
9325c51f124SMoriah Waterland 	if (getendvfp(&vfpGetCurrCharPtr(vfp)) && ept->pinfo) {
9335c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_EXTRA_TOKENS_PRESENT));
9345c51f124SMoriah Waterland 		return (-1);
9355c51f124SMoriah Waterland 	}
9365c51f124SMoriah Waterland 
9375c51f124SMoriah Waterland 	return (1);
9385c51f124SMoriah Waterland }
9395c51f124SMoriah Waterland 
9405c51f124SMoriah Waterland /*
9415c51f124SMoriah Waterland  * Get and validate the mode attribute. This returns an error if
9425c51f124SMoriah Waterland  *	1. the mode string is too long
9435c51f124SMoriah Waterland  *	2. the mode string includes alpha characters
9445c51f124SMoriah Waterland  *	3. the mode string is not octal
9455c51f124SMoriah Waterland  *	4. mode string is an install parameter
9465c51f124SMoriah Waterland  *	5. mode is an unresolved build parameter and MAPBUILD is
9475c51f124SMoriah Waterland  *	   in effect.
9485c51f124SMoriah Waterland  * If the mode is a build parameter, it is
9495c51f124SMoriah Waterland  *	1. returned as is if MAPNONE is in effect
9505c51f124SMoriah Waterland  *	2. evaluated if MAPBUILD is in effect
9515c51f124SMoriah Waterland  *
9525c51f124SMoriah Waterland  * NOTE : We use "mapmode!=MAPBUILD" to gather that it is install
9535c51f124SMoriah Waterland  * time. At install time we just fix a mode with bad bits set by
9545c51f124SMoriah Waterland  * setting it to CURMODE. This should be an error in a few releases
9555c51f124SMoriah Waterland  * (2.8 maybe) but faulty modes are so common in existing packages
9565c51f124SMoriah Waterland  * that this is a reasonable exception. -- JST 1994-11-9
9575c51f124SMoriah Waterland  *
9585c51f124SMoriah Waterland  * RETURNS
9595c51f124SMoriah Waterland  *	0 if mode is being returned as a valid value
9605c51f124SMoriah Waterland  *	1 if no attributes are present on the line
9615c51f124SMoriah Waterland  *	2 if there was a fundamental error
9625c51f124SMoriah Waterland  */
9635c51f124SMoriah Waterland static int
getvalmodevfp(char ** cp,mode_t * d,long bad,int map)9645c51f124SMoriah Waterland getvalmodevfp(char **cp, mode_t *d, long bad, int map)
9655c51f124SMoriah Waterland {
9665c51f124SMoriah Waterland 	char	tempmode[ATRSIZ+1];
9675c51f124SMoriah Waterland 	mode_t	tempmode_t;
9685c51f124SMoriah Waterland 	int	retval;
9695c51f124SMoriah Waterland 	int	n;
9705c51f124SMoriah Waterland 
9715c51f124SMoriah Waterland 	if ((retval = getstrvfp(cp, NULL, sizeof (tempmode), tempmode)) == 1) {
9725c51f124SMoriah Waterland 		return (1);
9735c51f124SMoriah Waterland 	} else if (retval == -1) {
9745c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_MODELONG));
9755c51f124SMoriah Waterland 		return (2);
9765c51f124SMoriah Waterland 	}
9775c51f124SMoriah Waterland 
9785c51f124SMoriah Waterland 	/*
9795c51f124SMoriah Waterland 	 * If it isn't a '?' (meaning go with whatever mode is
9805c51f124SMoriah Waterland 	 * there), validate the mode and convert it to a mode_t. The
9815c51f124SMoriah Waterland 	 * "bad" variable here is a misnomer. It doesn't necessarily
9825c51f124SMoriah Waterland 	 * mean bad.
9835c51f124SMoriah Waterland 	 */
9845c51f124SMoriah Waterland 	if (tempmode[0] == '?') {
9855c51f124SMoriah Waterland 		*d = WILDCARD;
9865c51f124SMoriah Waterland 		return (0);
9875c51f124SMoriah Waterland 	}
9885c51f124SMoriah Waterland 
9895c51f124SMoriah Waterland 	/*
9905c51f124SMoriah Waterland 	 * Mode may not be an install parameter or a
9915c51f124SMoriah Waterland 	 * non-build parameter.
9925c51f124SMoriah Waterland 	 */
9935c51f124SMoriah Waterland 
9945c51f124SMoriah Waterland 	if (tempmode[0] == '$' &&
9955c51f124SMoriah Waterland 	    (isupper(tempmode[1]) || !islower(tempmode[1]))) {
9965c51f124SMoriah Waterland 		setErrstr(pkg_gt(ERR_IMODE));
9975c51f124SMoriah Waterland 		return (2);
9985c51f124SMoriah Waterland 	}
9995c51f124SMoriah Waterland 
10005c51f124SMoriah Waterland 	if ((map) && (mapvar(mapmode, tempmode))) {
10015c51f124SMoriah Waterland 		(void) snprintf(getErrbufAddr(), getErrbufSize(),
1002*4f35a7b5SToomas Soome 		    pkg_gt(ERR_NOVAR), maptype, tempmode);
10035c51f124SMoriah Waterland 		setErrstr(getErrbufAddr());
10045c51f124SMoriah Waterland 		return (2);
10055c51f124SMoriah Waterland 	}
10065c51f124SMoriah Waterland 
10075c51f124SMoriah Waterland 	if (tempmode[0] == '$') {
10085c51f124SMoriah Waterland 		*d = BADMODE;	/* may be a problem */
10095c51f124SMoriah Waterland 		return (0);
10105c51f124SMoriah Waterland 	}
10115c51f124SMoriah Waterland 
10125c51f124SMoriah Waterland 	/* it's supposed to be something we can convert to a number */
10135c51f124SMoriah Waterland 
10145c51f124SMoriah Waterland 	n = 0;
10155c51f124SMoriah Waterland 
10165c51f124SMoriah Waterland 	/* reject it if it contains nonnumbers or it's not octal */
10175c51f124SMoriah Waterland 
10185c51f124SMoriah Waterland 	while (tempmode[n] && !isspace(tempmode[n])) {
10195c51f124SMoriah Waterland 		if (!isdigit(tempmode[n])) {
10205c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_MODEALPHA));
10215c51f124SMoriah Waterland 			return (2);
10225c51f124SMoriah Waterland 		}
10235c51f124SMoriah Waterland 
10245c51f124SMoriah Waterland 		if (strchr("89abcdefABCDEF", tempmode[n])) {
10255c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_BASEINVAL));
10265c51f124SMoriah Waterland 			return (2);
10275c51f124SMoriah Waterland 		}
10285c51f124SMoriah Waterland 		n++;
10295c51f124SMoriah Waterland 	}
10305c51f124SMoriah Waterland 
10315c51f124SMoriah Waterland 	tempmode_t = strtol(tempmode, NULL, 8);
10325c51f124SMoriah Waterland 
10335c51f124SMoriah Waterland 	/*
10345c51f124SMoriah Waterland 	 * We reject it if it contains inappropriate
10355c51f124SMoriah Waterland 	 * bits.
10365c51f124SMoriah Waterland 	 */
10375c51f124SMoriah Waterland 	if (tempmode_t & (~(S_IAMB | S_ISUID | S_ISGID | S_ISVTX))) {
10385c51f124SMoriah Waterland 		if (mapmode == MAPBUILD) {
10395c51f124SMoriah Waterland 			setErrstr(pkg_gt(ERR_MODEBITS));
10405c51f124SMoriah Waterland 			return (2);
10415c51f124SMoriah Waterland 		}
10425c51f124SMoriah Waterland 		tempmode_t = bad;
10435c51f124SMoriah Waterland 	}
10445c51f124SMoriah Waterland 
10455c51f124SMoriah Waterland 	*d = tempmode_t;
10465c51f124SMoriah Waterland 
10475c51f124SMoriah Waterland 	return (0);
10485c51f124SMoriah Waterland }
10495c51f124SMoriah Waterland 
10505c51f124SMoriah Waterland int
getnumvfp(char ** cp,int base,long * d,long bad)10515c51f124SMoriah Waterland getnumvfp(char **cp, int base, long *d, long bad)
10525c51f124SMoriah Waterland {
10535c51f124SMoriah Waterland 	int c;
10545c51f124SMoriah Waterland 	char	*p = *cp;
10555c51f124SMoriah Waterland 
10565c51f124SMoriah Waterland 	if (*p == '\0') {
10575c51f124SMoriah Waterland 		return (0);
10585c51f124SMoriah Waterland 	}
10595c51f124SMoriah Waterland 
10605c51f124SMoriah Waterland 	/* leading white space ignored */
10615c51f124SMoriah Waterland 	while (((c = *p) != '\0') && (isspace(*p++)))
10625c51f124SMoriah Waterland 		;
10635c51f124SMoriah Waterland 	if (c == '?') {
10645c51f124SMoriah Waterland 		*d = bad;
10655c51f124SMoriah Waterland 		*cp = p;
10665c51f124SMoriah Waterland 		return (0);
10675c51f124SMoriah Waterland 	}
10685c51f124SMoriah Waterland 
10695c51f124SMoriah Waterland 	if ((c == '\0') || (c == '\n') || !isdigit(c)) {
10705c51f124SMoriah Waterland 		p--;
10715c51f124SMoriah Waterland 		*cp = p;
10725c51f124SMoriah Waterland 		return (1);
10735c51f124SMoriah Waterland 	}
10745c51f124SMoriah Waterland 
10755c51f124SMoriah Waterland 	*d = 0;
10765c51f124SMoriah Waterland 	while (isdigit(c)) {
10775c51f124SMoriah Waterland 		*d = (*d * base) + (c & 017);
10785c51f124SMoriah Waterland 		c = *p++;
10795c51f124SMoriah Waterland 	}
10805c51f124SMoriah Waterland 	p--;
10815c51f124SMoriah Waterland 	*cp = p;
10825c51f124SMoriah Waterland 	return (0);
10835c51f124SMoriah Waterland }
10845c51f124SMoriah Waterland 
10855c51f124SMoriah Waterland int
getlnumvfp(char ** cp,int base,fsblkcnt_t * d,long bad)10865c51f124SMoriah Waterland getlnumvfp(char **cp, int base, fsblkcnt_t *d, long bad)
10875c51f124SMoriah Waterland {
10885c51f124SMoriah Waterland 	int c;
10895c51f124SMoriah Waterland 	char	*p = *cp;
10905c51f124SMoriah Waterland 
10915c51f124SMoriah Waterland 	if (*p == '\0') {
10925c51f124SMoriah Waterland 		return (0);
10935c51f124SMoriah Waterland 	}
10945c51f124SMoriah Waterland 
10955c51f124SMoriah Waterland 	/* leading white space ignored */
10965c51f124SMoriah Waterland 	while (((c = *p) != '\0') && (isspace(*p++)))
10975c51f124SMoriah Waterland 		;
10985c51f124SMoriah Waterland 	if (c == '?') {
10995c51f124SMoriah Waterland 		*d = bad;
11005c51f124SMoriah Waterland 		*cp = p;
11015c51f124SMoriah Waterland 		return (0);
11025c51f124SMoriah Waterland 	}
11035c51f124SMoriah Waterland 
11045c51f124SMoriah Waterland 	if ((c == '\0') || (c == '\n') || !isdigit(c)) {
11055c51f124SMoriah Waterland 		p--;
11065c51f124SMoriah Waterland 		*cp = p;
11075c51f124SMoriah Waterland 		return (1);
11085c51f124SMoriah Waterland 	}
11095c51f124SMoriah Waterland 
11105c51f124SMoriah Waterland 	*d = 0;
11115c51f124SMoriah Waterland 	while (isdigit(c)) {
11125c51f124SMoriah Waterland 		*d = (*d * base) + (c & 017);
11135c51f124SMoriah Waterland 		c = *p++;
11145c51f124SMoriah Waterland 	}
11155c51f124SMoriah Waterland 	p--;
11165c51f124SMoriah Waterland 	*cp = p;
11175c51f124SMoriah Waterland 	return (0);
11185c51f124SMoriah Waterland }
11195c51f124SMoriah Waterland 
11205c51f124SMoriah Waterland static int
getstrvfp(char ** cp,char * sep,int n,char * str)11215c51f124SMoriah Waterland getstrvfp(char **cp, char *sep, int n, char *str)
11225c51f124SMoriah Waterland {
11235c51f124SMoriah Waterland 	char	delims[256];
11245c51f124SMoriah Waterland 	int	c;
11255c51f124SMoriah Waterland 	char	*p = *cp;
11265c51f124SMoriah Waterland 	char	*p1;
11275c51f124SMoriah Waterland 	size_t	len;
11285c51f124SMoriah Waterland 
11295c51f124SMoriah Waterland 	if (*p == '\0') {
11305c51f124SMoriah Waterland 		return (1);
11315c51f124SMoriah Waterland 	}
11325c51f124SMoriah Waterland 
11335c51f124SMoriah Waterland 	/* leading white space ignored */
11345c51f124SMoriah Waterland 
11355c51f124SMoriah Waterland 	while (((c = *p) != '\0') && (isspace(*p++)))
11365c51f124SMoriah Waterland 		;
11375c51f124SMoriah Waterland 	if ((c == '\0') || (c == '\n')) {
11385c51f124SMoriah Waterland 		p--;
11395c51f124SMoriah Waterland 		*cp = p;
11405c51f124SMoriah Waterland 		return (1); /* nothing there */
11415c51f124SMoriah Waterland 	}
11425c51f124SMoriah Waterland 
11435c51f124SMoriah Waterland 	p--;
11445c51f124SMoriah Waterland 
11455c51f124SMoriah Waterland 	/* generate complete list of delimiters to scan for */
11465c51f124SMoriah Waterland 
11475c51f124SMoriah Waterland 	(void) strlcpy(delims, " \t\n", sizeof (delims));
11485c51f124SMoriah Waterland 	if ((sep != (char *)NULL) && (*sep != '\0')) {
11495c51f124SMoriah Waterland 		(void) strlcat(delims, sep, sizeof (delims));
11505c51f124SMoriah Waterland 	}
11515c51f124SMoriah Waterland 
11525c51f124SMoriah Waterland 	/* compute length based on delimiter found or not */
11535c51f124SMoriah Waterland 
11545c51f124SMoriah Waterland 	p1 = strpbrk(p, delims);
11555c51f124SMoriah Waterland 	if (p1 == (char *)NULL) {
11565c51f124SMoriah Waterland 		len = strlen(p);
11575c51f124SMoriah Waterland 	} else {
11585c51f124SMoriah Waterland 		len = (ptrdiff_t)p1 - (ptrdiff_t)p;
11595c51f124SMoriah Waterland 	}
11605c51f124SMoriah Waterland 
11615c51f124SMoriah Waterland 	/* if string will fit in result buffer copy string and return success */
11625c51f124SMoriah Waterland 
11635c51f124SMoriah Waterland 	if (len < n) {
11645c51f124SMoriah Waterland 		(void) memcpy(str, p, len);
11655c51f124SMoriah Waterland 		str[len] = '\0';
11665c51f124SMoriah Waterland 		p += len;
11675c51f124SMoriah Waterland 		*cp = p;
11685c51f124SMoriah Waterland 		return (0);
11695c51f124SMoriah Waterland 	}
11705c51f124SMoriah Waterland 
11715c51f124SMoriah Waterland 	/* result buffer too small; copy partial string, return error */
11725c51f124SMoriah Waterland 	(void) memcpy(str, p, n-1);
11735c51f124SMoriah Waterland 	str[n-1] = '\0';
11745c51f124SMoriah Waterland 	p += n;
11755c51f124SMoriah Waterland 	*cp = p;
11765c51f124SMoriah Waterland 	return (-1);
11775c51f124SMoriah Waterland }
11785c51f124SMoriah Waterland 
11795c51f124SMoriah Waterland /*
11805c51f124SMoriah Waterland  * Name:	getendvfp
11815c51f124SMoriah Waterland  * Description:	Locate the end of the current line given a pointer into a buffer
11825c51f124SMoriah Waterland  *		containing characters that is null terminated.
11835c51f124SMoriah Waterland  * Arguments:	char **cp - pointer to pointer to null-terminated string buffer
11845c51f124SMoriah Waterland  * Returns:	int == 0 -- no non-space characters preceeded the newline
11855c51f124SMoriah Waterland  *		    != 0 -- one or more non-space characters preceeded newline
11865c51f124SMoriah Waterland  * Effects:	cp is updated to point to the first character PAST the first new
11875c51f124SMoriah Waterland  *		line character found. If no newline character is found, cp is
11885c51f124SMoriah Waterland  *		updated to point to the '\0' at the end of the buffer.
11895c51f124SMoriah Waterland  */
11905c51f124SMoriah Waterland 
11915c51f124SMoriah Waterland static int
getendvfp(char ** cp)11925c51f124SMoriah Waterland getendvfp(char **cp)
11935c51f124SMoriah Waterland {
11945c51f124SMoriah Waterland 	int	n;
11955c51f124SMoriah Waterland 	char	*p = *cp;
11965c51f124SMoriah Waterland 
11975c51f124SMoriah Waterland 	n = 0;
11985c51f124SMoriah Waterland 
11995c51f124SMoriah Waterland 	/* if at end of buffer return no more characters left */
12005c51f124SMoriah Waterland 
12015c51f124SMoriah Waterland 	if (*p == '\0') {
12025c51f124SMoriah Waterland 		return (0);
12035c51f124SMoriah Waterland 	}
12045c51f124SMoriah Waterland 
12055c51f124SMoriah Waterland 	/* find the first null or end of line character */
12065c51f124SMoriah Waterland 
12075c51f124SMoriah Waterland 	while ((*p != '\0') && (*p != '\n')) {
12085c51f124SMoriah Waterland 		if (n == 0) {
12095c51f124SMoriah Waterland 			if (!isspace(*p)) {
12105c51f124SMoriah Waterland 				n++;
12115c51f124SMoriah Waterland 			}
12125c51f124SMoriah Waterland 		}
12135c51f124SMoriah Waterland 		p++;
12145c51f124SMoriah Waterland 	}
12155c51f124SMoriah Waterland 
12165c51f124SMoriah Waterland 	/* if at newline, increment pointer to first character past newline */
12175c51f124SMoriah Waterland 
12185c51f124SMoriah Waterland 	if (*p == '\n') {
12195c51f124SMoriah Waterland 		p++;
12205c51f124SMoriah Waterland 	}
12215c51f124SMoriah Waterland 
12225c51f124SMoriah Waterland 	/* set return pointer to null or first character past newline */
12235c51f124SMoriah Waterland 
12245c51f124SMoriah Waterland 	*cp = p;
12255c51f124SMoriah Waterland 
12265c51f124SMoriah Waterland 	/* return space/nospace indicator */
12275c51f124SMoriah Waterland 
12285c51f124SMoriah Waterland 	return (n);
12295c51f124SMoriah Waterland }
12305c51f124SMoriah Waterland 
12315c51f124SMoriah Waterland /*
12325c51f124SMoriah Waterland  * Name:	findendvfp
12335c51f124SMoriah Waterland  * Description:	Locate the end of the current line given a pointer into a buffer
12345c51f124SMoriah Waterland  *		containing characters that is null terminated.
12355c51f124SMoriah Waterland  * Arguments:	char **cp - pointer to pointer to null-terminated string buffer
12365c51f124SMoriah Waterland  * Returns:	none
12375c51f124SMoriah Waterland  * Effects:	cp is updated to point to the first character PAST the first new
12385c51f124SMoriah Waterland  *		line character found. If no newline character is found, cp is
12395c51f124SMoriah Waterland  *		updated to point to the '\0' at the end of the buffer.
12405c51f124SMoriah Waterland  */
12415c51f124SMoriah Waterland 
12425c51f124SMoriah Waterland static void
findendvfp(char ** cp)12435c51f124SMoriah Waterland findendvfp(char **cp)
12445c51f124SMoriah Waterland {
12455c51f124SMoriah Waterland 	char	*p1;
12465c51f124SMoriah Waterland 	char	*p = *cp;
12475c51f124SMoriah Waterland 
12485c51f124SMoriah Waterland 	/* if at end of buffer return no more characters left */
12495c51f124SMoriah Waterland 
12505c51f124SMoriah Waterland 	if (*p == '\0') {
12515c51f124SMoriah Waterland 		return;
12525c51f124SMoriah Waterland 	}
12535c51f124SMoriah Waterland 
12545c51f124SMoriah Waterland 	/* find the end of the line */
12555c51f124SMoriah Waterland 
12565c51f124SMoriah Waterland 	p1 = strchr(p, '\n');
12575c51f124SMoriah Waterland 	if (p1 != (char *)NULL) {
12585c51f124SMoriah Waterland 		*cp = ++p1;
12595c51f124SMoriah Waterland 		return;
12605c51f124SMoriah Waterland 	}
12615c51f124SMoriah Waterland 
12625c51f124SMoriah Waterland 	/* no newline found - point to null terminator */
12635c51f124SMoriah Waterland 
12645c51f124SMoriah Waterland 	*cp = strchr(p, '\0');
12655c51f124SMoriah Waterland }
1266