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