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