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 <string.h> 36*5c51f124SMoriah Waterland #include <strings.h> 37*5c51f124SMoriah Waterland #include <ctype.h> 38*5c51f124SMoriah Waterland #include <sys/types.h> 39*5c51f124SMoriah Waterland #include <libintl.h> 40*5c51f124SMoriah Waterland #include "pkglib.h" 41*5c51f124SMoriah Waterland #include "pkgstrct.h" 42*5c51f124SMoriah Waterland #include "pkglocale.h" 43*5c51f124SMoriah Waterland #include "pkglibmsgs.h" 44*5c51f124SMoriah Waterland 45*5c51f124SMoriah Waterland /* 46*5c51f124SMoriah Waterland * Forward declarations 47*5c51f124SMoriah Waterland */ 48*5c51f124SMoriah Waterland 49*5c51f124SMoriah Waterland static void findend(char **cp); 50*5c51f124SMoriah Waterland static int getend(char **cp); 51*5c51f124SMoriah Waterland static int getstr(char **cp, int n, char *str, int separator[]); 52*5c51f124SMoriah Waterland 53*5c51f124SMoriah Waterland /* from gpkgmap.c */ 54*5c51f124SMoriah Waterland int getnumvfp(char **cp, int base, long *d, long bad); 55*5c51f124SMoriah Waterland int getlnumvfp(char **cp, int base, fsblkcnt_t *d, long bad); 56*5c51f124SMoriah Waterland 57*5c51f124SMoriah Waterland /* 58*5c51f124SMoriah Waterland * Module globals 59*5c51f124SMoriah Waterland */ 60*5c51f124SMoriah Waterland 61*5c51f124SMoriah Waterland static char lpath[PATH_MAX]; /* for ept->path */ 62*5c51f124SMoriah Waterland static char mylocal[PATH_MAX]; /* for ept->ainfo.local */ 63*5c51f124SMoriah Waterland static int decisionTableInit = 0; 64*5c51f124SMoriah Waterland 65*5c51f124SMoriah Waterland /* 66*5c51f124SMoriah Waterland * These arrays must be indexable by an unsigned char. 67*5c51f124SMoriah Waterland */ 68*5c51f124SMoriah Waterland 69*5c51f124SMoriah Waterland static int ISPKGPATHSEP[UCHAR_MAX+1]; 70*5c51f124SMoriah Waterland static int ISWORDSEP[UCHAR_MAX+1]; 71*5c51f124SMoriah Waterland static int ISPKGNAMESEP[UCHAR_MAX+1]; 72*5c51f124SMoriah Waterland 73*5c51f124SMoriah Waterland /* 74*5c51f124SMoriah Waterland * Name: WRITEDATA 75*5c51f124SMoriah Waterland * Description: write out data to VFP_T given start and end pointers 76*5c51f124SMoriah Waterland * Arguments: VFP - (VFP_T *) - [RO, *RW] 77*5c51f124SMoriah Waterland * Contents file VFP to narrow search on 78*5c51f124SMoriah Waterland * FIRSTPOS - (char *) - [RO, *RO] 79*5c51f124SMoriah Waterland * Pointer to first byte to write out 80*5c51f124SMoriah Waterland * LASTPOS - (char *) - [RO, *RO] 81*5c51f124SMoriah Waterland * Pointer to last byte to write out 82*5c51f124SMoriah Waterland */ 83*5c51f124SMoriah Waterland 84*5c51f124SMoriah Waterland #define WRITEDATA(VFP, FIRSTPOS, LASTPOS) \ 85*5c51f124SMoriah Waterland { \ 86*5c51f124SMoriah Waterland ssize_t XXlenXX; \ 87*5c51f124SMoriah Waterland /* compute number of bytes skipped */ \ 88*5c51f124SMoriah Waterland XXlenXX = (ptrdiff_t)(LASTPOS) - (ptrdiff_t)(FIRSTPOS); \ 89*5c51f124SMoriah Waterland /* write the bytes out */ \ 90*5c51f124SMoriah Waterland vfpPutBytes((VFP), (FIRSTPOS), XXlenXX); \ 91*5c51f124SMoriah Waterland } 92*5c51f124SMoriah Waterland 93*5c51f124SMoriah Waterland /* 94*5c51f124SMoriah Waterland * Name: COPYPATH 95*5c51f124SMoriah Waterland * Description: copy path limiting size to destination capacity 96*5c51f124SMoriah Waterland * Arguments: DEST - (char []) - [RW] 97*5c51f124SMoriah Waterland * SRC - (char *) - [RO, *RO] 98*5c51f124SMoriah Waterland * Pointer to first byte of path to copy 99*5c51f124SMoriah Waterland * LEN - (int) - [RO] 100*5c51f124SMoriah Waterland * Number of bytes to copy 101*5c51f124SMoriah Waterland */ 102*5c51f124SMoriah Waterland 103*5c51f124SMoriah Waterland #define COPYPATH(DEST, SRC, LEN) \ 104*5c51f124SMoriah Waterland { \ 105*5c51f124SMoriah Waterland /* assure return path does not overflow */ \ 106*5c51f124SMoriah Waterland if ((LEN) > sizeof ((DEST))) { \ 107*5c51f124SMoriah Waterland (LEN) = sizeof ((DEST))-1; \ 108*5c51f124SMoriah Waterland } \ 109*5c51f124SMoriah Waterland /* copy return path to local storage */ \ 110*5c51f124SMoriah Waterland (void) memcpy((DEST), (SRC), (LEN)); \ 111*5c51f124SMoriah Waterland (DEST)[(LEN)] = '\0'; \ 112*5c51f124SMoriah Waterland } 113*5c51f124SMoriah Waterland 114*5c51f124SMoriah Waterland /* 115*5c51f124SMoriah Waterland * Name: narrowSearch 116*5c51f124SMoriah Waterland * Description: narrow the search location for a specified path 117*5c51f124SMoriah Waterland * The contents and package map files are always sorted by path. 118*5c51f124SMoriah Waterland * This function is given a target path to search for given the 119*5c51f124SMoriah Waterland * current location in a contents file. It is assured that the 120*5c51f124SMoriah Waterland * target path has not been searched for yet in the contents file 121*5c51f124SMoriah Waterland * so the current location in the contents file is guaranteed to 122*5c51f124SMoriah Waterland * be less than the location of the target path (if present). 123*5c51f124SMoriah Waterland * Given this employ a binary search to speed up the search for 124*5c51f124SMoriah Waterland * the path nearest to a specified target path. 125*5c51f124SMoriah Waterland * Arguments: a_vfp - (VFP_T *) - [RO, *RW] 126*5c51f124SMoriah Waterland * Contents file VFP to narrow search on 127*5c51f124SMoriah Waterland * a_path - (char *) - [RO, *RO] 128*5c51f124SMoriah Waterland * Pointer to path to search for 129*5c51f124SMoriah Waterland * a_pathLen - (size_t) - [RO] 130*5c51f124SMoriah Waterland * Length of string (a_path) 131*5c51f124SMoriah Waterland * Returns: char * - pointer to first byte of entry in contents file that 132*5c51f124SMoriah Waterland * is guaranteed to be the closest match to the specified 133*5c51f124SMoriah Waterland * a_path without being "greater than" the path. 134*5c51f124SMoriah Waterland * == (char *)NULL if no entry found 135*5c51f124SMoriah Waterland */ 136*5c51f124SMoriah Waterland 137*5c51f124SMoriah Waterland static char * 138*5c51f124SMoriah Waterland narrowSearch(VFP_T *a_vfp, char *a_path, size_t a_pathLen) 139*5c51f124SMoriah Waterland { 140*5c51f124SMoriah Waterland char *phigh; 141*5c51f124SMoriah Waterland char *plow; 142*5c51f124SMoriah Waterland char *pmid; 143*5c51f124SMoriah Waterland int n; 144*5c51f124SMoriah Waterland size_t plen; 145*5c51f124SMoriah Waterland 146*5c51f124SMoriah Waterland /* if no path to compare, start at beginning */ 147*5c51f124SMoriah Waterland 148*5c51f124SMoriah Waterland if ((a_path == (char *)NULL) || (*a_path == '\0')) { 149*5c51f124SMoriah Waterland return ((char *)NULL); 150*5c51f124SMoriah Waterland } 151*5c51f124SMoriah Waterland 152*5c51f124SMoriah Waterland /* if the contents file is empty, resort to sequential search */ 153*5c51f124SMoriah Waterland 154*5c51f124SMoriah Waterland if (vfpGetBytesRemaining(a_vfp) <= 1) { 155*5c51f124SMoriah Waterland return ((char *)NULL); 156*5c51f124SMoriah Waterland } 157*5c51f124SMoriah Waterland 158*5c51f124SMoriah Waterland /* 159*5c51f124SMoriah Waterland * test against first path - if the path specified is less than the 160*5c51f124SMoriah Waterland * first path in the contents file, then the path can be inserted 161*5c51f124SMoriah Waterland * before the first entry in the contents file. 162*5c51f124SMoriah Waterland */ 163*5c51f124SMoriah Waterland 164*5c51f124SMoriah Waterland /* locate start of first line */ 165*5c51f124SMoriah Waterland 166*5c51f124SMoriah Waterland plow = vfpGetCurrCharPtr(a_vfp); 167*5c51f124SMoriah Waterland pmid = plow; 168*5c51f124SMoriah Waterland 169*5c51f124SMoriah Waterland /* if first path not absolute, resort to sequential search */ 170*5c51f124SMoriah Waterland 171*5c51f124SMoriah Waterland if (*pmid != '/') { 172*5c51f124SMoriah Waterland return ((char *)NULL); 173*5c51f124SMoriah Waterland } 174*5c51f124SMoriah Waterland 175*5c51f124SMoriah Waterland /* find end of path */ 176*5c51f124SMoriah Waterland 177*5c51f124SMoriah Waterland while (ISPKGPATHSEP[(int)*pmid] == 0) { 178*5c51f124SMoriah Waterland pmid++; 179*5c51f124SMoriah Waterland } 180*5c51f124SMoriah Waterland 181*5c51f124SMoriah Waterland /* determine length of path */ 182*5c51f124SMoriah Waterland 183*5c51f124SMoriah Waterland plen = (ptrdiff_t)pmid - (ptrdiff_t)plow; 184*5c51f124SMoriah Waterland 185*5c51f124SMoriah Waterland /* compare target path with current path */ 186*5c51f124SMoriah Waterland 187*5c51f124SMoriah Waterland n = strncmp(a_path, plow, plen); 188*5c51f124SMoriah Waterland if (n == 0) { 189*5c51f124SMoriah Waterland /* if lengths same exact match return position found */ 190*5c51f124SMoriah Waterland if (a_pathLen == plen) { 191*5c51f124SMoriah Waterland return (plow); 192*5c51f124SMoriah Waterland } 193*5c51f124SMoriah Waterland /* not exact match - a_path > pm */ 194*5c51f124SMoriah Waterland n = a_pathLen; 195*5c51f124SMoriah Waterland } 196*5c51f124SMoriah Waterland 197*5c51f124SMoriah Waterland /* return if target is less than or equal to first entry */ 198*5c51f124SMoriah Waterland 199*5c51f124SMoriah Waterland if (n <= 0) { 200*5c51f124SMoriah Waterland return (plow); 201*5c51f124SMoriah Waterland } 202*5c51f124SMoriah Waterland 203*5c51f124SMoriah Waterland /* 204*5c51f124SMoriah Waterland * test against last path - if the path specified is greater than the 205*5c51f124SMoriah Waterland * last path in the contents file, then the path can be appended after 206*5c51f124SMoriah Waterland * the last entry in the contents file. 207*5c51f124SMoriah Waterland */ 208*5c51f124SMoriah Waterland 209*5c51f124SMoriah Waterland /* locate start of last line */ 210*5c51f124SMoriah Waterland 211*5c51f124SMoriah Waterland plow = vfpGetCurrCharPtr(a_vfp); 212*5c51f124SMoriah Waterland pmid = vfpGetLastCharPtr(a_vfp); 213*5c51f124SMoriah Waterland 214*5c51f124SMoriah Waterland while ((pmid > plow) && (!((pmid[0] == '/') && (pmid[-1] == '\n')))) { 215*5c51f124SMoriah Waterland pmid--; 216*5c51f124SMoriah Waterland } 217*5c51f124SMoriah Waterland 218*5c51f124SMoriah Waterland /* if absolute path, do comparison */ 219*5c51f124SMoriah Waterland 220*5c51f124SMoriah Waterland if ((pmid > plow) && (*pmid == '/')) { 221*5c51f124SMoriah Waterland plow = pmid; 222*5c51f124SMoriah Waterland 223*5c51f124SMoriah Waterland /* find end of path */ 224*5c51f124SMoriah Waterland 225*5c51f124SMoriah Waterland while (ISPKGPATHSEP[(int)*pmid] == 0) { 226*5c51f124SMoriah Waterland pmid++; 227*5c51f124SMoriah Waterland } 228*5c51f124SMoriah Waterland 229*5c51f124SMoriah Waterland /* determine length of path */ 230*5c51f124SMoriah Waterland 231*5c51f124SMoriah Waterland plen = (ptrdiff_t)pmid - (ptrdiff_t)plow; 232*5c51f124SMoriah Waterland 233*5c51f124SMoriah Waterland /* compare target path with current path */ 234*5c51f124SMoriah Waterland 235*5c51f124SMoriah Waterland n = strncmp(a_path, plow, plen); 236*5c51f124SMoriah Waterland if (n == 0) { 237*5c51f124SMoriah Waterland /* if lengths same exact match return position found */ 238*5c51f124SMoriah Waterland if (a_pathLen == plen) { 239*5c51f124SMoriah Waterland return (plow); 240*5c51f124SMoriah Waterland } 241*5c51f124SMoriah Waterland /* not exact match - a_path > pm */ 242*5c51f124SMoriah Waterland n = a_pathLen; 243*5c51f124SMoriah Waterland } 244*5c51f124SMoriah Waterland 245*5c51f124SMoriah Waterland /* return if target is greater than or equal to entry */ 246*5c51f124SMoriah Waterland 247*5c51f124SMoriah Waterland if (n >= 0) { 248*5c51f124SMoriah Waterland return (plow); 249*5c51f124SMoriah Waterland } 250*5c51f124SMoriah Waterland } 251*5c51f124SMoriah Waterland /* 252*5c51f124SMoriah Waterland * firstPath < targetpath < lastPath: 253*5c51f124SMoriah Waterland * binary search looking for closest "less than" match 254*5c51f124SMoriah Waterland */ 255*5c51f124SMoriah Waterland 256*5c51f124SMoriah Waterland plow = vfpGetCurrCharPtr(a_vfp); 257*5c51f124SMoriah Waterland phigh = vfpGetLastCharPtr(a_vfp); 258*5c51f124SMoriah Waterland 259*5c51f124SMoriah Waterland for (;;) { 260*5c51f124SMoriah Waterland char *pm; 261*5c51f124SMoriah Waterland 262*5c51f124SMoriah Waterland /* determine number of bytes left in search area */ 263*5c51f124SMoriah Waterland 264*5c51f124SMoriah Waterland plen = (ptrdiff_t)phigh - (ptrdiff_t)plow; 265*5c51f124SMoriah Waterland 266*5c51f124SMoriah Waterland /* calculate mid point between current low and high points */ 267*5c51f124SMoriah Waterland 268*5c51f124SMoriah Waterland pmid = plow + (plen >> 1); 269*5c51f124SMoriah Waterland 270*5c51f124SMoriah Waterland /* backup and find first "\n/" -or- start of buffer */ 271*5c51f124SMoriah Waterland 272*5c51f124SMoriah Waterland while ((pmid > plow) && 273*5c51f124SMoriah Waterland (!((pmid[0] == '/') && (pmid[-1] == '\n')))) { 274*5c51f124SMoriah Waterland pmid--; 275*5c51f124SMoriah Waterland } 276*5c51f124SMoriah Waterland 277*5c51f124SMoriah Waterland /* return lowest line found if current line not past that */ 278*5c51f124SMoriah Waterland 279*5c51f124SMoriah Waterland if (pmid <= plow) { 280*5c51f124SMoriah Waterland return (plow); 281*5c51f124SMoriah Waterland } 282*5c51f124SMoriah Waterland 283*5c51f124SMoriah Waterland /* remember start of this line */ 284*5c51f124SMoriah Waterland 285*5c51f124SMoriah Waterland pm = pmid; 286*5c51f124SMoriah Waterland 287*5c51f124SMoriah Waterland /* find end of path */ 288*5c51f124SMoriah Waterland 289*5c51f124SMoriah Waterland while (ISPKGPATHSEP[(int)*pmid] == 0) { 290*5c51f124SMoriah Waterland pmid++; 291*5c51f124SMoriah Waterland } 292*5c51f124SMoriah Waterland 293*5c51f124SMoriah Waterland /* determine length of path */ 294*5c51f124SMoriah Waterland 295*5c51f124SMoriah Waterland plen = (ptrdiff_t)pmid - (ptrdiff_t)pm; 296*5c51f124SMoriah Waterland 297*5c51f124SMoriah Waterland /* compare target path with current path */ 298*5c51f124SMoriah Waterland 299*5c51f124SMoriah Waterland n = strncmp(a_path, pm, plen); 300*5c51f124SMoriah Waterland 301*5c51f124SMoriah Waterland if (n == 0) { 302*5c51f124SMoriah Waterland /* if lengths same exact match return position found */ 303*5c51f124SMoriah Waterland if (a_pathLen == plen) { 304*5c51f124SMoriah Waterland return (pm); 305*5c51f124SMoriah Waterland } 306*5c51f124SMoriah Waterland /* not exact match - a_path > pm */ 307*5c51f124SMoriah Waterland n = a_pathLen; 308*5c51f124SMoriah Waterland } 309*5c51f124SMoriah Waterland 310*5c51f124SMoriah Waterland 311*5c51f124SMoriah Waterland /* not exact match - determine which watermark to split */ 312*5c51f124SMoriah Waterland 313*5c51f124SMoriah Waterland if (n > 0) { /* a_path > pm */ 314*5c51f124SMoriah Waterland plow = pm; 315*5c51f124SMoriah Waterland } else { /* a_path < pm */ 316*5c51f124SMoriah Waterland phigh = pm; 317*5c51f124SMoriah Waterland } 318*5c51f124SMoriah Waterland } 319*5c51f124SMoriah Waterland /*NOTREACHED*/ 320*5c51f124SMoriah Waterland } 321*5c51f124SMoriah Waterland 322*5c51f124SMoriah Waterland /* 323*5c51f124SMoriah Waterland * Name: srchcfile 324*5c51f124SMoriah Waterland * Description: search contents file looking for closest match to entry, 325*5c51f124SMoriah Waterland * creating a new contents file if output contents file specified 326*5c51f124SMoriah Waterland * Arguments: ept - (struct cfent *) - [RO, *RW] 327*5c51f124SMoriah Waterland * - contents file entry, describing last item found 328*5c51f124SMoriah Waterland * path - (char *) - [RO, *RO] 329*5c51f124SMoriah Waterland * - path to search for in contents file 330*5c51f124SMoriah Waterland * - If path is "*", then the next entry is returned; 331*5c51f124SMoriah Waterland * the next entry always matches this path 332*5c51f124SMoriah Waterland * - If the path is (char *)NULL or "", then all remaining 333*5c51f124SMoriah Waterland * entries are processed and copied out to the 334*5c51f124SMoriah Waterland * file specified by cfTmpVFp 335*5c51f124SMoriah Waterland * cfVfp - (VFP_T *) - [RO, *RW] 336*5c51f124SMoriah Waterland * - VFP_T open on contents file to search 337*5c51f124SMoriah Waterland * cfTmpVfp - (VFP_T *) - [RO, *RW] 338*5c51f124SMoriah Waterland * - VFP_T open on temporary contents file to populate 339*5c51f124SMoriah Waterland * Returns: int 340*5c51f124SMoriah Waterland * < 0 - error occurred 341*5c51f124SMoriah Waterland * - Use getErrstr to retrieve character-string describing 342*5c51f124SMoriah Waterland * the reason for failure 343*5c51f124SMoriah Waterland * == 0 - no match found 344*5c51f124SMoriah Waterland * - specified path not in the contents file 345*5c51f124SMoriah Waterland * - all contents of cfVfp copied to cfTmpVfp 346*5c51f124SMoriah Waterland * - current character of cfVfp is at end of file 347*5c51f124SMoriah Waterland * == 1 - exact match found 348*5c51f124SMoriah Waterland * - specified path found in contents file 349*5c51f124SMoriah Waterland * - contents of cfVfp up to entry found copied to cfTmpVfp 350*5c51f124SMoriah Waterland * - current character of cfVfp is first character of 351*5c51f124SMoriah Waterland * entry found 352*5c51f124SMoriah Waterland * - this value is always returned if path is "*" and the 353*5c51f124SMoriah Waterland * next entry is returned - -1 is returned when no more 354*5c51f124SMoriah Waterland * entries are left to process 355*5c51f124SMoriah Waterland * == 2 - entry found which is GREATER than path specified 356*5c51f124SMoriah Waterland * - specified path would fit BEFORE entry found 357*5c51f124SMoriah Waterland * - contents of cfVfp up to entry found copied to cfTmpVfp 358*5c51f124SMoriah Waterland * - current character of cfVfp is first character of 359*5c51f124SMoriah Waterland * entry found 360*5c51f124SMoriah Waterland * Side Effects: 361*5c51f124SMoriah Waterland * - The ept structure supplied is filled in with a description of 362*5c51f124SMoriah Waterland * the item that caused the search to terminate, except in the 363*5c51f124SMoriah Waterland * case of '0' in which case the contents of 'ept' is undefined. 364*5c51f124SMoriah Waterland * - NOTE: the ept->path item points to a path that is statically 365*5c51f124SMoriah Waterland * allocated and will be overwritten on the next call. 366*5c51f124SMoriah Waterland * - NOTE: the ept->ainfo.local item points to a path that is 367*5c51f124SMoriah Waterland * statically allocated and will be overwritten on the next call. 368*5c51f124SMoriah Waterland */ 369*5c51f124SMoriah Waterland 370*5c51f124SMoriah Waterland int 371*5c51f124SMoriah Waterland srchcfile(struct cfent *ept, char *path, VFP_T *cfVfp, VFP_T *cfTmpVfp) 372*5c51f124SMoriah Waterland { 373*5c51f124SMoriah Waterland char *cpath_start = (char *)NULL; 374*5c51f124SMoriah Waterland char *firstPos = vfpGetCurrCharPtr(cfVfp); 375*5c51f124SMoriah Waterland char *lastPos = NULL; 376*5c51f124SMoriah Waterland char *pos; 377*5c51f124SMoriah Waterland char classname[CLSSIZ+1]; 378*5c51f124SMoriah Waterland char pkgname[PKGSIZ+1]; 379*5c51f124SMoriah Waterland int anypath = 0; 380*5c51f124SMoriah Waterland int c; 381*5c51f124SMoriah Waterland int dataSkipped = 0; 382*5c51f124SMoriah Waterland int n; 383*5c51f124SMoriah Waterland int rdpath; 384*5c51f124SMoriah Waterland size_t cpath_len = 0; 385*5c51f124SMoriah Waterland size_t pathLength; 386*5c51f124SMoriah Waterland struct pinfo *lastpinfo; 387*5c51f124SMoriah Waterland struct pinfo *pinfo; 388*5c51f124SMoriah Waterland 389*5c51f124SMoriah Waterland /* 390*5c51f124SMoriah Waterland * this code does not use nested subroutines because execution time 391*5c51f124SMoriah Waterland * of this routine is especially critical to installation and upgrade 392*5c51f124SMoriah Waterland */ 393*5c51f124SMoriah Waterland 394*5c51f124SMoriah Waterland /* initialize local variables */ 395*5c51f124SMoriah Waterland 396*5c51f124SMoriah Waterland setErrstr(NULL); /* no error message currently cached */ 397*5c51f124SMoriah Waterland pathLength = (path == (char *)NULL ? 0 : strlen(path)); 398*5c51f124SMoriah Waterland lpath[0] = '\0'; 399*5c51f124SMoriah Waterland lpath[sizeof (lpath)-1] = '\0'; 400*5c51f124SMoriah Waterland 401*5c51f124SMoriah Waterland /* initialize ept structure values */ 402*5c51f124SMoriah Waterland 403*5c51f124SMoriah Waterland (void) strlcpy(ept->ainfo.group, BADGROUP, sizeof (ept->ainfo.group)); 404*5c51f124SMoriah Waterland (void) strlcpy(ept->ainfo.owner, BADOWNER, sizeof (ept->ainfo.owner)); 405*5c51f124SMoriah Waterland (void) strlcpy(ept->pkg_class, BADCLASS, sizeof (ept->pkg_class)); 406*5c51f124SMoriah Waterland ept->ainfo.local = (char *)NULL; 407*5c51f124SMoriah Waterland ept->ainfo.mode = BADMODE; 408*5c51f124SMoriah Waterland ept->cinfo.cksum = BADCONT; 409*5c51f124SMoriah Waterland ept->cinfo.modtime = BADCONT; 410*5c51f124SMoriah Waterland ept->cinfo.size = (fsblkcnt_t)BADCONT; 411*5c51f124SMoriah Waterland ept->ftype = BADFTYPE; 412*5c51f124SMoriah Waterland ept->npkgs = 0; 413*5c51f124SMoriah Waterland ept->path = (char *)NULL; 414*5c51f124SMoriah Waterland ept->pinfo = (struct pinfo *)NULL; 415*5c51f124SMoriah Waterland ept->pkg_class_idx = -1; 416*5c51f124SMoriah Waterland ept->volno = 0; 417*5c51f124SMoriah Waterland 418*5c51f124SMoriah Waterland /* 419*5c51f124SMoriah Waterland * populate decision tables that implement fast character checking; 420*5c51f124SMoriah Waterland * this is much faster than the equivalent strpbrk() call or a 421*5c51f124SMoriah Waterland * while() loop checking for the characters. It is only faster if 422*5c51f124SMoriah Waterland * there are at least 3 characters to scan for - when checking for 423*5c51f124SMoriah Waterland * one or two characters (such as '\n' or '\0') its faster to do 424*5c51f124SMoriah Waterland * a simple while() loop. 425*5c51f124SMoriah Waterland */ 426*5c51f124SMoriah Waterland 427*5c51f124SMoriah Waterland if (decisionTableInit == 0) { 428*5c51f124SMoriah Waterland /* 429*5c51f124SMoriah Waterland * any chars listed stop scan; 430*5c51f124SMoriah Waterland * scan stops on first byte found that is set to '1' below 431*5c51f124SMoriah Waterland */ 432*5c51f124SMoriah Waterland 433*5c51f124SMoriah Waterland /* 434*5c51f124SMoriah Waterland * Separators for path names, normal space and = 435*5c51f124SMoriah Waterland * for linked filenames 436*5c51f124SMoriah Waterland */ 437*5c51f124SMoriah Waterland bzero(ISPKGPATHSEP, sizeof (ISPKGPATHSEP)); 438*5c51f124SMoriah Waterland ISPKGPATHSEP['='] = 1; /* = */ 439*5c51f124SMoriah Waterland ISPKGPATHSEP[' '] = 1; /* space */ 440*5c51f124SMoriah Waterland ISPKGPATHSEP['\t'] = 1; /* horizontal-tab */ 441*5c51f124SMoriah Waterland ISPKGPATHSEP['\n'] = 1; /* new-line */ 442*5c51f124SMoriah Waterland ISPKGPATHSEP['\0'] = 1; /* NULL character */ 443*5c51f124SMoriah Waterland 444*5c51f124SMoriah Waterland /* 445*5c51f124SMoriah Waterland * Separators for normal words 446*5c51f124SMoriah Waterland */ 447*5c51f124SMoriah Waterland bzero(ISWORDSEP, sizeof (ISWORDSEP)); 448*5c51f124SMoriah Waterland ISWORDSEP[' '] = 1; 449*5c51f124SMoriah Waterland ISWORDSEP['\t'] = 1; 450*5c51f124SMoriah Waterland ISWORDSEP['\n'] = 1; 451*5c51f124SMoriah Waterland ISWORDSEP['\0'] = 1; 452*5c51f124SMoriah Waterland 453*5c51f124SMoriah Waterland /* 454*5c51f124SMoriah Waterland * Separators for list of packages, includes \\ for 455*5c51f124SMoriah Waterland * alternate ftype and : for classname 456*5c51f124SMoriah Waterland */ 457*5c51f124SMoriah Waterland bzero(ISPKGNAMESEP, sizeof (ISPKGNAMESEP)); 458*5c51f124SMoriah Waterland ISPKGNAMESEP[' '] = 1; 459*5c51f124SMoriah Waterland ISPKGNAMESEP['\t'] = 1; 460*5c51f124SMoriah Waterland ISPKGNAMESEP['\n'] = 1; 461*5c51f124SMoriah Waterland ISPKGNAMESEP[':'] = 1; 462*5c51f124SMoriah Waterland ISPKGNAMESEP['\\'] = 1; 463*5c51f124SMoriah Waterland ISPKGNAMESEP['\0'] = 1; 464*5c51f124SMoriah Waterland 465*5c51f124SMoriah Waterland decisionTableInit = 1; 466*5c51f124SMoriah Waterland } 467*5c51f124SMoriah Waterland 468*5c51f124SMoriah Waterland /* if no bytes in contents file, return 0 */ 469*5c51f124SMoriah Waterland 470*5c51f124SMoriah Waterland if (vfpGetBytesRemaining(cfVfp) <= 1) { 471*5c51f124SMoriah Waterland return (0); 472*5c51f124SMoriah Waterland } 473*5c51f124SMoriah Waterland 474*5c51f124SMoriah Waterland /* if the path to scan for is empty, act like no path was specified */ 475*5c51f124SMoriah Waterland 476*5c51f124SMoriah Waterland if ((path != (char *)NULL) && (*path == '\0')) { 477*5c51f124SMoriah Waterland path = (char *)NULL; 478*5c51f124SMoriah Waterland } 479*5c51f124SMoriah Waterland 480*5c51f124SMoriah Waterland /* 481*5c51f124SMoriah Waterland * if path to search for is "*", then we will return the first path 482*5c51f124SMoriah Waterland * we encounter as a match, otherwise we return an error 483*5c51f124SMoriah Waterland */ 484*5c51f124SMoriah Waterland 485*5c51f124SMoriah Waterland if ((path != (char *)NULL) && (path[0] != '/')) { 486*5c51f124SMoriah Waterland if (strcmp(path, "*") != 0) { 487*5c51f124SMoriah Waterland setErrstr(pkg_gt(ERR_ILLEGAL_SEARCH_PATH)); 488*5c51f124SMoriah Waterland return (-1); 489*5c51f124SMoriah Waterland } 490*5c51f124SMoriah Waterland anypath = 1; 491*5c51f124SMoriah Waterland } 492*5c51f124SMoriah Waterland 493*5c51f124SMoriah Waterland /* attempt to narrow down the search for the specified path */ 494*5c51f124SMoriah Waterland 495*5c51f124SMoriah Waterland if (anypath == 0) { 496*5c51f124SMoriah Waterland char *np; 497*5c51f124SMoriah Waterland 498*5c51f124SMoriah Waterland np = narrowSearch(cfVfp, path, pathLength); 499*5c51f124SMoriah Waterland if (np != (char *)NULL) { 500*5c51f124SMoriah Waterland dataSkipped = 1; 501*5c51f124SMoriah Waterland lastPos = np; 502*5c51f124SMoriah Waterland vfpSetCurrCharPtr(cfVfp, np); 503*5c51f124SMoriah Waterland } 504*5c51f124SMoriah Waterland } 505*5c51f124SMoriah Waterland 506*5c51f124SMoriah Waterland /* 507*5c51f124SMoriah Waterland * If the path to search for in the source contents file is NULL, then 508*5c51f124SMoriah Waterland * this is a request to scan to the end of the source contents file. If 509*5c51f124SMoriah Waterland * there is a temporary contents file to copy entries to, all that needs 510*5c51f124SMoriah Waterland * to be done is to copy the data remaining from the current location in 511*5c51f124SMoriah Waterland * the source contents file to the end of the temporary contents file. 512*5c51f124SMoriah Waterland * if there is no temporary contents file to copy to, then all that 513*5c51f124SMoriah Waterland * needs to be done is to seek to the end of the source contents file. 514*5c51f124SMoriah Waterland */ 515*5c51f124SMoriah Waterland 516*5c51f124SMoriah Waterland if ((anypath == 0) && (path == (char *)NULL)) { 517*5c51f124SMoriah Waterland if (cfTmpVfp != (VFP_T *)NULL) { 518*5c51f124SMoriah Waterland if (vfpGetBytesRemaining(cfVfp) > 0) { 519*5c51f124SMoriah Waterland WRITEDATA(cfTmpVfp, firstPos, 520*5c51f124SMoriah Waterland vfpGetLastCharPtr(cfVfp)+1); 521*5c51f124SMoriah Waterland } 522*5c51f124SMoriah Waterland *vfpGetLastCharPtr(cfTmpVfp) = '\0'; 523*5c51f124SMoriah Waterland } 524*5c51f124SMoriah Waterland vfpSeekToEnd(cfVfp); 525*5c51f124SMoriah Waterland return (0); 526*5c51f124SMoriah Waterland } 527*5c51f124SMoriah Waterland 528*5c51f124SMoriah Waterland /* 529*5c51f124SMoriah Waterland * ********************************************************************* 530*5c51f124SMoriah Waterland * main loop processing entries from the contents file looking for 531*5c51f124SMoriah Waterland * the specified path 532*5c51f124SMoriah Waterland * ********************************************************************* 533*5c51f124SMoriah Waterland */ 534*5c51f124SMoriah Waterland 535*5c51f124SMoriah Waterland for (;;) { 536*5c51f124SMoriah Waterland char *p; 537*5c51f124SMoriah Waterland 538*5c51f124SMoriah Waterland /* not reading old style entry */ 539*5c51f124SMoriah Waterland 540*5c51f124SMoriah Waterland rdpath = 0; 541*5c51f124SMoriah Waterland 542*5c51f124SMoriah Waterland /* determine first character of the next entry */ 543*5c51f124SMoriah Waterland 544*5c51f124SMoriah Waterland if (vfpGetBytesRemaining(cfVfp) <= 0) { 545*5c51f124SMoriah Waterland /* no bytes in contents file current char is NULL */ 546*5c51f124SMoriah Waterland 547*5c51f124SMoriah Waterland c = '\0'; 548*5c51f124SMoriah Waterland } else { 549*5c51f124SMoriah Waterland /* grab path from first entry */ 550*5c51f124SMoriah Waterland 551*5c51f124SMoriah Waterland c = vfpGetcNoInc(cfVfp); 552*5c51f124SMoriah Waterland } 553*5c51f124SMoriah Waterland 554*5c51f124SMoriah Waterland /* save current position in file */ 555*5c51f124SMoriah Waterland 556*5c51f124SMoriah Waterland pos = vfpGetCurrCharPtr(cfVfp); 557*5c51f124SMoriah Waterland 558*5c51f124SMoriah Waterland /* 559*5c51f124SMoriah Waterland * ============================================================= 560*5c51f124SMoriah Waterland * at the first character of the next entry in the contents file 561*5c51f124SMoriah Waterland * if not absolute path check for exceptions and old style entry 562*5c51f124SMoriah Waterland * --> if end of contents file write out skipped data and return 563*5c51f124SMoriah Waterland * --> if comment character skip to end of line and restart loop 564*5c51f124SMoriah Waterland * --> else process "old style entry: ftype class path" 565*5c51f124SMoriah Waterland * ============================================================= 566*5c51f124SMoriah Waterland */ 567*5c51f124SMoriah Waterland 568*5c51f124SMoriah Waterland if (c != '/') { 569*5c51f124SMoriah Waterland /* if NULL character then end of contents file found */ 570*5c51f124SMoriah Waterland 571*5c51f124SMoriah Waterland if (c == '\0') { 572*5c51f124SMoriah Waterland /* write out skipped data before returning */ 573*5c51f124SMoriah Waterland if (dataSkipped && 574*5c51f124SMoriah Waterland (cfTmpVfp != (VFP_T *)NULL)) { 575*5c51f124SMoriah Waterland WRITEDATA(cfTmpVfp, firstPos, lastPos); 576*5c51f124SMoriah Waterland *vfpGetLastCharPtr(cfTmpVfp) = '\0'; 577*5c51f124SMoriah Waterland } 578*5c51f124SMoriah Waterland 579*5c51f124SMoriah Waterland return (0); /* no more entries */ 580*5c51f124SMoriah Waterland } 581*5c51f124SMoriah Waterland 582*5c51f124SMoriah Waterland /* ignore lines that begin with #, : or a "space" */ 583*5c51f124SMoriah Waterland 584*5c51f124SMoriah Waterland if ((isspace(c) != 0) || (c == '#') || (c == ':')) { 585*5c51f124SMoriah Waterland /* line is a comment */ 586*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 587*5c51f124SMoriah Waterland continue; 588*5c51f124SMoriah Waterland } 589*5c51f124SMoriah Waterland 590*5c51f124SMoriah Waterland /* 591*5c51f124SMoriah Waterland * old style entry - format is: 592*5c51f124SMoriah Waterland * ftype class path 593*5c51f124SMoriah Waterland * set ept->ftype to the type 594*5c51f124SMoriah Waterland * set ept->class to the class 595*5c51f124SMoriah Waterland * set ept->path to point to lpath 596*5c51f124SMoriah Waterland * set cpath_start/cpath_len to point to the file name 597*5c51f124SMoriah Waterland * set rdpath to '1' to indicate old style entry parsed 598*5c51f124SMoriah Waterland */ 599*5c51f124SMoriah Waterland 600*5c51f124SMoriah Waterland while (isspace((c = vfpGetc(cfVfp)))) 601*5c51f124SMoriah Waterland ; 602*5c51f124SMoriah Waterland 603*5c51f124SMoriah Waterland switch (c) { 604*5c51f124SMoriah Waterland case '?': case 'f': case 'v': case 'e': case 'l': 605*5c51f124SMoriah Waterland case 's': case 'p': case 'c': case 'b': case 'd': 606*5c51f124SMoriah Waterland case 'x': 607*5c51f124SMoriah Waterland /* save ftype */ 608*5c51f124SMoriah Waterland ept->ftype = (char)c; 609*5c51f124SMoriah Waterland 610*5c51f124SMoriah Waterland /* save class */ 611*5c51f124SMoriah Waterland if (getstr(&vfpGetCurrCharPtr(cfVfp), CLSSIZ, 612*5c51f124SMoriah Waterland ept->pkg_class, ISWORDSEP)) { 613*5c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_CLASS_TOKEN); 614*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 615*5c51f124SMoriah Waterland return (-1); 616*5c51f124SMoriah Waterland } 617*5c51f124SMoriah Waterland 618*5c51f124SMoriah Waterland /* 619*5c51f124SMoriah Waterland * locate file name up to "=", set cpath_start 620*5c51f124SMoriah Waterland * and cpath_len to point to the file name 621*5c51f124SMoriah Waterland */ 622*5c51f124SMoriah Waterland cpath_start = vfpGetCurrCharPtr(cfVfp); 623*5c51f124SMoriah Waterland p = vfpGetCurrCharPtr(cfVfp); 624*5c51f124SMoriah Waterland 625*5c51f124SMoriah Waterland /* 626*5c51f124SMoriah Waterland * skip past all bytes until first '= \t\n\0': 627*5c51f124SMoriah Waterland */ 628*5c51f124SMoriah Waterland while (ISPKGPATHSEP[(int)*p] == 0) { 629*5c51f124SMoriah Waterland p++; 630*5c51f124SMoriah Waterland } 631*5c51f124SMoriah Waterland 632*5c51f124SMoriah Waterland cpath_len = vfpGetCurrPtrDelta(cfVfp, p); 633*5c51f124SMoriah Waterland 634*5c51f124SMoriah Waterland /* 635*5c51f124SMoriah Waterland * if the path is zero bytes, line is corrupted 636*5c51f124SMoriah Waterland */ 637*5c51f124SMoriah Waterland 638*5c51f124SMoriah Waterland if (cpath_len < 1) { 639*5c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_PATHNAME_FLD); 640*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 641*5c51f124SMoriah Waterland return (-1); 642*5c51f124SMoriah Waterland } 643*5c51f124SMoriah Waterland 644*5c51f124SMoriah Waterland vfpIncCurrPtrBy(cfVfp, cpath_len); 645*5c51f124SMoriah Waterland 646*5c51f124SMoriah Waterland /* set path to point to local path cache */ 647*5c51f124SMoriah Waterland ept->path = lpath; 648*5c51f124SMoriah Waterland 649*5c51f124SMoriah Waterland /* set flag indicating path already parsed */ 650*5c51f124SMoriah Waterland rdpath = 1; 651*5c51f124SMoriah Waterland break; 652*5c51f124SMoriah Waterland 653*5c51f124SMoriah Waterland case '\0': 654*5c51f124SMoriah Waterland /* end of line before new-line seen */ 655*5c51f124SMoriah Waterland vfpDecCurrPtr(cfVfp); 656*5c51f124SMoriah Waterland setErrstr(ERR_INCOMPLETE_ENTRY); 657*5c51f124SMoriah Waterland return (-1); 658*5c51f124SMoriah Waterland 659*5c51f124SMoriah Waterland case '0': case '1': case '2': case '3': case '4': 660*5c51f124SMoriah Waterland case '5': case '6': case '7': case '8': case '9': 661*5c51f124SMoriah Waterland /* volume number seen */ 662*5c51f124SMoriah Waterland setErrstr(ERR_VOLUMENO_UNEXPECTED); 663*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 664*5c51f124SMoriah Waterland return (-1); 665*5c51f124SMoriah Waterland 666*5c51f124SMoriah Waterland case 'i': 667*5c51f124SMoriah Waterland /* type i files are not cataloged */ 668*5c51f124SMoriah Waterland setErrstr(ERR_FTYPE_I_UNEXPECTED); 669*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 670*5c51f124SMoriah Waterland return (-1); 671*5c51f124SMoriah Waterland 672*5c51f124SMoriah Waterland default: 673*5c51f124SMoriah Waterland /* unknown ftype */ 674*5c51f124SMoriah Waterland setErrstr(ERR_UNKNOWN_FTYPE); 675*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 676*5c51f124SMoriah Waterland return (-1); 677*5c51f124SMoriah Waterland } 678*5c51f124SMoriah Waterland } else { 679*5c51f124SMoriah Waterland /* 680*5c51f124SMoriah Waterland * current entry DOES start with absolute path 681*5c51f124SMoriah Waterland * set ept->path to point to lpath 682*5c51f124SMoriah Waterland * set cpath_start/cpath_len to point to the file name 683*5c51f124SMoriah Waterland */ 684*5c51f124SMoriah Waterland /* copy first token into path element of passed structure */ 685*5c51f124SMoriah Waterland 686*5c51f124SMoriah Waterland cpath_start = vfpGetCurrCharPtr(cfVfp); 687*5c51f124SMoriah Waterland 688*5c51f124SMoriah Waterland p = cpath_start; 689*5c51f124SMoriah Waterland 690*5c51f124SMoriah Waterland /* 691*5c51f124SMoriah Waterland * skip past all bytes until first from '= \t\n\0': 692*5c51f124SMoriah Waterland */ 693*5c51f124SMoriah Waterland 694*5c51f124SMoriah Waterland while (ISPKGPATHSEP[(int)*p] == 0) { 695*5c51f124SMoriah Waterland p++; 696*5c51f124SMoriah Waterland } 697*5c51f124SMoriah Waterland 698*5c51f124SMoriah Waterland cpath_len = vfpGetCurrPtrDelta(cfVfp, p); 699*5c51f124SMoriah Waterland 700*5c51f124SMoriah Waterland vfpIncCurrPtrBy(cfVfp, cpath_len); 701*5c51f124SMoriah Waterland 702*5c51f124SMoriah Waterland if (vfpGetcNoInc(cfVfp) == '\0') { 703*5c51f124SMoriah Waterland setErrstr(ERR_INCOMPLETE_ENTRY); 704*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 705*5c51f124SMoriah Waterland return (-1); 706*5c51f124SMoriah Waterland } 707*5c51f124SMoriah Waterland 708*5c51f124SMoriah Waterland ept->path = lpath; 709*5c51f124SMoriah Waterland } 710*5c51f124SMoriah Waterland 711*5c51f124SMoriah Waterland /* 712*5c51f124SMoriah Waterland * ============================================================= 713*5c51f124SMoriah Waterland * if absolute path then the path is collected and we are at the 714*5c51f124SMoriah Waterland * first byte following the absolute path name; 715*5c51f124SMoriah Waterland * if not an absolute path then an old style entry, ept has been 716*5c51f124SMoriah Waterland * filled with the type and class and path name. 717*5c51f124SMoriah Waterland * determine if we have read the pathname which identifies 718*5c51f124SMoriah Waterland * the entry we are searching for 719*5c51f124SMoriah Waterland * ============================================================= 720*5c51f124SMoriah Waterland */ 721*5c51f124SMoriah Waterland 722*5c51f124SMoriah Waterland if (anypath != 0) { 723*5c51f124SMoriah Waterland n = 0; /* next entry is "equal to" */ 724*5c51f124SMoriah Waterland } else if (path == (char *)NULL) { 725*5c51f124SMoriah Waterland n = 1; /* next entry is "greater than" */ 726*5c51f124SMoriah Waterland } else { 727*5c51f124SMoriah Waterland n = strncmp(path, cpath_start, cpath_len); 728*5c51f124SMoriah Waterland if ((n == 0) && (cpath_len != pathLength)) { 729*5c51f124SMoriah Waterland n = cpath_len; 730*5c51f124SMoriah Waterland } 731*5c51f124SMoriah Waterland } 732*5c51f124SMoriah Waterland 733*5c51f124SMoriah Waterland /* get first character following the end of the path */ 734*5c51f124SMoriah Waterland 735*5c51f124SMoriah Waterland c = vfpGetc(cfVfp); 736*5c51f124SMoriah Waterland 737*5c51f124SMoriah Waterland /* 738*5c51f124SMoriah Waterland * if an exact match, always parse out the local path 739*5c51f124SMoriah Waterland */ 740*5c51f124SMoriah Waterland 741*5c51f124SMoriah Waterland if (n == 0) { 742*5c51f124SMoriah Waterland /* 743*5c51f124SMoriah Waterland * we want to return information about this path in 744*5c51f124SMoriah Waterland * the structure provided, so parse any local path 745*5c51f124SMoriah Waterland * and jump to code which parses rest of the input line 746*5c51f124SMoriah Waterland */ 747*5c51f124SMoriah Waterland if (c == '=') { 748*5c51f124SMoriah Waterland /* parse local path specification */ 749*5c51f124SMoriah Waterland if (getstr(&vfpGetCurrCharPtr(cfVfp), PATH_MAX, 750*5c51f124SMoriah Waterland mylocal, ISWORDSEP)) { 751*5c51f124SMoriah Waterland 752*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 753*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 754*5c51f124SMoriah Waterland 755*5c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_LL_PATH); 756*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 757*5c51f124SMoriah Waterland return (-1); 758*5c51f124SMoriah Waterland } 759*5c51f124SMoriah Waterland ept->ainfo.local = mylocal; 760*5c51f124SMoriah Waterland } 761*5c51f124SMoriah Waterland } 762*5c51f124SMoriah Waterland 763*5c51f124SMoriah Waterland /* 764*5c51f124SMoriah Waterland * if an exact match and processing a new style entry, read the 765*5c51f124SMoriah Waterland * remaining information from the new style entry - if this is 766*5c51f124SMoriah Waterland * an old style entry (rdpath != 0) then the existing info has 767*5c51f124SMoriah Waterland * already been processed as it exists before the pathname and 768*5c51f124SMoriah Waterland * not after like a new style entry 769*5c51f124SMoriah Waterland */ 770*5c51f124SMoriah Waterland 771*5c51f124SMoriah Waterland if (n == 0 && rdpath == 0) { 772*5c51f124SMoriah Waterland while (isspace((c = vfpGetc(cfVfp)))) 773*5c51f124SMoriah Waterland ; 774*5c51f124SMoriah Waterland 775*5c51f124SMoriah Waterland switch (c) { 776*5c51f124SMoriah Waterland case '?': case 'f': case 'v': case 'e': case 'l': 777*5c51f124SMoriah Waterland case 's': case 'p': case 'c': case 'b': case 'd': 778*5c51f124SMoriah Waterland case 'x': 779*5c51f124SMoriah Waterland /* save ftype */ 780*5c51f124SMoriah Waterland ept->ftype = (char)c; 781*5c51f124SMoriah Waterland 782*5c51f124SMoriah Waterland /* save class */ 783*5c51f124SMoriah Waterland if (getstr(&vfpGetCurrCharPtr(cfVfp), CLSSIZ, 784*5c51f124SMoriah Waterland ept->pkg_class, ISWORDSEP)) { 785*5c51f124SMoriah Waterland 786*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 787*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 788*5c51f124SMoriah Waterland 789*5c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_CLASS_TOKEN); 790*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 791*5c51f124SMoriah Waterland return (-1); 792*5c51f124SMoriah Waterland } 793*5c51f124SMoriah Waterland break; /* we already read the pathname */ 794*5c51f124SMoriah Waterland 795*5c51f124SMoriah Waterland case '\0': 796*5c51f124SMoriah Waterland /* end of line before new-line seen */ 797*5c51f124SMoriah Waterland vfpDecCurrPtr(cfVfp); 798*5c51f124SMoriah Waterland 799*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 800*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 801*5c51f124SMoriah Waterland 802*5c51f124SMoriah Waterland setErrstr(ERR_INCOMPLETE_ENTRY); 803*5c51f124SMoriah Waterland return (-1); 804*5c51f124SMoriah Waterland 805*5c51f124SMoriah Waterland case '0': case '1': case '2': case '3': case '4': 806*5c51f124SMoriah Waterland case '5': case '6': case '7': case '8': case '9': 807*5c51f124SMoriah Waterland 808*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 809*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 810*5c51f124SMoriah Waterland 811*5c51f124SMoriah Waterland setErrstr(ERR_VOLUMENO_UNEXPECTED); 812*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 813*5c51f124SMoriah Waterland return (-1); 814*5c51f124SMoriah Waterland 815*5c51f124SMoriah Waterland case 'i': 816*5c51f124SMoriah Waterland 817*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 818*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 819*5c51f124SMoriah Waterland 820*5c51f124SMoriah Waterland setErrstr(ERR_FTYPE_I_UNEXPECTED); 821*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 822*5c51f124SMoriah Waterland return (-1); 823*5c51f124SMoriah Waterland 824*5c51f124SMoriah Waterland default: 825*5c51f124SMoriah Waterland /* unknown ftype */ 826*5c51f124SMoriah Waterland 827*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 828*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 829*5c51f124SMoriah Waterland 830*5c51f124SMoriah Waterland setErrstr(ERR_UNKNOWN_FTYPE); 831*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 832*5c51f124SMoriah Waterland return (-1); 833*5c51f124SMoriah Waterland } 834*5c51f124SMoriah Waterland } 835*5c51f124SMoriah Waterland 836*5c51f124SMoriah Waterland /* 837*5c51f124SMoriah Waterland * if an exact match all processing is completed; break out of 838*5c51f124SMoriah Waterland * the main processing loop and finish processing this entry 839*5c51f124SMoriah Waterland * prior to returning to the caller. 840*5c51f124SMoriah Waterland */ 841*5c51f124SMoriah Waterland 842*5c51f124SMoriah Waterland if (n == 0) { 843*5c51f124SMoriah Waterland break; 844*5c51f124SMoriah Waterland } 845*5c51f124SMoriah Waterland 846*5c51f124SMoriah Waterland /* 847*5c51f124SMoriah Waterland * this entry is not an exact match for the path being searched 848*5c51f124SMoriah Waterland * for - if this entry is GREATER THAN the path being searched 849*5c51f124SMoriah Waterland * for then finish processing and return GREATER THAN result 850*5c51f124SMoriah Waterland * to the caller so the entry for the path being searched for 851*5c51f124SMoriah Waterland * can be added to the contents file. 852*5c51f124SMoriah Waterland */ 853*5c51f124SMoriah Waterland 854*5c51f124SMoriah Waterland if (n < 0) { 855*5c51f124SMoriah Waterland /* 856*5c51f124SMoriah Waterland * the entry we want would fit BEFORE the one we just 857*5c51f124SMoriah Waterland * read, so we need to unread what we've read by 858*5c51f124SMoriah Waterland * seeking back to the start of this entry 859*5c51f124SMoriah Waterland */ 860*5c51f124SMoriah Waterland 861*5c51f124SMoriah Waterland vfpSetCurrCharPtr(cfVfp, pos); 862*5c51f124SMoriah Waterland 863*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 864*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 865*5c51f124SMoriah Waterland 866*5c51f124SMoriah Waterland /* write out any skipped data before returning */ 867*5c51f124SMoriah Waterland if (dataSkipped && (cfTmpVfp != (VFP_T *)NULL)) { 868*5c51f124SMoriah Waterland WRITEDATA(cfTmpVfp, firstPos, lastPos); 869*5c51f124SMoriah Waterland } 870*5c51f124SMoriah Waterland 871*5c51f124SMoriah Waterland return (2); /* path would insert here */ 872*5c51f124SMoriah Waterland } 873*5c51f124SMoriah Waterland 874*5c51f124SMoriah Waterland /* 875*5c51f124SMoriah Waterland * This entry is "LESS THAN" the specified path to search for 876*5c51f124SMoriah Waterland * need to process the next entry from the contents file. First, 877*5c51f124SMoriah Waterland * if writing to new contents file, update new contents file if 878*5c51f124SMoriah Waterland * processing old style entry; otherwise, update skipped data 879*5c51f124SMoriah Waterland * information to remember current last byte of skipped data. 880*5c51f124SMoriah Waterland */ 881*5c51f124SMoriah Waterland 882*5c51f124SMoriah Waterland if (cfTmpVfp != (VFP_T *)NULL) { 883*5c51f124SMoriah Waterland char *px; 884*5c51f124SMoriah Waterland ssize_t len; 885*5c51f124SMoriah Waterland 886*5c51f124SMoriah Waterland if (rdpath != 0) { 887*5c51f124SMoriah Waterland /* modify record: write out any skipped data */ 888*5c51f124SMoriah Waterland if (dataSkipped) { 889*5c51f124SMoriah Waterland WRITEDATA(cfTmpVfp, firstPos, lastPos); 890*5c51f124SMoriah Waterland } 891*5c51f124SMoriah Waterland 892*5c51f124SMoriah Waterland /* 893*5c51f124SMoriah Waterland * copy what we've read and the rest of this 894*5c51f124SMoriah Waterland * line onto the specified output stream 895*5c51f124SMoriah Waterland */ 896*5c51f124SMoriah Waterland vfpPutBytes(cfTmpVfp, cpath_start, cpath_len); 897*5c51f124SMoriah Waterland vfpPutc(cfTmpVfp, c); 898*5c51f124SMoriah Waterland vfpPutc(cfTmpVfp, ept->ftype); 899*5c51f124SMoriah Waterland vfpPutc(cfTmpVfp, ' '); 900*5c51f124SMoriah Waterland vfpPuts(cfTmpVfp, ept->pkg_class); 901*5c51f124SMoriah Waterland 902*5c51f124SMoriah Waterland px = strchr(vfpGetCurrCharPtr(cfVfp), '\n'); 903*5c51f124SMoriah Waterland 904*5c51f124SMoriah Waterland if (px == (char *)NULL) { 905*5c51f124SMoriah Waterland len = vfpGetBytesRemaining(cfVfp); 906*5c51f124SMoriah Waterland vfpPutBytes(cfTmpVfp, 907*5c51f124SMoriah Waterland vfpGetCurrCharPtr(cfVfp), len); 908*5c51f124SMoriah Waterland vfpPutc(cfTmpVfp, '\n'); 909*5c51f124SMoriah Waterland vfpSeekToEnd(cfVfp); 910*5c51f124SMoriah Waterland } else { 911*5c51f124SMoriah Waterland len = vfpGetCurrPtrDelta(cfVfp, px); 912*5c51f124SMoriah Waterland vfpPutBytes(cfTmpVfp, 913*5c51f124SMoriah Waterland vfpGetCurrCharPtr(cfVfp), len); 914*5c51f124SMoriah Waterland vfpIncCurrPtrBy(cfVfp, len); 915*5c51f124SMoriah Waterland } 916*5c51f124SMoriah Waterland 917*5c51f124SMoriah Waterland /* reset skiped bytes if any data skipped */ 918*5c51f124SMoriah Waterland if (dataSkipped) { 919*5c51f124SMoriah Waterland dataSkipped = 0; 920*5c51f124SMoriah Waterland lastPos = (char *)NULL; 921*5c51f124SMoriah Waterland firstPos = vfpGetCurrCharPtr(cfVfp); 922*5c51f124SMoriah Waterland } 923*5c51f124SMoriah Waterland } else { 924*5c51f124SMoriah Waterland /* skip data */ 925*5c51f124SMoriah Waterland dataSkipped = 1; 926*5c51f124SMoriah Waterland 927*5c51f124SMoriah Waterland px = strchr(vfpGetCurrCharPtr(cfVfp), '\n'); 928*5c51f124SMoriah Waterland 929*5c51f124SMoriah Waterland if (px == (char *)NULL) { 930*5c51f124SMoriah Waterland vfpSeekToEnd(cfVfp); 931*5c51f124SMoriah Waterland } else { 932*5c51f124SMoriah Waterland len = vfpGetCurrPtrDelta(cfVfp, px)+1; 933*5c51f124SMoriah Waterland vfpIncCurrPtrBy(cfVfp, len); 934*5c51f124SMoriah Waterland } 935*5c51f124SMoriah Waterland lastPos = vfpGetCurrCharPtr(cfVfp); 936*5c51f124SMoriah Waterland } 937*5c51f124SMoriah Waterland } else { 938*5c51f124SMoriah Waterland /* 939*5c51f124SMoriah Waterland * since this isn't the entry we want, just read the 940*5c51f124SMoriah Waterland * stream until we find the end of this entry and 941*5c51f124SMoriah Waterland * then start this search loop again 942*5c51f124SMoriah Waterland */ 943*5c51f124SMoriah Waterland char *px; 944*5c51f124SMoriah Waterland 945*5c51f124SMoriah Waterland px = strchr(vfpGetCurrCharPtr(cfVfp), '\n'); 946*5c51f124SMoriah Waterland 947*5c51f124SMoriah Waterland if (px == (char *)NULL) { 948*5c51f124SMoriah Waterland vfpSeekToEnd(cfVfp); 949*5c51f124SMoriah Waterland 950*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 951*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 952*5c51f124SMoriah Waterland 953*5c51f124SMoriah Waterland setErrstr(pkg_gt(ERR_MISSING_NEWLINE)); 954*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 955*5c51f124SMoriah Waterland return (-1); 956*5c51f124SMoriah Waterland } else { 957*5c51f124SMoriah Waterland ssize_t len; 958*5c51f124SMoriah Waterland 959*5c51f124SMoriah Waterland len = vfpGetCurrPtrDelta(cfVfp, px)+1; 960*5c51f124SMoriah Waterland vfpIncCurrPtrBy(cfVfp, len); 961*5c51f124SMoriah Waterland } 962*5c51f124SMoriah Waterland } 963*5c51f124SMoriah Waterland } 964*5c51f124SMoriah Waterland 965*5c51f124SMoriah Waterland /* 966*5c51f124SMoriah Waterland * ********************************************************************* 967*5c51f124SMoriah Waterland * end of main loop processing entries from contents file 968*5c51f124SMoriah Waterland * the loop is broken out of when an exact match for the 969*5c51f124SMoriah Waterland * path being searched for has been found and the type is one of: 970*5c51f124SMoriah Waterland * - ?fvelspcbdx 971*5c51f124SMoriah Waterland * at this point parsing is at the first character past the full path 972*5c51f124SMoriah Waterland * name on an exact match for the path being looked for - parse the 973*5c51f124SMoriah Waterland * remainder of the entries information into the ept structure. 974*5c51f124SMoriah Waterland * ********************************************************************* 975*5c51f124SMoriah Waterland */ 976*5c51f124SMoriah Waterland 977*5c51f124SMoriah Waterland /* link/symbolic link must have link destination */ 978*5c51f124SMoriah Waterland 979*5c51f124SMoriah Waterland if (((ept->ftype == 's') || (ept->ftype == 'l')) && 980*5c51f124SMoriah Waterland (ept->ainfo.local == NULL)) { 981*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 982*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 983*5c51f124SMoriah Waterland 984*5c51f124SMoriah Waterland setErrstr(ERR_NO_LINK_SOURCE_SPECIFIED); 985*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 986*5c51f124SMoriah Waterland return (-1); 987*5c51f124SMoriah Waterland } 988*5c51f124SMoriah Waterland 989*5c51f124SMoriah Waterland /* character/block devices have major/minor device numbers */ 990*5c51f124SMoriah Waterland 991*5c51f124SMoriah Waterland if (((ept->ftype == 'c') || (ept->ftype == 'b'))) { 992*5c51f124SMoriah Waterland ept->ainfo.major = BADMAJOR; 993*5c51f124SMoriah Waterland ept->ainfo.minor = BADMINOR; 994*5c51f124SMoriah Waterland if (getnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, 995*5c51f124SMoriah Waterland (long *)&ept->ainfo.major, BADMAJOR) || 996*5c51f124SMoriah Waterland getnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, 997*5c51f124SMoriah Waterland (long *)&ept->ainfo.minor, BADMINOR)) { 998*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 999*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1000*5c51f124SMoriah Waterland 1001*5c51f124SMoriah Waterland setErrstr(pkg_gt(ERR_CANNOT_READ_MM_NUMS)); 1002*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 1003*5c51f124SMoriah Waterland return (-1); 1004*5c51f124SMoriah Waterland } 1005*5c51f124SMoriah Waterland } 1006*5c51f124SMoriah Waterland 1007*5c51f124SMoriah Waterland /* most types have mode, owner, group identification components */ 1008*5c51f124SMoriah Waterland 1009*5c51f124SMoriah Waterland if ((ept->ftype == 'd') || (ept->ftype == 'x') || (ept->ftype == 'c') || 1010*5c51f124SMoriah Waterland (ept->ftype == 'b') || (ept->ftype == 'p') || 1011*5c51f124SMoriah Waterland (ept->ftype == 'f') || (ept->ftype == 'v') || 1012*5c51f124SMoriah Waterland (ept->ftype == 'e')) { 1013*5c51f124SMoriah Waterland /* mode, owner, group should be here */ 1014*5c51f124SMoriah Waterland if (getnumvfp(&vfpGetCurrCharPtr(cfVfp), 8, 1015*5c51f124SMoriah Waterland (long *)&ept->ainfo.mode, BADMODE) || 1016*5c51f124SMoriah Waterland getstr(&vfpGetCurrCharPtr(cfVfp), sizeof (ept->ainfo.owner), 1017*5c51f124SMoriah Waterland ept->ainfo.owner, ISWORDSEP) || 1018*5c51f124SMoriah Waterland getstr(&vfpGetCurrCharPtr(cfVfp), sizeof (ept->ainfo.group), 1019*5c51f124SMoriah Waterland ept->ainfo.group, ISWORDSEP)) { 1020*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 1021*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1022*5c51f124SMoriah Waterland 1023*5c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_MOG); 1024*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 1025*5c51f124SMoriah Waterland return (-1); 1026*5c51f124SMoriah Waterland } 1027*5c51f124SMoriah Waterland } 1028*5c51f124SMoriah Waterland 1029*5c51f124SMoriah Waterland /* i/f/v/e have size, checksum, modification time components */ 1030*5c51f124SMoriah Waterland 1031*5c51f124SMoriah Waterland if ((ept->ftype == 'i') || (ept->ftype == 'f') || 1032*5c51f124SMoriah Waterland (ept->ftype == 'v') || (ept->ftype == 'e')) { 1033*5c51f124SMoriah Waterland /* look for content description */ 1034*5c51f124SMoriah Waterland if (getlnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, 1035*5c51f124SMoriah Waterland (fsblkcnt_t *)&ept->cinfo.size, BADCONT) || 1036*5c51f124SMoriah Waterland getnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, 1037*5c51f124SMoriah Waterland (long *)&ept->cinfo.cksum, BADCONT) || 1038*5c51f124SMoriah Waterland getnumvfp(&vfpGetCurrCharPtr(cfVfp), 10, 1039*5c51f124SMoriah Waterland (long *)&ept->cinfo.modtime, BADCONT)) { 1040*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 1041*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1042*5c51f124SMoriah Waterland 1043*5c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_CONTENT_INFO); 1044*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 1045*5c51f124SMoriah Waterland return (-1); 1046*5c51f124SMoriah Waterland } 1047*5c51f124SMoriah Waterland } 1048*5c51f124SMoriah Waterland 1049*5c51f124SMoriah Waterland /* i files processing is completed - return 'exact match found' */ 1050*5c51f124SMoriah Waterland 1051*5c51f124SMoriah Waterland if (ept->ftype == 'i') { 1052*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 1053*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1054*5c51f124SMoriah Waterland 1055*5c51f124SMoriah Waterland if (getend(&vfpGetCurrCharPtr(cfVfp))) { 1056*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 1057*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1058*5c51f124SMoriah Waterland 1059*5c51f124SMoriah Waterland setErrstr(ERR_EXTRA_TOKENS); 1060*5c51f124SMoriah Waterland return (-1); 1061*5c51f124SMoriah Waterland } 1062*5c51f124SMoriah Waterland 1063*5c51f124SMoriah Waterland /* write out any skipped data before returning */ 1064*5c51f124SMoriah Waterland if (dataSkipped && (cfTmpVfp != (VFP_T *)NULL)) { 1065*5c51f124SMoriah Waterland WRITEDATA(cfTmpVfp, firstPos, lastPos); 1066*5c51f124SMoriah Waterland } 1067*5c51f124SMoriah Waterland 1068*5c51f124SMoriah Waterland return (1); 1069*5c51f124SMoriah Waterland } 1070*5c51f124SMoriah Waterland 1071*5c51f124SMoriah Waterland /* 1072*5c51f124SMoriah Waterland * determine list of packages which reference this entry 1073*5c51f124SMoriah Waterland */ 1074*5c51f124SMoriah Waterland 1075*5c51f124SMoriah Waterland lastpinfo = (struct pinfo *)NULL; 1076*5c51f124SMoriah Waterland while ((c = getstr(&vfpGetCurrCharPtr(cfVfp), sizeof (pkgname), 1077*5c51f124SMoriah Waterland pkgname, ISPKGNAMESEP)) <= 0) { 1078*5c51f124SMoriah Waterland /* if c < 0 the string was too long to fix in the buffer */ 1079*5c51f124SMoriah Waterland 1080*5c51f124SMoriah Waterland if (c < 0) { 1081*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 1082*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1083*5c51f124SMoriah Waterland 1084*5c51f124SMoriah Waterland setErrstr(ERR_PACKAGE_NAME_TOO_LONG); 1085*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 1086*5c51f124SMoriah Waterland return (-1); 1087*5c51f124SMoriah Waterland } 1088*5c51f124SMoriah Waterland 1089*5c51f124SMoriah Waterland /* a package is present - create and populate pinfo structure */ 1090*5c51f124SMoriah Waterland 1091*5c51f124SMoriah Waterland pinfo = (struct pinfo *)calloc(1, sizeof (struct pinfo)); 1092*5c51f124SMoriah Waterland if (!pinfo) { 1093*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 1094*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1095*5c51f124SMoriah Waterland 1096*5c51f124SMoriah Waterland setErrstr(ERR_NO_MEMORY); 1097*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 1098*5c51f124SMoriah Waterland return (-1); 1099*5c51f124SMoriah Waterland } 1100*5c51f124SMoriah Waterland if (!lastpinfo) { 1101*5c51f124SMoriah Waterland ept->pinfo = pinfo; /* first one */ 1102*5c51f124SMoriah Waterland } else { 1103*5c51f124SMoriah Waterland lastpinfo->next = pinfo; /* link list */ 1104*5c51f124SMoriah Waterland } 1105*5c51f124SMoriah Waterland lastpinfo = pinfo; 1106*5c51f124SMoriah Waterland 1107*5c51f124SMoriah Waterland if ((pkgname[0] == '-') || (pkgname[0] == '+') || 1108*5c51f124SMoriah Waterland (pkgname[0] == '*') || (pkgname[0] == '~') || 1109*5c51f124SMoriah Waterland (pkgname[0] == '!') || (pkgname[0] == '%')) { 1110*5c51f124SMoriah Waterland pinfo->status = pkgname[0]; 1111*5c51f124SMoriah Waterland (void) strlcpy(pinfo->pkg, pkgname+1, 1112*5c51f124SMoriah Waterland sizeof (pinfo->pkg)); 1113*5c51f124SMoriah Waterland } else { 1114*5c51f124SMoriah Waterland (void) strlcpy(pinfo->pkg, pkgname, 1115*5c51f124SMoriah Waterland sizeof (pinfo->pkg)); 1116*5c51f124SMoriah Waterland } 1117*5c51f124SMoriah Waterland 1118*5c51f124SMoriah Waterland /* pkg/[:[ftype][:class] */ 1119*5c51f124SMoriah Waterland c = (vfpGetc(cfVfp)); 1120*5c51f124SMoriah Waterland if (c == '\\') { 1121*5c51f124SMoriah Waterland /* get alternate ftype */ 1122*5c51f124SMoriah Waterland pinfo->editflag++; 1123*5c51f124SMoriah Waterland c = (vfpGetc(cfVfp)); 1124*5c51f124SMoriah Waterland } 1125*5c51f124SMoriah Waterland 1126*5c51f124SMoriah Waterland if (c == ':') { 1127*5c51f124SMoriah Waterland /* get special classname */ 1128*5c51f124SMoriah Waterland (void) getstr(&vfpGetCurrCharPtr(cfVfp), 1129*5c51f124SMoriah Waterland sizeof (classname), classname, ISWORDSEP); 1130*5c51f124SMoriah Waterland (void) strlcpy(pinfo->aclass, classname, 1131*5c51f124SMoriah Waterland sizeof (pinfo->aclass)); 1132*5c51f124SMoriah Waterland c = (vfpGetc(cfVfp)); 1133*5c51f124SMoriah Waterland } 1134*5c51f124SMoriah Waterland ept->npkgs++; 1135*5c51f124SMoriah Waterland 1136*5c51f124SMoriah Waterland /* break out of while if at end of entry */ 1137*5c51f124SMoriah Waterland 1138*5c51f124SMoriah Waterland if ((c == '\n') || (c == '\0')) { 1139*5c51f124SMoriah Waterland break; 1140*5c51f124SMoriah Waterland } 1141*5c51f124SMoriah Waterland 1142*5c51f124SMoriah Waterland /* if package not separated by a space return an error */ 1143*5c51f124SMoriah Waterland 1144*5c51f124SMoriah Waterland if (!isspace(c)) { 1145*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 1146*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1147*5c51f124SMoriah Waterland 1148*5c51f124SMoriah Waterland setErrstr(ERR_BAD_ENTRY_END); 1149*5c51f124SMoriah Waterland findend(&vfpGetCurrCharPtr(cfVfp)); 1150*5c51f124SMoriah Waterland return (-1); 1151*5c51f124SMoriah Waterland } 1152*5c51f124SMoriah Waterland } 1153*5c51f124SMoriah Waterland 1154*5c51f124SMoriah Waterland /* 1155*5c51f124SMoriah Waterland * parsing of the entry is complete 1156*5c51f124SMoriah Waterland */ 1157*5c51f124SMoriah Waterland 1158*5c51f124SMoriah Waterland /* copy path found to 'lpath' */ 1159*5c51f124SMoriah Waterland COPYPATH(lpath, cpath_start, cpath_len); 1160*5c51f124SMoriah Waterland 1161*5c51f124SMoriah Waterland /* write out any skipped data before returning */ 1162*5c51f124SMoriah Waterland if (dataSkipped && (cfTmpVfp != (VFP_T *)NULL)) { 1163*5c51f124SMoriah Waterland WRITEDATA(cfTmpVfp, firstPos, lastPos); 1164*5c51f124SMoriah Waterland } 1165*5c51f124SMoriah Waterland 1166*5c51f124SMoriah Waterland /* if not at the end of the entry, make it so */ 1167*5c51f124SMoriah Waterland 1168*5c51f124SMoriah Waterland if ((c != '\n') && (c != '\0')) { 1169*5c51f124SMoriah Waterland if (getend(&vfpGetCurrCharPtr(cfVfp)) && ept->pinfo) { 1170*5c51f124SMoriah Waterland setErrstr(ERR_EXTRA_TOKENS); 1171*5c51f124SMoriah Waterland return (-1); 1172*5c51f124SMoriah Waterland } 1173*5c51f124SMoriah Waterland } 1174*5c51f124SMoriah Waterland 1175*5c51f124SMoriah Waterland return (1); 1176*5c51f124SMoriah Waterland } 1177*5c51f124SMoriah Waterland 1178*5c51f124SMoriah Waterland static int 1179*5c51f124SMoriah Waterland getstr(char **cp, int n, char *str, int separator[]) 1180*5c51f124SMoriah Waterland { 1181*5c51f124SMoriah Waterland int c; 1182*5c51f124SMoriah Waterland char *p = *cp; 1183*5c51f124SMoriah Waterland char *p1; 1184*5c51f124SMoriah Waterland size_t len; 1185*5c51f124SMoriah Waterland 1186*5c51f124SMoriah Waterland if (*p == '\0') { 1187*5c51f124SMoriah Waterland return (1); 1188*5c51f124SMoriah Waterland } 1189*5c51f124SMoriah Waterland 1190*5c51f124SMoriah Waterland /* leading white space ignored */ 1191*5c51f124SMoriah Waterland 1192*5c51f124SMoriah Waterland while (((c = *p) != '\0') && (isspace(*p++))) 1193*5c51f124SMoriah Waterland ; 1194*5c51f124SMoriah Waterland if ((c == '\0') || (c == '\n')) { 1195*5c51f124SMoriah Waterland p--; 1196*5c51f124SMoriah Waterland *cp = p; 1197*5c51f124SMoriah Waterland return (1); /* nothing there */ 1198*5c51f124SMoriah Waterland } 1199*5c51f124SMoriah Waterland 1200*5c51f124SMoriah Waterland p--; 1201*5c51f124SMoriah Waterland 1202*5c51f124SMoriah Waterland /* compute length based on delimiter found or not */ 1203*5c51f124SMoriah Waterland 1204*5c51f124SMoriah Waterland p1 = p; 1205*5c51f124SMoriah Waterland while (separator[(int)*p1] == 0) { 1206*5c51f124SMoriah Waterland p1++; 1207*5c51f124SMoriah Waterland } 1208*5c51f124SMoriah Waterland 1209*5c51f124SMoriah Waterland len = (ptrdiff_t)p1 - (ptrdiff_t)p; 1210*5c51f124SMoriah Waterland 1211*5c51f124SMoriah Waterland /* if string will fit in result buffer copy string and return success */ 1212*5c51f124SMoriah Waterland 1213*5c51f124SMoriah Waterland if (len < n) { 1214*5c51f124SMoriah Waterland (void) memcpy(str, p, len); 1215*5c51f124SMoriah Waterland str[len] = '\0'; 1216*5c51f124SMoriah Waterland p += len; 1217*5c51f124SMoriah Waterland *cp = p; 1218*5c51f124SMoriah Waterland return (0); 1219*5c51f124SMoriah Waterland } 1220*5c51f124SMoriah Waterland 1221*5c51f124SMoriah Waterland /* result buffer too small; copy partial string, return error */ 1222*5c51f124SMoriah Waterland (void) memcpy(str, p, n-1); 1223*5c51f124SMoriah Waterland str[n-1] = '\0'; 1224*5c51f124SMoriah Waterland p += n; 1225*5c51f124SMoriah Waterland *cp = p; 1226*5c51f124SMoriah Waterland return (-1); 1227*5c51f124SMoriah Waterland } 1228*5c51f124SMoriah Waterland 1229*5c51f124SMoriah Waterland static int 1230*5c51f124SMoriah Waterland getend(char **cp) 1231*5c51f124SMoriah Waterland { 1232*5c51f124SMoriah Waterland int n; 1233*5c51f124SMoriah Waterland char *p = *cp; 1234*5c51f124SMoriah Waterland 1235*5c51f124SMoriah Waterland n = 0; 1236*5c51f124SMoriah Waterland 1237*5c51f124SMoriah Waterland /* if at end of buffer return no more characters left */ 1238*5c51f124SMoriah Waterland 1239*5c51f124SMoriah Waterland if (*p == '\0') { 1240*5c51f124SMoriah Waterland return (0); 1241*5c51f124SMoriah Waterland } 1242*5c51f124SMoriah Waterland 1243*5c51f124SMoriah Waterland while ((*p != '\0') && (*p != '\n')) { 1244*5c51f124SMoriah Waterland if (n == 0) { 1245*5c51f124SMoriah Waterland if (!isspace(*p)) { 1246*5c51f124SMoriah Waterland n++; 1247*5c51f124SMoriah Waterland } 1248*5c51f124SMoriah Waterland } 1249*5c51f124SMoriah Waterland p++; 1250*5c51f124SMoriah Waterland } 1251*5c51f124SMoriah Waterland 1252*5c51f124SMoriah Waterland *cp = ++p; 1253*5c51f124SMoriah Waterland return (n); 1254*5c51f124SMoriah Waterland } 1255*5c51f124SMoriah Waterland 1256*5c51f124SMoriah Waterland static void 1257*5c51f124SMoriah Waterland findend(char **cp) 1258*5c51f124SMoriah Waterland { 1259*5c51f124SMoriah Waterland char *p1; 1260*5c51f124SMoriah Waterland char *p = *cp; 1261*5c51f124SMoriah Waterland 1262*5c51f124SMoriah Waterland /* if at end of buffer return no more characters left */ 1263*5c51f124SMoriah Waterland 1264*5c51f124SMoriah Waterland if (*p == '\0') { 1265*5c51f124SMoriah Waterland return; 1266*5c51f124SMoriah Waterland } 1267*5c51f124SMoriah Waterland 1268*5c51f124SMoriah Waterland /* find the end of the line */ 1269*5c51f124SMoriah Waterland 1270*5c51f124SMoriah Waterland p1 = strchr(p, '\n'); 1271*5c51f124SMoriah Waterland 1272*5c51f124SMoriah Waterland if (p1 != (char *)NULL) { 1273*5c51f124SMoriah Waterland *cp = ++p1; 1274*5c51f124SMoriah Waterland return; 1275*5c51f124SMoriah Waterland } 1276*5c51f124SMoriah Waterland 1277*5c51f124SMoriah Waterland *cp = strchr(p, '\0'); 1278*5c51f124SMoriah Waterland } 1279