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