xref: /titanic_50/usr/src/cmd/svr4pkg/pkgchk/checkmap.c (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
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 2006 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 #include <stdio.h>
32*5c51f124SMoriah Waterland #include <string.h>
33*5c51f124SMoriah Waterland #include <limits.h>
34*5c51f124SMoriah Waterland #include <errno.h>
35*5c51f124SMoriah Waterland #include <stdlib.h>
36*5c51f124SMoriah Waterland #include <unistd.h>
37*5c51f124SMoriah Waterland #include <dirent.h>
38*5c51f124SMoriah Waterland #include <sys/types.h>
39*5c51f124SMoriah Waterland #include <sys/stat.h>
40*5c51f124SMoriah Waterland #include <sys/param.h>
41*5c51f124SMoriah Waterland #include <sys/mman.h>
42*5c51f124SMoriah Waterland #include <pkgstrct.h>
43*5c51f124SMoriah Waterland #include <pkglocs.h>
44*5c51f124SMoriah Waterland #include <locale.h>
45*5c51f124SMoriah Waterland #include <libintl.h>
46*5c51f124SMoriah Waterland #include <pkglib.h>
47*5c51f124SMoriah Waterland #include "libadm.h"
48*5c51f124SMoriah Waterland #include "libinst.h"
49*5c51f124SMoriah Waterland 
50*5c51f124SMoriah Waterland extern int	qflag, lflag, Lflag, pkgcnt;
51*5c51f124SMoriah Waterland extern short	npaths;
52*5c51f124SMoriah Waterland 
53*5c51f124SMoriah Waterland extern char	*basedir, *pathlist[], *ppathlist[], **pkg, **environ;
54*5c51f124SMoriah Waterland 
55*5c51f124SMoriah Waterland extern short	used[];
56*5c51f124SMoriah Waterland extern struct cfent **eptlist;
57*5c51f124SMoriah Waterland 
58*5c51f124SMoriah Waterland /* ocfile.c */
59*5c51f124SMoriah Waterland extern int	socfile(VFP_T **vfp);	/* simple open & lock of DB. */
60*5c51f124SMoriah Waterland extern int	relslock(void);		/* unlock the database. */
61*5c51f124SMoriah Waterland 
62*5c51f124SMoriah Waterland /* ckentry.c */
63*5c51f124SMoriah Waterland extern int	ckentry(int envflag, int maptyp, struct cfent *ept, VFP_T *vfp);
64*5c51f124SMoriah Waterland 
65*5c51f124SMoriah Waterland #define	NXTENTRY(P, VFP) \
66*5c51f124SMoriah Waterland 		(maptyp ? srchcfile((P), "*", (VFP), (VFP_T *)NULL) : \
67*5c51f124SMoriah Waterland 		gpkgmapvfp((P), (VFP)))
68*5c51f124SMoriah Waterland 
69*5c51f124SMoriah Waterland #define	MSG_ARCHIVE	"NOTE: some pathnames are in private formats " \
70*5c51f124SMoriah Waterland 			    "and cannot be verified"
71*5c51f124SMoriah Waterland #define	WRN_NOPKG	"WARNING: no pathnames were associated with <%s>"
72*5c51f124SMoriah Waterland #define	WRN_NOPATH	"WARNING: no information associated with pathname <%s>"
73*5c51f124SMoriah Waterland #define	EMPTY_PKG "WARNING: Package <%s> is installed but empty"
74*5c51f124SMoriah Waterland #define	ERR_NOMEM	"unable to allocate dynamic memory, errno=%d"
75*5c51f124SMoriah Waterland #define	ERR_PKGMAP	"unable to open pkgmap file <%s>"
76*5c51f124SMoriah Waterland #define	ERR_ENVFILE	"unable to open environment file <%s>"
77*5c51f124SMoriah Waterland 
78*5c51f124SMoriah Waterland static struct cfent entry;
79*5c51f124SMoriah Waterland 
80*5c51f124SMoriah Waterland static int	shellmatch(char *, char *);
81*5c51f124SMoriah Waterland static int is_partial_path_in_DB(char *, char *);
82*5c51f124SMoriah Waterland 
83*5c51f124SMoriah Waterland int	selpath(char *, int);
84*5c51f124SMoriah Waterland int	selpkg(char *);
85*5c51f124SMoriah Waterland 
86*5c51f124SMoriah Waterland /*
87*5c51f124SMoriah Waterland  * This routine checks all files which are referenced in the pkgmap which is
88*5c51f124SMoriah Waterland  * identified by the mapfile arg. When the package is installed, the mapfile
89*5c51f124SMoriah Waterland  * may be the contents file or a separate pkgmap (maptyp tells the function
90*5c51f124SMoriah Waterland  * which it is). The variable uninst tells the function whether the package
91*5c51f124SMoriah Waterland  * is in the installed state or not. The envfile entry is usually a pkginfo
92*5c51f124SMoriah Waterland  * file, but it could be any environment parameter list.
93*5c51f124SMoriah Waterland  */
94*5c51f124SMoriah Waterland 
95*5c51f124SMoriah Waterland int
96*5c51f124SMoriah Waterland checkmap(int maptyp, int uninst, char *mapfile, char *envfile,
97*5c51f124SMoriah Waterland 		char *pkginst, char *path, int pathtype)
98*5c51f124SMoriah Waterland {
99*5c51f124SMoriah Waterland 	FILE		*fp;
100*5c51f124SMoriah Waterland 	char		*cl = NULL;
101*5c51f124SMoriah Waterland 	char		*value;
102*5c51f124SMoriah Waterland 	char		param[MAX_PKG_PARAM_LENGTH];
103*5c51f124SMoriah Waterland 	int		count;
104*5c51f124SMoriah Waterland 	int		errflg;
105*5c51f124SMoriah Waterland 	int		n;
106*5c51f124SMoriah Waterland 	int		selected;
107*5c51f124SMoriah Waterland 	struct pinfo	*pinfo;
108*5c51f124SMoriah Waterland 	VFP_T		*vfp = (VFP_T *)NULL;
109*5c51f124SMoriah Waterland 
110*5c51f124SMoriah Waterland 	if (envfile != NULL) {
111*5c51f124SMoriah Waterland 		if ((fp = fopen(envfile, "r")) == NULL) {
112*5c51f124SMoriah Waterland 			progerr(gettext(ERR_ENVFILE), envfile);
113*5c51f124SMoriah Waterland 			return (-1);
114*5c51f124SMoriah Waterland 		}
115*5c51f124SMoriah Waterland 		param[0] = '\0';
116*5c51f124SMoriah Waterland 		while (value = fpkgparam(fp, param)) {
117*5c51f124SMoriah Waterland 			if (strcmp("PATH", param) != 0) {
118*5c51f124SMoriah Waterland 				/*
119*5c51f124SMoriah Waterland 				 * If checking an uninstalled package, we
120*5c51f124SMoriah Waterland 				 * only want two parameters. If we took all
121*5c51f124SMoriah Waterland 				 * of them, including path definitions, we
122*5c51f124SMoriah Waterland 				 * wouldn't be looking in the right places in
123*5c51f124SMoriah Waterland 				 * the reloc and root directories.
124*5c51f124SMoriah Waterland 				 */
125*5c51f124SMoriah Waterland 				if (uninst) {
126*5c51f124SMoriah Waterland 					if ((strncmp("PKG_SRC_NOVERIFY", param,
127*5c51f124SMoriah Waterland 					    16) == 0) && value) {
128*5c51f124SMoriah Waterland 						logerr(gettext(MSG_ARCHIVE));
129*5c51f124SMoriah Waterland 						putparam(param, value);
130*5c51f124SMoriah Waterland 					}
131*5c51f124SMoriah Waterland 					if ((strncmp("CLASSES", param,
132*5c51f124SMoriah Waterland 					    7) == 0) && value)
133*5c51f124SMoriah Waterland 						putparam(param, value);
134*5c51f124SMoriah Waterland 				} else
135*5c51f124SMoriah Waterland 					putparam(param, value);
136*5c51f124SMoriah Waterland 			}
137*5c51f124SMoriah Waterland 
138*5c51f124SMoriah Waterland 			free(value);
139*5c51f124SMoriah Waterland 
140*5c51f124SMoriah Waterland 			param[0] = '\0';
141*5c51f124SMoriah Waterland 		}
142*5c51f124SMoriah Waterland 		(void) fclose(fp);
143*5c51f124SMoriah Waterland 		basedir = getenv("BASEDIR");
144*5c51f124SMoriah Waterland 	}
145*5c51f124SMoriah Waterland 
146*5c51f124SMoriah Waterland 	/*
147*5c51f124SMoriah Waterland 	 * If we are using a contents file for the map, this locks the
148*5c51f124SMoriah Waterland 	 * contents file in order to freeze the database and assure it
149*5c51f124SMoriah Waterland 	 * remains synchronized with the file system against which it is
150*5c51f124SMoriah Waterland 	 * being compared. There is no practical way to lock another pkgmap
151*5c51f124SMoriah Waterland 	 * on some unknown medium so we don't bother.
152*5c51f124SMoriah Waterland 	 */
153*5c51f124SMoriah Waterland 	if (maptyp) {	/* If this is the contents file */
154*5c51f124SMoriah Waterland 		if (!socfile(&vfp)) {
155*5c51f124SMoriah Waterland 			progerr(gettext(ERR_PKGMAP), "contents");
156*5c51f124SMoriah Waterland 			return (-1);
157*5c51f124SMoriah Waterland 		}
158*5c51f124SMoriah Waterland 	} else {
159*5c51f124SMoriah Waterland 		if (vfpOpen(&vfp, mapfile, "r", VFP_NONE) != 0) {
160*5c51f124SMoriah Waterland 			progerr(gettext(ERR_PKGMAP), mapfile);
161*5c51f124SMoriah Waterland 			return (-1);
162*5c51f124SMoriah Waterland 		}
163*5c51f124SMoriah Waterland 	}
164*5c51f124SMoriah Waterland 
165*5c51f124SMoriah Waterland 	if ((cl = getenv("CLASSES")) != NULL)
166*5c51f124SMoriah Waterland 		cl_sets(qstrdup(cl));
167*5c51f124SMoriah Waterland 
168*5c51f124SMoriah Waterland 	errflg = count = 0;
169*5c51f124SMoriah Waterland 
170*5c51f124SMoriah Waterland 	do {
171*5c51f124SMoriah Waterland 		if ((n = NXTENTRY(&entry, vfp)) == 0) {
172*5c51f124SMoriah Waterland 			break;
173*5c51f124SMoriah Waterland 		}
174*5c51f124SMoriah Waterland 		/*
175*5c51f124SMoriah Waterland 		 * Search for partial paths in the ext DB.
176*5c51f124SMoriah Waterland 		 */
177*5c51f124SMoriah Waterland 		if (pathtype) {
178*5c51f124SMoriah Waterland 			/* LINTED warning: statement has no consequent: if */
179*5c51f124SMoriah Waterland 			if (is_partial_path_in_DB(entry.path, path)) {
180*5c51f124SMoriah Waterland 				/* Check this entry */
181*5c51f124SMoriah Waterland 				;
182*5c51f124SMoriah Waterland 			} else if (entry.ftype == 's' ||
183*5c51f124SMoriah Waterland 						entry.ftype == 'l') {
184*5c51f124SMoriah Waterland 				if (is_partial_path_in_DB(
185*5c51f124SMoriah Waterland 				/* LINTED warning: statement has no consequen */
186*5c51f124SMoriah Waterland 					entry.ainfo.local, path)) {
187*5c51f124SMoriah Waterland 					/* Check this entry */
188*5c51f124SMoriah Waterland 					;
189*5c51f124SMoriah Waterland 				} else {
190*5c51f124SMoriah Waterland 					continue;
191*5c51f124SMoriah Waterland 				}
192*5c51f124SMoriah Waterland 			} else {
193*5c51f124SMoriah Waterland 				/* Skip to next DB entry */
194*5c51f124SMoriah Waterland 				continue;
195*5c51f124SMoriah Waterland 			}
196*5c51f124SMoriah Waterland 		}
197*5c51f124SMoriah Waterland 
198*5c51f124SMoriah Waterland 		if (n < 0) {
199*5c51f124SMoriah Waterland 			char	*errstr = getErrstr();
200*5c51f124SMoriah Waterland 			logerr(gettext("ERROR: garbled entry"));
201*5c51f124SMoriah Waterland 			logerr(gettext("pathname: %s"),
202*5c51f124SMoriah Waterland 			    (entry.path && *entry.path) ? entry.path :
203*5c51f124SMoriah Waterland 			    "Unknown");
204*5c51f124SMoriah Waterland 			logerr(gettext("problem: %s"),
205*5c51f124SMoriah Waterland 			    (errstr && *errstr) ? errstr : "Unknown");
206*5c51f124SMoriah Waterland 			exit(99);
207*5c51f124SMoriah Waterland 		}
208*5c51f124SMoriah Waterland 		if (n == 0)
209*5c51f124SMoriah Waterland 			break; /* done with file */
210*5c51f124SMoriah Waterland 
211*5c51f124SMoriah Waterland 		/*
212*5c51f124SMoriah Waterland 		 * The class list may not be complete for good reason, so
213*5c51f124SMoriah Waterland 		 * there's no complaining if this returns an index of -1.
214*5c51f124SMoriah Waterland 		 */
215*5c51f124SMoriah Waterland 		if (cl != NULL)
216*5c51f124SMoriah Waterland 			entry.pkg_class_idx = cl_idx(entry.pkg_class);
217*5c51f124SMoriah Waterland 
218*5c51f124SMoriah Waterland 		if (maptyp && pkginst != NULL) {
219*5c51f124SMoriah Waterland 			/*
220*5c51f124SMoriah Waterland 			 * check to see if the entry we just read
221*5c51f124SMoriah Waterland 			 * is associated with one of the packages
222*5c51f124SMoriah Waterland 			 * we have listed on the command line
223*5c51f124SMoriah Waterland 			 */
224*5c51f124SMoriah Waterland 			selected = 0;
225*5c51f124SMoriah Waterland 			pinfo = entry.pinfo;
226*5c51f124SMoriah Waterland 			while (pinfo) {
227*5c51f124SMoriah Waterland 				if (selpkg(pinfo->pkg)) {
228*5c51f124SMoriah Waterland 					selected++;
229*5c51f124SMoriah Waterland 					break;
230*5c51f124SMoriah Waterland 				}
231*5c51f124SMoriah Waterland 				pinfo = pinfo->next;
232*5c51f124SMoriah Waterland 			}
233*5c51f124SMoriah Waterland 			if (!selected)
234*5c51f124SMoriah Waterland 				continue; /* not selected */
235*5c51f124SMoriah Waterland 		}
236*5c51f124SMoriah Waterland 
237*5c51f124SMoriah Waterland 		/*
238*5c51f124SMoriah Waterland 		 * Check to see if the pathname associated with the entry
239*5c51f124SMoriah Waterland 		 * we just read is associated with the list of paths we
240*5c51f124SMoriah Waterland 		 * supplied on the command line
241*5c51f124SMoriah Waterland 		 */
242*5c51f124SMoriah Waterland 		if (!selpath(entry.path, pathtype))
243*5c51f124SMoriah Waterland 			continue; /* not selected */
244*5c51f124SMoriah Waterland 
245*5c51f124SMoriah Waterland 		/*
246*5c51f124SMoriah Waterland 		 * Determine if this is a package object wanting
247*5c51f124SMoriah Waterland 		 * verification. Metafiles are always checked, otherwise, we
248*5c51f124SMoriah Waterland 		 * rely on the class to discriminate.
249*5c51f124SMoriah Waterland 		 */
250*5c51f124SMoriah Waterland 		if (entry.ftype != 'i')
251*5c51f124SMoriah Waterland 			/* If there's no class list... */
252*5c51f124SMoriah Waterland 			if (cl != NULL)
253*5c51f124SMoriah Waterland 				/*
254*5c51f124SMoriah Waterland 				 * ... or this entry isn't in that class list
255*5c51f124SMoriah Waterland 				 * or it's in a private format, then don't
256*5c51f124SMoriah Waterland 				 * check it.
257*5c51f124SMoriah Waterland 				 */
258*5c51f124SMoriah Waterland 				if (entry.pkg_class_idx == -1 ||
259*5c51f124SMoriah Waterland 				    cl_svfy(entry.pkg_class_idx) == NOVERIFY)
260*5c51f124SMoriah Waterland 					continue;
261*5c51f124SMoriah Waterland 
262*5c51f124SMoriah Waterland 		count++;
263*5c51f124SMoriah Waterland 		if (ckentry((envfile ? 1 : 0), maptyp, &entry, vfp))
264*5c51f124SMoriah Waterland 			errflg++;
265*5c51f124SMoriah Waterland 	} while (n != 0);
266*5c51f124SMoriah Waterland 
267*5c51f124SMoriah Waterland 	(void) vfpClose(&vfp);
268*5c51f124SMoriah Waterland 
269*5c51f124SMoriah Waterland 	if (maptyp)
270*5c51f124SMoriah Waterland 		relslock();
271*5c51f124SMoriah Waterland 
272*5c51f124SMoriah Waterland 	if (environ) {
273*5c51f124SMoriah Waterland 		/* free up environment resources */
274*5c51f124SMoriah Waterland 		for (n = 0; environ[n]; n++)
275*5c51f124SMoriah Waterland 			free(environ[n]);
276*5c51f124SMoriah Waterland 		free(environ);
277*5c51f124SMoriah Waterland 		environ = NULL;
278*5c51f124SMoriah Waterland 	}
279*5c51f124SMoriah Waterland 
280*5c51f124SMoriah Waterland 	if (maptyp) {
281*5c51f124SMoriah Waterland 		/*
282*5c51f124SMoriah Waterland 		 * make sure each listed package was associated with
283*5c51f124SMoriah Waterland 		 * an entry from the prototype or pkgmap
284*5c51f124SMoriah Waterland 		 */
285*5c51f124SMoriah Waterland 		(void) selpkg(NULL);
286*5c51f124SMoriah Waterland 	}
287*5c51f124SMoriah Waterland 	if (!qflag && !lflag && !Lflag) {
288*5c51f124SMoriah Waterland 		/*
289*5c51f124SMoriah Waterland 		 * make sure each listed pathname was associated with an entry
290*5c51f124SMoriah Waterland 		 * from the prototype or pkgmap
291*5c51f124SMoriah Waterland 		 */
292*5c51f124SMoriah Waterland 		(void) selpath(NULL, pathtype);
293*5c51f124SMoriah Waterland 	}
294*5c51f124SMoriah Waterland 	return (errflg);
295*5c51f124SMoriah Waterland }
296*5c51f124SMoriah Waterland 
297*5c51f124SMoriah Waterland int
298*5c51f124SMoriah Waterland selpkg(char *p)
299*5c51f124SMoriah Waterland {
300*5c51f124SMoriah Waterland 	static char *selected;
301*5c51f124SMoriah Waterland 	char buf[80];
302*5c51f124SMoriah Waterland 	char *root;
303*5c51f124SMoriah Waterland 	register int i;
304*5c51f124SMoriah Waterland 
305*5c51f124SMoriah Waterland 	if (p == NULL) {
306*5c51f124SMoriah Waterland 		if (selected == NULL) {
307*5c51f124SMoriah Waterland 			if (pkgcnt) {
308*5c51f124SMoriah Waterland 				for (i = 0; i < pkgcnt; ++i) {
309*5c51f124SMoriah Waterland 					/* bugid 1227628 */
310*5c51f124SMoriah Waterland 					root = get_inst_root();
311*5c51f124SMoriah Waterland 					if (root)
312*5c51f124SMoriah Waterland 						(void) snprintf(buf,
313*5c51f124SMoriah Waterland 						sizeof (buf),
314*5c51f124SMoriah Waterland 						"%s/var/sadm/pkg/%s/pkginfo",
315*5c51f124SMoriah Waterland 						root, pkg[i]);
316*5c51f124SMoriah Waterland 					else
317*5c51f124SMoriah Waterland 						(void) snprintf(buf,
318*5c51f124SMoriah Waterland 						sizeof (buf),
319*5c51f124SMoriah Waterland 						"/var/sadm/pkg/%s/pkginfo",
320*5c51f124SMoriah Waterland 						pkg[i]);
321*5c51f124SMoriah Waterland 
322*5c51f124SMoriah Waterland 					if (access(buf, F_OK))
323*5c51f124SMoriah Waterland 						logerr(gettext(WRN_NOPKG),
324*5c51f124SMoriah Waterland 							pkg[i]);
325*5c51f124SMoriah Waterland 					else
326*5c51f124SMoriah Waterland 						logerr(gettext(EMPTY_PKG),
327*5c51f124SMoriah Waterland 							pkg[i]);
328*5c51f124SMoriah Waterland 				}
329*5c51f124SMoriah Waterland 			}
330*5c51f124SMoriah Waterland 		} else {
331*5c51f124SMoriah Waterland 			for (i = 0; i < pkgcnt; ++i) {
332*5c51f124SMoriah Waterland 				if (selected[i] == NULL) {
333*5c51f124SMoriah Waterland 					root = get_inst_root();
334*5c51f124SMoriah Waterland 					if (root)
335*5c51f124SMoriah Waterland 						(void) snprintf(buf,
336*5c51f124SMoriah Waterland 						sizeof (buf),
337*5c51f124SMoriah Waterland 						"%s/var/sadm/pkg/%s/pkginfo",
338*5c51f124SMoriah Waterland 						root, pkg[i]);
339*5c51f124SMoriah Waterland 					else
340*5c51f124SMoriah Waterland 						(void) snprintf(buf,
341*5c51f124SMoriah Waterland 						sizeof (buf),
342*5c51f124SMoriah Waterland 						"/var/sadm/pkg/%s/pkginfo",
343*5c51f124SMoriah Waterland 						pkg[i]);
344*5c51f124SMoriah Waterland 
345*5c51f124SMoriah Waterland 					if (access(buf, F_OK))
346*5c51f124SMoriah Waterland 						logerr(gettext(WRN_NOPKG),
347*5c51f124SMoriah Waterland 							pkg[i]);
348*5c51f124SMoriah Waterland 					else
349*5c51f124SMoriah Waterland 						logerr(gettext(EMPTY_PKG),
350*5c51f124SMoriah Waterland 							pkg[i]);
351*5c51f124SMoriah Waterland 				}
352*5c51f124SMoriah Waterland 			}
353*5c51f124SMoriah Waterland 		}
354*5c51f124SMoriah Waterland 		return (0); /* return value not important */
355*5c51f124SMoriah Waterland 	} else if (pkgcnt == 0)
356*5c51f124SMoriah Waterland 		return (1);
357*5c51f124SMoriah Waterland 	else if (selected == NULL) {
358*5c51f124SMoriah Waterland 		selected =
359*5c51f124SMoriah Waterland 		    (char *)calloc((unsigned)(pkgcnt+1), sizeof (char));
360*5c51f124SMoriah Waterland 		if (selected == NULL) {
361*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOMEM), errno);
362*5c51f124SMoriah Waterland 			exit(99);
363*5c51f124SMoriah Waterland 			/*NOTREACHED*/
364*5c51f124SMoriah Waterland 		}
365*5c51f124SMoriah Waterland 	}
366*5c51f124SMoriah Waterland 
367*5c51f124SMoriah Waterland 	for (i = 0; i < pkgcnt; ++i) {
368*5c51f124SMoriah Waterland 		if (pkgnmchk(p, pkg[i], 0) == 0) {
369*5c51f124SMoriah Waterland 			if (selected != NULL)
370*5c51f124SMoriah Waterland 				selected[i] = 'b';
371*5c51f124SMoriah Waterland 			return (1);
372*5c51f124SMoriah Waterland 		}
373*5c51f124SMoriah Waterland 	}
374*5c51f124SMoriah Waterland 	return (0);
375*5c51f124SMoriah Waterland }
376*5c51f124SMoriah Waterland 
377*5c51f124SMoriah Waterland int
378*5c51f124SMoriah Waterland selpath(char *path, int partial_path)
379*5c51f124SMoriah Waterland {
380*5c51f124SMoriah Waterland 	int n;
381*5c51f124SMoriah Waterland 
382*5c51f124SMoriah Waterland 	if (!npaths)
383*5c51f124SMoriah Waterland 		return (1); /* everything is selectable */
384*5c51f124SMoriah Waterland 
385*5c51f124SMoriah Waterland 	for (n = 0; n < npaths; n++) {
386*5c51f124SMoriah Waterland 		if (path == NULL) {
387*5c51f124SMoriah Waterland 			if (!used[n])
388*5c51f124SMoriah Waterland 				logerr(gettext(WRN_NOPATH),
389*5c51f124SMoriah Waterland 					partial_path ? ppathlist[n] :
390*5c51f124SMoriah Waterland 					pathlist[n]);
391*5c51f124SMoriah Waterland 		} else if (partial_path) {
392*5c51f124SMoriah Waterland 			used[n] = 1;
393*5c51f124SMoriah Waterland 			return (1);
394*5c51f124SMoriah Waterland 		} else if (!shellmatch(pathlist[n], path)) {
395*5c51f124SMoriah Waterland 			used[n] = 1;
396*5c51f124SMoriah Waterland 			return (1);
397*5c51f124SMoriah Waterland 		}
398*5c51f124SMoriah Waterland 	}
399*5c51f124SMoriah Waterland 	return (0); /* not selected */
400*5c51f124SMoriah Waterland }
401*5c51f124SMoriah Waterland 
402*5c51f124SMoriah Waterland static int
403*5c51f124SMoriah Waterland shellmatch(char *spec, char *path)
404*5c51f124SMoriah Waterland {
405*5c51f124SMoriah Waterland 	/* Check if the value is NULL */
406*5c51f124SMoriah Waterland 	if (spec == NULL || path == NULL)
407*5c51f124SMoriah Waterland 		return (1);
408*5c51f124SMoriah Waterland 
409*5c51f124SMoriah Waterland 	while (*spec && (*spec == *path)) {
410*5c51f124SMoriah Waterland 		spec++, path++;
411*5c51f124SMoriah Waterland 	}
412*5c51f124SMoriah Waterland 	if ((*spec == *path) || (*spec == '*'))
413*5c51f124SMoriah Waterland 		return (0);
414*5c51f124SMoriah Waterland 	return (1);
415*5c51f124SMoriah Waterland }
416*5c51f124SMoriah Waterland 
417*5c51f124SMoriah Waterland static int
418*5c51f124SMoriah Waterland is_partial_path_in_DB(char *srcpath, char *trgtpath)
419*5c51f124SMoriah Waterland {
420*5c51f124SMoriah Waterland 	if (strstr(srcpath, trgtpath) == NULL) {
421*5c51f124SMoriah Waterland 		return (0);
422*5c51f124SMoriah Waterland 	} else {
423*5c51f124SMoriah Waterland 		return (1);
424*5c51f124SMoriah Waterland 	}
425*5c51f124SMoriah Waterland }
426