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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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