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
srchcfile(struct cfent * ept,char * path,PKGserver server)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
getstr(char ** cp,int n,char * str,int separator[])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
getend(char ** cp)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