15c51f124SMoriah Waterland /* 25c51f124SMoriah Waterland * CDDL HEADER START 35c51f124SMoriah Waterland * 45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 55c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 65c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 75c51f124SMoriah Waterland * 85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 105c51f124SMoriah Waterland * See the License for the specific language governing permissions 115c51f124SMoriah Waterland * and limitations under the License. 125c51f124SMoriah Waterland * 135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 185c51f124SMoriah Waterland * 195c51f124SMoriah Waterland * CDDL HEADER END 205c51f124SMoriah Waterland */ 215c51f124SMoriah Waterland 225c51f124SMoriah Waterland /* 235c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 245c51f124SMoriah Waterland * Use is subject to license terms. 255c51f124SMoriah Waterland */ 265c51f124SMoriah Waterland 275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 285c51f124SMoriah Waterland /* All Rights Reserved */ 295c51f124SMoriah Waterland 305c51f124SMoriah Waterland #include <stdio.h> 315c51f124SMoriah Waterland #include <limits.h> 325c51f124SMoriah Waterland #include <stdlib.h> 335c51f124SMoriah Waterland #include <string.h> 345c51f124SMoriah Waterland #include <strings.h> 355c51f124SMoriah Waterland #include <ctype.h> 365c51f124SMoriah Waterland #include <sys/types.h> 375c51f124SMoriah Waterland #include <libintl.h> 385c51f124SMoriah Waterland #include "pkglib.h" 395c51f124SMoriah Waterland #include "pkgstrct.h" 405c51f124SMoriah Waterland #include "pkglocale.h" 415c51f124SMoriah Waterland #include "pkglibmsgs.h" 425c51f124SMoriah Waterland 435c51f124SMoriah Waterland /* 445c51f124SMoriah Waterland * Forward declarations 455c51f124SMoriah Waterland */ 465c51f124SMoriah Waterland 475c51f124SMoriah Waterland static int getend(char **cp); 485c51f124SMoriah Waterland static int getstr(char **cp, int n, char *str, int separator[]); 495c51f124SMoriah Waterland 505c51f124SMoriah Waterland /* from gpkgmap.c */ 515c51f124SMoriah Waterland int getnumvfp(char **cp, int base, long *d, long bad); 525c51f124SMoriah Waterland int getlnumvfp(char **cp, int base, fsblkcnt_t *d, long bad); 535c51f124SMoriah Waterland 545c51f124SMoriah Waterland /* 555c51f124SMoriah Waterland * Module globals 565c51f124SMoriah Waterland */ 575c51f124SMoriah Waterland 585c51f124SMoriah Waterland static char lpath[PATH_MAX]; /* for ept->path */ 595c51f124SMoriah Waterland static char mylocal[PATH_MAX]; /* for ept->ainfo.local */ 605c51f124SMoriah Waterland static int decisionTableInit = 0; 615c51f124SMoriah Waterland 625c51f124SMoriah Waterland /* 635c51f124SMoriah Waterland * These arrays must be indexable by an unsigned char. 645c51f124SMoriah Waterland */ 655c51f124SMoriah Waterland 665c51f124SMoriah Waterland static int ISWORDSEP[UCHAR_MAX+1]; 675c51f124SMoriah Waterland static int ISPKGNAMESEP[UCHAR_MAX+1]; 685c51f124SMoriah Waterland 695c51f124SMoriah Waterland /* 705c51f124SMoriah Waterland * Name: COPYPATH 715c51f124SMoriah Waterland * Description: copy path limiting size to destination capacity 725c51f124SMoriah Waterland * Arguments: DEST - (char []) - [RW] 735c51f124SMoriah Waterland * SRC - (char *) - [RO, *RO] 745c51f124SMoriah Waterland * Pointer to first byte of path to copy 755c51f124SMoriah Waterland * LEN - (int) - [RO] 765c51f124SMoriah Waterland * Number of bytes to copy 775c51f124SMoriah Waterland */ 785c51f124SMoriah Waterland 795c51f124SMoriah Waterland #define COPYPATH(DEST, SRC, LEN) \ 805c51f124SMoriah Waterland { \ 815c51f124SMoriah Waterland /* assure return path does not overflow */ \ 825c51f124SMoriah Waterland if ((LEN) > sizeof ((DEST))) { \ 835c51f124SMoriah Waterland (LEN) = sizeof ((DEST))-1; \ 845c51f124SMoriah Waterland } \ 855c51f124SMoriah Waterland /* copy return path to local storage */ \ 865c51f124SMoriah Waterland (void) memcpy((DEST), (SRC), (LEN)); \ 875c51f124SMoriah Waterland (DEST)[(LEN)] = '\0'; \ 885c51f124SMoriah Waterland } 895c51f124SMoriah Waterland 905c51f124SMoriah Waterland /* 915c51f124SMoriah Waterland * Name: srchcfile 925c51f124SMoriah Waterland * Description: search contents file looking for closest match to entry, 935c51f124SMoriah Waterland * creating a new contents file if output contents file specified 945c51f124SMoriah Waterland * Arguments: ept - (struct cfent *) - [RO, *RW] 955c51f124SMoriah Waterland * - contents file entry, describing last item found 965c51f124SMoriah Waterland * path - (char *) - [RO, *RO] 975c51f124SMoriah Waterland * - path to search for in contents file 985c51f124SMoriah Waterland * - If path is "*", then the next entry is returned; 995c51f124SMoriah Waterland * the next entry always matches this path 100*62224350SCasper H.S. Dik * PKGserver 101*62224350SCasper H.S. Dik * - our door to the database server. 102*62224350SCasper H.S. Dik * 1035c51f124SMoriah Waterland * Returns: int 1045c51f124SMoriah Waterland * < 0 - error occurred 1055c51f124SMoriah Waterland * - Use getErrstr to retrieve character-string describing 1065c51f124SMoriah Waterland * the reason for failure 1075c51f124SMoriah Waterland * == 0 - no match found 1085c51f124SMoriah Waterland * - specified path not in the contents file 1095c51f124SMoriah Waterland * == 1 - exact match found 1105c51f124SMoriah Waterland * - specified path found in contents file 1115c51f124SMoriah Waterland * - this value is always returned if path is "*" and the 112*62224350SCasper H.S. Dik * next entry is returned - 0 is returned when no more 1135c51f124SMoriah Waterland * entries are left to process 1145c51f124SMoriah Waterland * Side Effects: 1155c51f124SMoriah Waterland * - The ept structure supplied is filled in with a description of 1165c51f124SMoriah Waterland * the item that caused the search to terminate, except in the 1175c51f124SMoriah Waterland * case of '0' in which case the contents of 'ept' is undefined. 1185c51f124SMoriah Waterland * - NOTE: the ept->path item points to a path that is statically 1195c51f124SMoriah Waterland * allocated and will be overwritten on the next call. 1205c51f124SMoriah Waterland * - NOTE: the ept->ainfo.local item points to a path that is 1215c51f124SMoriah Waterland * statically allocated and will be overwritten on the next call. 1225c51f124SMoriah Waterland */ 1235c51f124SMoriah Waterland 1245c51f124SMoriah Waterland int 125*62224350SCasper H.S. Dik srchcfile(struct cfent *ept, char *path, PKGserver server) 1265c51f124SMoriah Waterland { 127*62224350SCasper H.S. Dik char *cpath_start = NULL; 1285c51f124SMoriah Waterland char classname[CLSSIZ+1]; 1295c51f124SMoriah Waterland char pkgname[PKGSIZ+1]; 1305c51f124SMoriah Waterland int anypath = 0; 1315c51f124SMoriah Waterland int c; 132*62224350SCasper H.S. Dik int cpath_len = 0; 1335c51f124SMoriah Waterland struct pinfo *lastpinfo; 1345c51f124SMoriah Waterland struct pinfo *pinfo; 135*62224350SCasper H.S. Dik char *p; 136*62224350SCasper H.S. Dik char *curbuf; 137*62224350SCasper H.S. Dik int linelen; /* includes NUL */ 1385c51f124SMoriah Waterland 1395c51f124SMoriah Waterland /* 1405c51f124SMoriah Waterland * this code does not use nested subroutines because execution time 1415c51f124SMoriah Waterland * of this routine is especially critical to installation and upgrade 1425c51f124SMoriah Waterland */ 1435c51f124SMoriah Waterland 1445c51f124SMoriah Waterland /* initialize local variables */ 1455c51f124SMoriah Waterland 1465c51f124SMoriah Waterland setErrstr(NULL); /* no error message currently cached */ 1475c51f124SMoriah Waterland lpath[0] = '\0'; 1485c51f124SMoriah Waterland lpath[sizeof (lpath)-1] = '\0'; 1495c51f124SMoriah Waterland 1505c51f124SMoriah Waterland /* initialize ept structure values */ 1515c51f124SMoriah Waterland 1525c51f124SMoriah Waterland (void) strlcpy(ept->ainfo.group, BADGROUP, sizeof (ept->ainfo.group)); 1535c51f124SMoriah Waterland (void) strlcpy(ept->ainfo.owner, BADOWNER, sizeof (ept->ainfo.owner)); 1545c51f124SMoriah Waterland (void) strlcpy(ept->pkg_class, BADCLASS, sizeof (ept->pkg_class)); 1555c51f124SMoriah Waterland ept->ainfo.local = (char *)NULL; 1565c51f124SMoriah Waterland ept->ainfo.mode = BADMODE; 1575c51f124SMoriah Waterland ept->cinfo.cksum = BADCONT; 1585c51f124SMoriah Waterland ept->cinfo.modtime = BADCONT; 1595c51f124SMoriah Waterland ept->cinfo.size = (fsblkcnt_t)BADCONT; 1605c51f124SMoriah Waterland ept->ftype = BADFTYPE; 1615c51f124SMoriah Waterland ept->npkgs = 0; 1625c51f124SMoriah Waterland ept->path = (char *)NULL; 1635c51f124SMoriah Waterland ept->pinfo = (struct pinfo *)NULL; 1645c51f124SMoriah Waterland ept->pkg_class_idx = -1; 1655c51f124SMoriah Waterland ept->volno = 0; 1665c51f124SMoriah Waterland 1675c51f124SMoriah Waterland /* 1685c51f124SMoriah Waterland * populate decision tables that implement fast character checking; 1695c51f124SMoriah Waterland * this is much faster than the equivalent strpbrk() call or a 1705c51f124SMoriah Waterland * while() loop checking for the characters. It is only faster if 1715c51f124SMoriah Waterland * there are at least 3 characters to scan for - when checking for 1725c51f124SMoriah Waterland * one or two characters (such as '\n' or '\0') its faster to do 1735c51f124SMoriah Waterland * a simple while() loop. 1745c51f124SMoriah Waterland */ 1755c51f124SMoriah Waterland 1765c51f124SMoriah Waterland if (decisionTableInit == 0) { 1775c51f124SMoriah Waterland /* 1785c51f124SMoriah Waterland * any chars listed stop scan; 1795c51f124SMoriah Waterland * scan stops on first byte found that is set to '1' below 1805c51f124SMoriah Waterland */ 1815c51f124SMoriah Waterland 1825c51f124SMoriah Waterland /* 1835c51f124SMoriah Waterland * Separators for normal words 1845c51f124SMoriah Waterland */ 1855c51f124SMoriah Waterland bzero(ISWORDSEP, sizeof (ISWORDSEP)); 1865c51f124SMoriah Waterland ISWORDSEP[' '] = 1; 1875c51f124SMoriah Waterland ISWORDSEP['\t'] = 1; 1885c51f124SMoriah Waterland ISWORDSEP['\n'] = 1; 1895c51f124SMoriah Waterland ISWORDSEP['\0'] = 1; 1905c51f124SMoriah Waterland 1915c51f124SMoriah Waterland /* 1925c51f124SMoriah Waterland * Separators for list of packages, includes \\ for 1935c51f124SMoriah Waterland * alternate ftype and : for classname 1945c51f124SMoriah Waterland */ 1955c51f124SMoriah Waterland bzero(ISPKGNAMESEP, sizeof (ISPKGNAMESEP)); 1965c51f124SMoriah Waterland ISPKGNAMESEP[' '] = 1; 1975c51f124SMoriah Waterland ISPKGNAMESEP['\t'] = 1; 1985c51f124SMoriah Waterland ISPKGNAMESEP['\n'] = 1; 1995c51f124SMoriah Waterland ISPKGNAMESEP[':'] = 1; 2005c51f124SMoriah Waterland ISPKGNAMESEP['\\'] = 1; 2015c51f124SMoriah Waterland ISPKGNAMESEP['\0'] = 1; 2025c51f124SMoriah Waterland 2035c51f124SMoriah Waterland decisionTableInit = 1; 2045c51f124SMoriah Waterland } 2055c51f124SMoriah Waterland 2065c51f124SMoriah Waterland /* if the path to scan for is empty, act like no path was specified */ 2075c51f124SMoriah Waterland 208*62224350SCasper H.S. Dik if ((path != NULL) && (*path == '\0')) { 209*62224350SCasper H.S. Dik path = NULL; 2105c51f124SMoriah Waterland } 2115c51f124SMoriah Waterland 2125c51f124SMoriah Waterland /* 2135c51f124SMoriah Waterland * if path to search for is "*", then we will return the first path 2145c51f124SMoriah Waterland * we encounter as a match, otherwise we return an error 2155c51f124SMoriah Waterland */ 2165c51f124SMoriah Waterland 217*62224350SCasper H.S. Dik if ((path != NULL) && (path[0] != '/')) { 2185c51f124SMoriah Waterland if (strcmp(path, "*") != 0) { 2195c51f124SMoriah Waterland setErrstr(pkg_gt(ERR_ILLEGAL_SEARCH_PATH)); 2205c51f124SMoriah Waterland return (-1); 2215c51f124SMoriah Waterland } 2225c51f124SMoriah Waterland anypath = 1; 2235c51f124SMoriah Waterland } 2245c51f124SMoriah Waterland 2255c51f124SMoriah Waterland /* attempt to narrow down the search for the specified path */ 2265c51f124SMoriah Waterland 227*62224350SCasper H.S. Dik if (anypath == 0 && path == NULL) 2285c51f124SMoriah Waterland return (0); 2295c51f124SMoriah Waterland 2305c51f124SMoriah Waterland /* determine first character of the next entry */ 231*62224350SCasper H.S. Dik if (anypath == 0) 232*62224350SCasper H.S. Dik curbuf = pkggetentry_named(server, path, &linelen, &cpath_len); 233*62224350SCasper H.S. Dik else 234*62224350SCasper H.S. Dik curbuf = pkggetentry(server, &linelen, &cpath_len); 2355c51f124SMoriah Waterland 236*62224350SCasper H.S. Dik if (curbuf == NULL) 237*62224350SCasper H.S. Dik return (0); 2385c51f124SMoriah Waterland 2395c51f124SMoriah Waterland /* 2405c51f124SMoriah Waterland * current entry DOES start with absolute path 2415c51f124SMoriah Waterland * set ept->path to point to lpath 2425c51f124SMoriah Waterland * set cpath_start/cpath_len to point to the file name 2435c51f124SMoriah Waterland */ 244*62224350SCasper H.S. Dik 2455c51f124SMoriah Waterland /* copy first token into path element of passed structure */ 2465c51f124SMoriah Waterland 247*62224350SCasper H.S. Dik cpath_start = curbuf; 2485c51f124SMoriah Waterland 249*62224350SCasper H.S. Dik p = cpath_start + cpath_len; 2505c51f124SMoriah Waterland 2515c51f124SMoriah Waterland ept->path = lpath; 2525c51f124SMoriah Waterland 253*62224350SCasper H.S. Dik /* copy path found to 'lpath' */ 254*62224350SCasper H.S. Dik COPYPATH(lpath, cpath_start, cpath_len); 2555c51f124SMoriah Waterland 2565c51f124SMoriah Waterland /* get first character following the end of the path */ 2575c51f124SMoriah Waterland 258*62224350SCasper H.S. Dik c = *p++; 2595c51f124SMoriah Waterland 2605c51f124SMoriah Waterland /* 2615c51f124SMoriah Waterland * we want to return information about this path in 2625c51f124SMoriah Waterland * the structure provided, so parse any local path 2635c51f124SMoriah Waterland * and jump to code which parses rest of the input line 2645c51f124SMoriah Waterland */ 2655c51f124SMoriah Waterland if (c == '=') { 2665c51f124SMoriah Waterland /* parse local path specification */ 267*62224350SCasper H.S. Dik if (getstr(&p, PATH_MAX, mylocal, ISWORDSEP)) { 2685c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_LL_PATH); 2695c51f124SMoriah Waterland return (-1); 2705c51f124SMoriah Waterland } 2715c51f124SMoriah Waterland ept->ainfo.local = mylocal; 2725c51f124SMoriah Waterland } 2735c51f124SMoriah Waterland 2745c51f124SMoriah Waterland /* 2755c51f124SMoriah Waterland * if an exact match and processing a new style entry, read the 276*62224350SCasper H.S. Dik * remaining information from the new style entry. 2775c51f124SMoriah Waterland */ 2785c51f124SMoriah Waterland 279*62224350SCasper H.S. Dik while (isspace((c = *p++))) 2805c51f124SMoriah Waterland ; 2815c51f124SMoriah Waterland 2825c51f124SMoriah Waterland switch (c) { 2835c51f124SMoriah Waterland case '?': case 'f': case 'v': case 'e': case 'l': 2845c51f124SMoriah Waterland case 's': case 'p': case 'c': case 'b': case 'd': 2855c51f124SMoriah Waterland case 'x': 2865c51f124SMoriah Waterland /* save ftype */ 2875c51f124SMoriah Waterland ept->ftype = (char)c; 2885c51f124SMoriah Waterland 2895c51f124SMoriah Waterland /* save class */ 290*62224350SCasper H.S. Dik if (getstr(&p, CLSSIZ, ept->pkg_class, ISWORDSEP)) { 2915c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_CLASS_TOKEN); 2925c51f124SMoriah Waterland return (-1); 2935c51f124SMoriah Waterland } 2945c51f124SMoriah Waterland break; /* we already read the pathname */ 2955c51f124SMoriah Waterland 2965c51f124SMoriah Waterland case '\0': 2975c51f124SMoriah Waterland /* end of line before new-line seen */ 2985c51f124SMoriah Waterland setErrstr(ERR_INCOMPLETE_ENTRY); 2995c51f124SMoriah Waterland return (-1); 3005c51f124SMoriah Waterland 3015c51f124SMoriah Waterland case '0': case '1': case '2': case '3': case '4': 3025c51f124SMoriah Waterland case '5': case '6': case '7': case '8': case '9': 3035c51f124SMoriah Waterland setErrstr(ERR_VOLUMENO_UNEXPECTED); 3045c51f124SMoriah Waterland return (-1); 3055c51f124SMoriah Waterland 3065c51f124SMoriah Waterland case 'i': 3075c51f124SMoriah Waterland setErrstr(ERR_FTYPE_I_UNEXPECTED); 3085c51f124SMoriah Waterland return (-1); 3095c51f124SMoriah Waterland 3105c51f124SMoriah Waterland default: 3115c51f124SMoriah Waterland /* unknown ftype */ 3125c51f124SMoriah Waterland setErrstr(ERR_UNKNOWN_FTYPE); 3135c51f124SMoriah Waterland return (-1); 3145c51f124SMoriah Waterland } 3155c51f124SMoriah Waterland 3165c51f124SMoriah Waterland /* link/symbolic link must have link destination */ 3175c51f124SMoriah Waterland 3185c51f124SMoriah Waterland if (((ept->ftype == 's') || (ept->ftype == 'l')) && 3195c51f124SMoriah Waterland (ept->ainfo.local == NULL)) { 3205c51f124SMoriah Waterland setErrstr(ERR_NO_LINK_SOURCE_SPECIFIED); 3215c51f124SMoriah Waterland return (-1); 3225c51f124SMoriah Waterland } 3235c51f124SMoriah Waterland 3245c51f124SMoriah Waterland /* character/block devices have major/minor device numbers */ 3255c51f124SMoriah Waterland 3265c51f124SMoriah Waterland if (((ept->ftype == 'c') || (ept->ftype == 'b'))) { 3275c51f124SMoriah Waterland ept->ainfo.major = BADMAJOR; 3285c51f124SMoriah Waterland ept->ainfo.minor = BADMINOR; 329*62224350SCasper H.S. Dik if (getnumvfp(&p, 10, (long *)&ept->ainfo.major, BADMAJOR) || 330*62224350SCasper H.S. Dik getnumvfp(&p, 10, (long *)&ept->ainfo.minor, BADMINOR)) { 3315c51f124SMoriah Waterland setErrstr(pkg_gt(ERR_CANNOT_READ_MM_NUMS)); 3325c51f124SMoriah Waterland return (-1); 3335c51f124SMoriah Waterland } 3345c51f124SMoriah Waterland } 3355c51f124SMoriah Waterland 3365c51f124SMoriah Waterland /* most types have mode, owner, group identification components */ 3375c51f124SMoriah Waterland 3385c51f124SMoriah Waterland if ((ept->ftype == 'd') || (ept->ftype == 'x') || (ept->ftype == 'c') || 3395c51f124SMoriah Waterland (ept->ftype == 'b') || (ept->ftype == 'p') || 3405c51f124SMoriah Waterland (ept->ftype == 'f') || (ept->ftype == 'v') || 3415c51f124SMoriah Waterland (ept->ftype == 'e')) { 3425c51f124SMoriah Waterland /* mode, owner, group should be here */ 343*62224350SCasper H.S. Dik if (getnumvfp(&p, 8, (long *)&ept->ainfo.mode, BADMODE) || 344*62224350SCasper H.S. Dik getstr(&p, sizeof (ept->ainfo.owner), ept->ainfo.owner, 345*62224350SCasper H.S. Dik ISWORDSEP) || 346*62224350SCasper H.S. Dik getstr(&p, sizeof (ept->ainfo.group), ept->ainfo.group, 347*62224350SCasper H.S. Dik ISWORDSEP)) { 3485c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_MOG); 3495c51f124SMoriah Waterland return (-1); 3505c51f124SMoriah Waterland } 3515c51f124SMoriah Waterland } 3525c51f124SMoriah Waterland 3535c51f124SMoriah Waterland /* i/f/v/e have size, checksum, modification time components */ 3545c51f124SMoriah Waterland 3555c51f124SMoriah Waterland if ((ept->ftype == 'i') || (ept->ftype == 'f') || 3565c51f124SMoriah Waterland (ept->ftype == 'v') || (ept->ftype == 'e')) { 3575c51f124SMoriah Waterland /* look for content description */ 358*62224350SCasper H.S. Dik if (getlnumvfp(&p, 10, (fsblkcnt_t *)&ept->cinfo.size, 359*62224350SCasper H.S. Dik BADCONT) || 360*62224350SCasper H.S. Dik getnumvfp(&p, 10, (long *)&ept->cinfo.cksum, BADCONT) || 361*62224350SCasper H.S. Dik getnumvfp(&p, 10, (long *)&ept->cinfo.modtime, BADCONT)) { 3625c51f124SMoriah Waterland setErrstr(ERR_CANNOT_READ_CONTENT_INFO); 3635c51f124SMoriah Waterland return (-1); 3645c51f124SMoriah Waterland } 3655c51f124SMoriah Waterland } 3665c51f124SMoriah Waterland 3675c51f124SMoriah Waterland /* i files processing is completed - return 'exact match found' */ 3685c51f124SMoriah Waterland 3695c51f124SMoriah Waterland if (ept->ftype == 'i') { 3705c51f124SMoriah Waterland return (1); 3715c51f124SMoriah Waterland } 3725c51f124SMoriah Waterland 3735c51f124SMoriah Waterland /* 3745c51f124SMoriah Waterland * determine list of packages which reference this entry 3755c51f124SMoriah Waterland */ 3765c51f124SMoriah Waterland 3775c51f124SMoriah Waterland lastpinfo = (struct pinfo *)NULL; 378*62224350SCasper H.S. Dik while ((c = getstr(&p, sizeof (pkgname), pkgname, ISPKGNAMESEP)) <= 0) { 3795c51f124SMoriah Waterland /* if c < 0 the string was too long to fix in the buffer */ 3805c51f124SMoriah Waterland 3815c51f124SMoriah Waterland if (c < 0) { 3825c51f124SMoriah Waterland setErrstr(ERR_PACKAGE_NAME_TOO_LONG); 3835c51f124SMoriah Waterland return (-1); 3845c51f124SMoriah Waterland } 3855c51f124SMoriah Waterland 3865c51f124SMoriah Waterland /* a package is present - create and populate pinfo structure */ 3875c51f124SMoriah Waterland 3885c51f124SMoriah Waterland pinfo = (struct pinfo *)calloc(1, sizeof (struct pinfo)); 3895c51f124SMoriah Waterland if (!pinfo) { 3905c51f124SMoriah Waterland setErrstr(ERR_NO_MEMORY); 3915c51f124SMoriah Waterland return (-1); 3925c51f124SMoriah Waterland } 3935c51f124SMoriah Waterland if (!lastpinfo) { 3945c51f124SMoriah Waterland ept->pinfo = pinfo; /* first one */ 3955c51f124SMoriah Waterland } else { 3965c51f124SMoriah Waterland lastpinfo->next = pinfo; /* link list */ 3975c51f124SMoriah Waterland } 3985c51f124SMoriah Waterland lastpinfo = pinfo; 3995c51f124SMoriah Waterland 4005c51f124SMoriah Waterland if ((pkgname[0] == '-') || (pkgname[0] == '+') || 4015c51f124SMoriah Waterland (pkgname[0] == '*') || (pkgname[0] == '~') || 4025c51f124SMoriah Waterland (pkgname[0] == '!') || (pkgname[0] == '%')) { 4035c51f124SMoriah Waterland pinfo->status = pkgname[0]; 4045c51f124SMoriah Waterland (void) strlcpy(pinfo->pkg, pkgname+1, 4055c51f124SMoriah Waterland sizeof (pinfo->pkg)); 4065c51f124SMoriah Waterland } else { 4075c51f124SMoriah Waterland (void) strlcpy(pinfo->pkg, pkgname, 4085c51f124SMoriah Waterland sizeof (pinfo->pkg)); 4095c51f124SMoriah Waterland } 4105c51f124SMoriah Waterland 4115c51f124SMoriah Waterland /* pkg/[:[ftype][:class] */ 412*62224350SCasper H.S. Dik c = *p++; 4135c51f124SMoriah Waterland if (c == '\\') { 4145c51f124SMoriah Waterland /* get alternate ftype */ 4155c51f124SMoriah Waterland pinfo->editflag++; 416*62224350SCasper H.S. Dik c = *p++; 4175c51f124SMoriah Waterland } 4185c51f124SMoriah Waterland 4195c51f124SMoriah Waterland if (c == ':') { 4205c51f124SMoriah Waterland /* get special classname */ 421*62224350SCasper H.S. Dik (void) getstr(&p, sizeof (classname), classname, 422*62224350SCasper H.S. Dik ISWORDSEP); 4235c51f124SMoriah Waterland (void) strlcpy(pinfo->aclass, classname, 4245c51f124SMoriah Waterland sizeof (pinfo->aclass)); 425*62224350SCasper H.S. Dik c = *p++; 4265c51f124SMoriah Waterland } 4275c51f124SMoriah Waterland ept->npkgs++; 4285c51f124SMoriah Waterland 4295c51f124SMoriah Waterland /* break out of while if at end of entry */ 4305c51f124SMoriah Waterland 4315c51f124SMoriah Waterland if ((c == '\n') || (c == '\0')) { 4325c51f124SMoriah Waterland break; 4335c51f124SMoriah Waterland } 4345c51f124SMoriah Waterland 4355c51f124SMoriah Waterland /* if package not separated by a space return an error */ 4365c51f124SMoriah Waterland 4375c51f124SMoriah Waterland if (!isspace(c)) { 4385c51f124SMoriah Waterland setErrstr(ERR_BAD_ENTRY_END); 4395c51f124SMoriah Waterland return (-1); 4405c51f124SMoriah Waterland } 4415c51f124SMoriah Waterland } 4425c51f124SMoriah Waterland 4435c51f124SMoriah Waterland /* 4445c51f124SMoriah Waterland * parsing of the entry is complete 4455c51f124SMoriah Waterland */ 4465c51f124SMoriah Waterland 4475c51f124SMoriah Waterland /* if not at the end of the entry, make it so */ 4485c51f124SMoriah Waterland 4495c51f124SMoriah Waterland if ((c != '\n') && (c != '\0')) { 450*62224350SCasper H.S. Dik if (getend(&p) && ept->pinfo) { 4515c51f124SMoriah Waterland setErrstr(ERR_EXTRA_TOKENS); 4525c51f124SMoriah Waterland return (-1); 4535c51f124SMoriah Waterland } 4545c51f124SMoriah Waterland } 4555c51f124SMoriah Waterland 4565c51f124SMoriah Waterland return (1); 4575c51f124SMoriah Waterland } 4585c51f124SMoriah Waterland 4595c51f124SMoriah Waterland static int 4605c51f124SMoriah Waterland getstr(char **cp, int n, char *str, int separator[]) 4615c51f124SMoriah Waterland { 4625c51f124SMoriah Waterland int c; 4635c51f124SMoriah Waterland char *p = *cp; 4645c51f124SMoriah Waterland char *p1; 4655c51f124SMoriah Waterland size_t len; 4665c51f124SMoriah Waterland 4675c51f124SMoriah Waterland if (*p == '\0') { 4685c51f124SMoriah Waterland return (1); 4695c51f124SMoriah Waterland } 4705c51f124SMoriah Waterland 4715c51f124SMoriah Waterland /* leading white space ignored */ 4725c51f124SMoriah Waterland 4735c51f124SMoriah Waterland while (((c = *p) != '\0') && (isspace(*p++))) 4745c51f124SMoriah Waterland ; 4755c51f124SMoriah Waterland if ((c == '\0') || (c == '\n')) { 4765c51f124SMoriah Waterland p--; 4775c51f124SMoriah Waterland *cp = p; 4785c51f124SMoriah Waterland return (1); /* nothing there */ 4795c51f124SMoriah Waterland } 4805c51f124SMoriah Waterland 4815c51f124SMoriah Waterland p--; 4825c51f124SMoriah Waterland 4835c51f124SMoriah Waterland /* compute length based on delimiter found or not */ 4845c51f124SMoriah Waterland 4855c51f124SMoriah Waterland p1 = p; 486*62224350SCasper H.S. Dik while (separator[(int)(*(unsigned char *)p1)] == 0) { 4875c51f124SMoriah Waterland p1++; 4885c51f124SMoriah Waterland } 4895c51f124SMoriah Waterland 4905c51f124SMoriah Waterland len = (ptrdiff_t)p1 - (ptrdiff_t)p; 4915c51f124SMoriah Waterland 4925c51f124SMoriah Waterland /* if string will fit in result buffer copy string and return success */ 4935c51f124SMoriah Waterland 4945c51f124SMoriah Waterland if (len < n) { 4955c51f124SMoriah Waterland (void) memcpy(str, p, len); 4965c51f124SMoriah Waterland str[len] = '\0'; 4975c51f124SMoriah Waterland p += len; 4985c51f124SMoriah Waterland *cp = p; 4995c51f124SMoriah Waterland return (0); 5005c51f124SMoriah Waterland } 5015c51f124SMoriah Waterland 5025c51f124SMoriah Waterland /* result buffer too small; copy partial string, return error */ 5035c51f124SMoriah Waterland (void) memcpy(str, p, n-1); 5045c51f124SMoriah Waterland str[n-1] = '\0'; 5055c51f124SMoriah Waterland p += n; 5065c51f124SMoriah Waterland *cp = p; 5075c51f124SMoriah Waterland return (-1); 5085c51f124SMoriah Waterland } 5095c51f124SMoriah Waterland 5105c51f124SMoriah Waterland static int 5115c51f124SMoriah Waterland getend(char **cp) 5125c51f124SMoriah Waterland { 5135c51f124SMoriah Waterland int n; 5145c51f124SMoriah Waterland char *p = *cp; 5155c51f124SMoriah Waterland 5165c51f124SMoriah Waterland n = 0; 5175c51f124SMoriah Waterland 5185c51f124SMoriah Waterland /* if at end of buffer return no more characters left */ 5195c51f124SMoriah Waterland 5205c51f124SMoriah Waterland if (*p == '\0') { 5215c51f124SMoriah Waterland return (0); 5225c51f124SMoriah Waterland } 5235c51f124SMoriah Waterland 5245c51f124SMoriah Waterland while ((*p != '\0') && (*p != '\n')) { 5255c51f124SMoriah Waterland if (n == 0) { 5265c51f124SMoriah Waterland if (!isspace(*p)) { 5275c51f124SMoriah Waterland n++; 5285c51f124SMoriah Waterland } 5295c51f124SMoriah Waterland } 5305c51f124SMoriah Waterland p++; 5315c51f124SMoriah Waterland } 5325c51f124SMoriah Waterland 5335c51f124SMoriah Waterland *cp = ++p; 5345c51f124SMoriah Waterland return (n); 5355c51f124SMoriah Waterland } 536