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 <memory.h>
33*5c51f124SMoriah Waterland #include <string.h>
34*5c51f124SMoriah Waterland #include <limits.h>
35*5c51f124SMoriah Waterland #include <dirent.h>
36*5c51f124SMoriah Waterland #include <sys/types.h>
37*5c51f124SMoriah Waterland #include <sys/stat.h>
38*5c51f124SMoriah Waterland #include <pkgstrct.h>
39*5c51f124SMoriah Waterland #include <locale.h>
40*5c51f124SMoriah Waterland #include <libintl.h>
41*5c51f124SMoriah Waterland #include <unistd.h>
42*5c51f124SMoriah Waterland #include <stdlib.h>
43*5c51f124SMoriah Waterland #include "pkglib.h"
44*5c51f124SMoriah Waterland #include "install.h"
45*5c51f124SMoriah Waterland #include "libadm.h"
46*5c51f124SMoriah Waterland #include "libinst.h"
47*5c51f124SMoriah Waterland 
48*5c51f124SMoriah Waterland extern int	Lflag, lflag, aflag, cflag, fflag, qflag, nflag, xflag, vflag;
49*5c51f124SMoriah Waterland extern char	*basedir, *device, pkgspool[];
50*5c51f124SMoriah Waterland 
51*5c51f124SMoriah Waterland #define	NXTENTRY(P, VFP) \
52*5c51f124SMoriah Waterland 		(maptyp ? srchcfile((P), "*", (VFP), (VFP_T *)NULL) :\
53*5c51f124SMoriah Waterland 		gpkgmapvfp((P), (VFP)))
54*5c51f124SMoriah Waterland 
55*5c51f124SMoriah Waterland #define	ERR_SPOOLED	"ERROR: unable to locate spooled object <%s>"
56*5c51f124SMoriah Waterland #define	MSG_NET_OBJ	"It is remote and may be available from the network."
57*5c51f124SMoriah Waterland #define	ERR_RMHIDDEN	"unable to remove hidden file"
58*5c51f124SMoriah Waterland #define	ERR_HIDDEN	"ERROR: hidden file in exclusive directory"
59*5c51f124SMoriah Waterland 
60*5c51f124SMoriah Waterland static char	*findspool(struct cfent *ept);
61*5c51f124SMoriah Waterland static int	xdir(int maptyp, VFP_T *vfp, char *dirname);
62*5c51f124SMoriah Waterland 
63*5c51f124SMoriah Waterland int
64*5c51f124SMoriah Waterland ckentry(int envflag, int maptyp, struct cfent *ept, VFP_T *vfp)
65*5c51f124SMoriah Waterland {
66*5c51f124SMoriah Waterland 	int	a_err, c_err,
67*5c51f124SMoriah Waterland 		errflg;
68*5c51f124SMoriah Waterland 	char	*path;
69*5c51f124SMoriah Waterland 	char	*ir = get_inst_root();
70*5c51f124SMoriah Waterland 
71*5c51f124SMoriah Waterland 	if (ept->ftype != 'i') {
72*5c51f124SMoriah Waterland 		if (envflag)
73*5c51f124SMoriah Waterland 			mappath(2, ept->path);
74*5c51f124SMoriah Waterland 		if (!device)
75*5c51f124SMoriah Waterland 			basepath(ept->path, maptyp ? NULL : basedir, ir);
76*5c51f124SMoriah Waterland 	}
77*5c51f124SMoriah Waterland 	canonize(ept->path);
78*5c51f124SMoriah Waterland 	if (strchr("sl", ept->ftype)) {
79*5c51f124SMoriah Waterland 		if (envflag)				/* -e option */
80*5c51f124SMoriah Waterland 			mappath(2, ept->ainfo.local);
81*5c51f124SMoriah Waterland 		if (!RELATIVE(ept->ainfo.local)) {	/* Absolute Path */
82*5c51f124SMoriah Waterland 			if (!device) {
83*5c51f124SMoriah Waterland 				if (ept->ftype == 'l')	/* Hard Link */
84*5c51f124SMoriah Waterland 					basepath(ept->ainfo.local, NULL, ir);
85*5c51f124SMoriah Waterland 			}
86*5c51f124SMoriah Waterland 		}
87*5c51f124SMoriah Waterland 		if (!RELATIVE(ept->ainfo.local))	/* Absolute Path */
88*5c51f124SMoriah Waterland 			canonize(ept->ainfo.local);
89*5c51f124SMoriah Waterland 	}
90*5c51f124SMoriah Waterland 	if (envflag) {
91*5c51f124SMoriah Waterland 		if (!strchr("isl", ept->ftype)) {
92*5c51f124SMoriah Waterland 			mapvar(2, ept->ainfo.owner);
93*5c51f124SMoriah Waterland 			mapvar(2, ept->ainfo.group);
94*5c51f124SMoriah Waterland 		}
95*5c51f124SMoriah Waterland 	}
96*5c51f124SMoriah Waterland 
97*5c51f124SMoriah Waterland 	if (lflag) {
98*5c51f124SMoriah Waterland 		tputcfent(ept, stdout);
99*5c51f124SMoriah Waterland 		return (0);
100*5c51f124SMoriah Waterland 	} else if (Lflag)
101*5c51f124SMoriah Waterland 		return (putcfile(ept, stdout));
102*5c51f124SMoriah Waterland 
103*5c51f124SMoriah Waterland 	errflg = 0;
104*5c51f124SMoriah Waterland 	if (device) {
105*5c51f124SMoriah Waterland 		if (strchr("dxslcbp", ept->ftype))
106*5c51f124SMoriah Waterland 			return (0);
107*5c51f124SMoriah Waterland 		if ((path = findspool(ept)) == NULL) {
108*5c51f124SMoriah Waterland 			logerr(gettext(ERR_SPOOLED), ept->path);
109*5c51f124SMoriah Waterland 			return (-1);
110*5c51f124SMoriah Waterland 		}
111*5c51f124SMoriah Waterland 
112*5c51f124SMoriah Waterland 		/*
113*5c51f124SMoriah Waterland 		 * If the package file attributes are to be sync'd up with
114*5c51f124SMoriah Waterland 		 * the pkgmap, we fix the attributes here.
115*5c51f124SMoriah Waterland 		 */
116*5c51f124SMoriah Waterland 		if (fflag) {
117*5c51f124SMoriah Waterland 			a_err = 0;
118*5c51f124SMoriah Waterland 			/* Clear dangerous bits. */
119*5c51f124SMoriah Waterland 			ept->ainfo.mode = (ept->ainfo.mode & S_IAMB);
120*5c51f124SMoriah Waterland 			/*
121*5c51f124SMoriah Waterland 			 * Make sure the file is readable by the world and
122*5c51f124SMoriah Waterland 			 * writeable by root.
123*5c51f124SMoriah Waterland 			 */
124*5c51f124SMoriah Waterland 			ept->ainfo.mode |= 0644;
125*5c51f124SMoriah Waterland 			if (!strchr("in", ept->ftype)) {
126*5c51f124SMoriah Waterland 				/* Set the safe attributes. */
127*5c51f124SMoriah Waterland 				if (a_err = averify(fflag, &ept->ftype,
128*5c51f124SMoriah Waterland 				    path, &ept->ainfo)) {
129*5c51f124SMoriah Waterland 					errflg++;
130*5c51f124SMoriah Waterland 					if (!qflag || (a_err != VE_EXIST)) {
131*5c51f124SMoriah Waterland 						logerr(gettext("ERROR: %s"),
132*5c51f124SMoriah Waterland 						    ept->path);
133*5c51f124SMoriah Waterland 						logerr(getErrbufAddr());
134*5c51f124SMoriah Waterland 					}
135*5c51f124SMoriah Waterland 					if (a_err == VE_EXIST)
136*5c51f124SMoriah Waterland 						return (-1);
137*5c51f124SMoriah Waterland 				}
138*5c51f124SMoriah Waterland 			}
139*5c51f124SMoriah Waterland 		}
140*5c51f124SMoriah Waterland 		/* Report invalid modtimes by passing cverify a -1 */
141*5c51f124SMoriah Waterland 		c_err = cverify((!fflag ? (-1) : fflag),  &ept->ftype, path,
142*5c51f124SMoriah Waterland 			&ept->cinfo, 1);
143*5c51f124SMoriah Waterland 		if (c_err) {
144*5c51f124SMoriah Waterland 			logerr(gettext("ERROR: %s"), path);
145*5c51f124SMoriah Waterland 			logerr(getErrbufAddr());
146*5c51f124SMoriah Waterland 			return (-1);
147*5c51f124SMoriah Waterland 		}
148*5c51f124SMoriah Waterland 	} else {
149*5c51f124SMoriah Waterland 		a_err = 0;
150*5c51f124SMoriah Waterland 		if (aflag && !strchr("in", ept->ftype)) {
151*5c51f124SMoriah Waterland 			/* validate attributes */
152*5c51f124SMoriah Waterland 			if (a_err = averify(fflag, &ept->ftype, ept->path,
153*5c51f124SMoriah Waterland 			    &ept->ainfo)) {
154*5c51f124SMoriah Waterland 				errflg++;
155*5c51f124SMoriah Waterland 				if (!qflag || (a_err != VE_EXIST)) {
156*5c51f124SMoriah Waterland 					logerr(gettext("ERROR: %s"),
157*5c51f124SMoriah Waterland 					    ept->path);
158*5c51f124SMoriah Waterland 					logerr(getErrbufAddr());
159*5c51f124SMoriah Waterland 					if (maptyp && ept->pinfo->status ==
160*5c51f124SMoriah Waterland 					    SERVED_FILE)
161*5c51f124SMoriah Waterland 						logerr(gettext(MSG_NET_OBJ));
162*5c51f124SMoriah Waterland 				}
163*5c51f124SMoriah Waterland 				if (a_err == VE_EXIST)
164*5c51f124SMoriah Waterland 					return (-1);
165*5c51f124SMoriah Waterland 			}
166*5c51f124SMoriah Waterland 		}
167*5c51f124SMoriah Waterland 		if (cflag && strchr("fev", ept->ftype) &&
168*5c51f124SMoriah Waterland 		    (!nflag || ept->ftype != 'v') && /* bug # 1082144 */
169*5c51f124SMoriah Waterland 		    (!nflag || ept->ftype != 'e')) {
170*5c51f124SMoriah Waterland 			/* validate contents */
171*5c51f124SMoriah Waterland 			/* Report invalid modtimes by passing cverify a -1 */
172*5c51f124SMoriah Waterland 			if (c_err = cverify((!fflag ? (-1) : fflag),
173*5c51f124SMoriah Waterland 				&ept->ftype, ept->path, &ept->cinfo, 1)) {
174*5c51f124SMoriah Waterland 				errflg++;
175*5c51f124SMoriah Waterland 				if (!qflag || (c_err != VE_EXIST)) {
176*5c51f124SMoriah Waterland 					if (!a_err)
177*5c51f124SMoriah Waterland 						logerr(gettext("ERROR: %s"),
178*5c51f124SMoriah Waterland 						    ept->path);
179*5c51f124SMoriah Waterland 					logerr(getErrbufAddr());
180*5c51f124SMoriah Waterland 					if (maptyp && ept->pinfo->status ==
181*5c51f124SMoriah Waterland 					    SERVED_FILE)
182*5c51f124SMoriah Waterland 						logerr(gettext(MSG_NET_OBJ));
183*5c51f124SMoriah Waterland 				}
184*5c51f124SMoriah Waterland 				if (c_err == VE_EXIST)
185*5c51f124SMoriah Waterland 					return (-1);
186*5c51f124SMoriah Waterland 			}
187*5c51f124SMoriah Waterland 		}
188*5c51f124SMoriah Waterland 		if (xflag && (ept->ftype == 'x')) {
189*5c51f124SMoriah Waterland 			/* must do verbose here since ept->path will change */
190*5c51f124SMoriah Waterland 			path = strdup(ept->path);
191*5c51f124SMoriah Waterland 			if (xdir(maptyp, vfp, path))
192*5c51f124SMoriah Waterland 				errflg++;
193*5c51f124SMoriah Waterland 			(void) strcpy(ept->path, path);
194*5c51f124SMoriah Waterland 			free(path);
195*5c51f124SMoriah Waterland 		}
196*5c51f124SMoriah Waterland 	}
197*5c51f124SMoriah Waterland 	if (vflag)
198*5c51f124SMoriah Waterland 		(void) fprintf(stderr, "%s\n", ept->path);
199*5c51f124SMoriah Waterland 	return (errflg);
200*5c51f124SMoriah Waterland }
201*5c51f124SMoriah Waterland 
202*5c51f124SMoriah Waterland static int
203*5c51f124SMoriah Waterland xdir(int maptyp, VFP_T *vfp, char *dirname)
204*5c51f124SMoriah Waterland {
205*5c51f124SMoriah Waterland 	DIR		*dirfp;
206*5c51f124SMoriah Waterland 	char		badpath[PATH_MAX+1];
207*5c51f124SMoriah Waterland 	int		dirfound;
208*5c51f124SMoriah Waterland 	int		errflg;
209*5c51f124SMoriah Waterland 	int		len;
210*5c51f124SMoriah Waterland 	int		n;
211*5c51f124SMoriah Waterland 	struct cfent	mine;
212*5c51f124SMoriah Waterland 	struct dirent	*drp;
213*5c51f124SMoriah Waterland 	struct pinfo	*pinfo;
214*5c51f124SMoriah Waterland 	void		*pos;
215*5c51f124SMoriah Waterland 
216*5c51f124SMoriah Waterland 	pos = vfpGetCurrCharPtr(vfp);	/* get current position in file */
217*5c51f124SMoriah Waterland 
218*5c51f124SMoriah Waterland 	if ((dirfp = opendir(dirname)) == NULL) {
219*5c51f124SMoriah Waterland 		progerr(gettext("unable to open directory <%s>"), dirname);
220*5c51f124SMoriah Waterland 		return (-1);
221*5c51f124SMoriah Waterland 	}
222*5c51f124SMoriah Waterland 	len = strlen(dirname);
223*5c51f124SMoriah Waterland 
224*5c51f124SMoriah Waterland 	errflg = 0;
225*5c51f124SMoriah Waterland 	(void) memset((char *)&mine, '\0', sizeof (struct cfent));
226*5c51f124SMoriah Waterland 	while ((drp = readdir(dirfp)) != NULL) {
227*5c51f124SMoriah Waterland 		if (strcmp(drp->d_name, ".") == NULL ||
228*5c51f124SMoriah Waterland 		    strcmp(drp->d_name, "..") == NULL)
229*5c51f124SMoriah Waterland 			continue;
230*5c51f124SMoriah Waterland 		dirfound = 0;
231*5c51f124SMoriah Waterland 		while ((n = NXTENTRY(&mine, vfp)) != 0) {
232*5c51f124SMoriah Waterland 			if (n < 0) {
233*5c51f124SMoriah Waterland 				char	*errstr = getErrstr();
234*5c51f124SMoriah Waterland 				logerr(gettext("ERROR: garbled entry"));
235*5c51f124SMoriah Waterland 				logerr(gettext("pathname: %s"),
236*5c51f124SMoriah Waterland 				    (mine.path && *mine.path) ? mine.path :
237*5c51f124SMoriah Waterland 				    "Unknown");
238*5c51f124SMoriah Waterland 				logerr(gettext("problem: %s"),
239*5c51f124SMoriah Waterland 				    (errstr && *errstr) ? errstr : "Unknown");
240*5c51f124SMoriah Waterland 				exit(99);
241*5c51f124SMoriah Waterland 			}
242*5c51f124SMoriah Waterland 			if (strncmp(mine.path, dirname, len) ||
243*5c51f124SMoriah Waterland 			(mine.path[len] != '/'))
244*5c51f124SMoriah Waterland 				break;
245*5c51f124SMoriah Waterland 			if (strcmp(drp->d_name, &mine.path[len+1]) == NULL) {
246*5c51f124SMoriah Waterland 				dirfound++;
247*5c51f124SMoriah Waterland 				break;
248*5c51f124SMoriah Waterland 			}
249*5c51f124SMoriah Waterland 		}
250*5c51f124SMoriah Waterland 
251*5c51f124SMoriah Waterland 		vfpGetCurrCharPtr(vfp) = pos;
252*5c51f124SMoriah Waterland 
253*5c51f124SMoriah Waterland 		if (!dirfound) {
254*5c51f124SMoriah Waterland 			(void) snprintf(badpath, sizeof (badpath),
255*5c51f124SMoriah Waterland 				"%s/%s", dirname, drp->d_name);
256*5c51f124SMoriah Waterland 			if (fflag) {
257*5c51f124SMoriah Waterland 				if (unlink(badpath)) {
258*5c51f124SMoriah Waterland 					errflg++;
259*5c51f124SMoriah Waterland 					logerr(gettext("ERROR: %s"), badpath);
260*5c51f124SMoriah Waterland 					logerr(gettext(ERR_RMHIDDEN));
261*5c51f124SMoriah Waterland 				}
262*5c51f124SMoriah Waterland 			} else {
263*5c51f124SMoriah Waterland 				errflg++;
264*5c51f124SMoriah Waterland 				logerr(gettext("ERROR: %s"), badpath);
265*5c51f124SMoriah Waterland 				logerr(gettext(ERR_HIDDEN));
266*5c51f124SMoriah Waterland 			}
267*5c51f124SMoriah Waterland 		}
268*5c51f124SMoriah Waterland 	}
269*5c51f124SMoriah Waterland 
270*5c51f124SMoriah Waterland 	if (maptyp) {
271*5c51f124SMoriah Waterland 		/* clear memory we've used */
272*5c51f124SMoriah Waterland 		while ((pinfo = mine.pinfo) != NULL) {
273*5c51f124SMoriah Waterland 			mine.pinfo = pinfo->next;
274*5c51f124SMoriah Waterland 			free((char *)pinfo);
275*5c51f124SMoriah Waterland 		}
276*5c51f124SMoriah Waterland 	}
277*5c51f124SMoriah Waterland 
278*5c51f124SMoriah Waterland 	(void) closedir(dirfp);
279*5c51f124SMoriah Waterland 	return (errflg);
280*5c51f124SMoriah Waterland }
281*5c51f124SMoriah Waterland 
282*5c51f124SMoriah Waterland static char *
283*5c51f124SMoriah Waterland findspool(struct cfent *ept)
284*5c51f124SMoriah Waterland {
285*5c51f124SMoriah Waterland 	static char	path[2*PATH_MAX+1];
286*5c51f124SMoriah Waterland 	char		host[PATH_MAX+1];
287*5c51f124SMoriah Waterland 
288*5c51f124SMoriah Waterland 	(void) strcpy(host, pkgspool);
289*5c51f124SMoriah Waterland 	if (ept->ftype == 'i') {
290*5c51f124SMoriah Waterland 		if (strcmp(ept->path, "pkginfo"))
291*5c51f124SMoriah Waterland 			(void) strcat(host, "/install");
292*5c51f124SMoriah Waterland 	} else if (ept->path[0] == '/') {
293*5c51f124SMoriah Waterland 		(void) strcat(host, "/root");
294*5c51f124SMoriah Waterland 	} else {
295*5c51f124SMoriah Waterland 		(void) strcat(host, "/reloc");
296*5c51f124SMoriah Waterland 	}
297*5c51f124SMoriah Waterland 
298*5c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/%s", host,
299*5c51f124SMoriah Waterland 		ept->path + (ept->path[0] == '/'));
300*5c51f124SMoriah Waterland 
301*5c51f124SMoriah Waterland 	if (access(path, 0) == 0) {
302*5c51f124SMoriah Waterland 		return (path);
303*5c51f124SMoriah Waterland 	}
304*5c51f124SMoriah Waterland 
305*5c51f124SMoriah Waterland 	if ((ept->ftype != 'i') && (ept->volno > 0)) {
306*5c51f124SMoriah Waterland 		(void) snprintf(path, sizeof (path),
307*5c51f124SMoriah Waterland 				"%s.%d/%s", host, ept->volno,
308*5c51f124SMoriah Waterland 			ept->path + (ept->path[0] == '/'));
309*5c51f124SMoriah Waterland 		if (access(path, 0) == 0) {
310*5c51f124SMoriah Waterland 			return (path);
311*5c51f124SMoriah Waterland 		}
312*5c51f124SMoriah Waterland 	}
313*5c51f124SMoriah Waterland 	return (NULL);
314*5c51f124SMoriah Waterland }
315