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 /*
2362224350SCasper H.S. Dik  * 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 
315c51f124SMoriah Waterland #include <stdio.h>
325c51f124SMoriah Waterland #include <memory.h>
335c51f124SMoriah Waterland #include <string.h>
345c51f124SMoriah Waterland #include <limits.h>
355c51f124SMoriah Waterland #include <dirent.h>
365c51f124SMoriah Waterland #include <sys/types.h>
375c51f124SMoriah Waterland #include <sys/stat.h>
385c51f124SMoriah Waterland #include <pkgstrct.h>
395c51f124SMoriah Waterland #include <locale.h>
405c51f124SMoriah Waterland #include <libintl.h>
415c51f124SMoriah Waterland #include <unistd.h>
425c51f124SMoriah Waterland #include <stdlib.h>
435c51f124SMoriah Waterland #include "pkglib.h"
445c51f124SMoriah Waterland #include "install.h"
455c51f124SMoriah Waterland #include "libadm.h"
465c51f124SMoriah Waterland #include "libinst.h"
475c51f124SMoriah Waterland 
485c51f124SMoriah Waterland extern int	Lflag, lflag, aflag, cflag, fflag, qflag, nflag, xflag, vflag;
495c51f124SMoriah Waterland extern char	*basedir, *device, pkgspool[];
505c51f124SMoriah Waterland 
5162224350SCasper H.S. Dik #define	NXTENTRY(P, VFP) (gpkgmapvfp((P), (VFP)))
525c51f124SMoriah Waterland 
535c51f124SMoriah Waterland #define	ERR_SPOOLED	"ERROR: unable to locate spooled object <%s>"
545c51f124SMoriah Waterland #define	MSG_NET_OBJ	"It is remote and may be available from the network."
555c51f124SMoriah Waterland #define	ERR_RMHIDDEN	"unable to remove hidden file"
565c51f124SMoriah Waterland #define	ERR_HIDDEN	"ERROR: hidden file in exclusive directory"
575c51f124SMoriah Waterland 
585c51f124SMoriah Waterland static char	*findspool(struct cfent *ept);
5962224350SCasper H.S. Dik static int	xdir(int maptyp, VFP_T *vfp, PKGserver server, char *dirname);
605c51f124SMoriah Waterland 
615c51f124SMoriah Waterland int
ckentry(int envflag,int maptyp,struct cfent * ept,VFP_T * vfp,PKGserver server)6262224350SCasper H.S. Dik ckentry(int envflag, int maptyp, struct cfent *ept, VFP_T *vfp,
6362224350SCasper H.S. Dik     PKGserver server)
645c51f124SMoriah Waterland {
65*014740deSToomas Soome 	int	a_err, c_err, errflg;
665c51f124SMoriah Waterland 	char	*path;
675c51f124SMoriah Waterland 	char	*ir = get_inst_root();
685c51f124SMoriah Waterland 
695c51f124SMoriah Waterland 	if (ept->ftype != 'i') {
705c51f124SMoriah Waterland 		if (envflag)
715c51f124SMoriah Waterland 			mappath(2, ept->path);
725c51f124SMoriah Waterland 		if (!device)
735c51f124SMoriah Waterland 			basepath(ept->path, maptyp ? NULL : basedir, ir);
745c51f124SMoriah Waterland 	}
755c51f124SMoriah Waterland 	canonize(ept->path);
765c51f124SMoriah Waterland 	if (strchr("sl", ept->ftype)) {
775c51f124SMoriah Waterland 		if (envflag)				/* -e option */
785c51f124SMoriah Waterland 			mappath(2, ept->ainfo.local);
795c51f124SMoriah Waterland 		if (!RELATIVE(ept->ainfo.local)) {	/* Absolute Path */
805c51f124SMoriah Waterland 			if (!device) {
815c51f124SMoriah Waterland 				if (ept->ftype == 'l')	/* Hard Link */
825c51f124SMoriah Waterland 					basepath(ept->ainfo.local, NULL, ir);
835c51f124SMoriah Waterland 			}
845c51f124SMoriah Waterland 		}
855c51f124SMoriah Waterland 		if (!RELATIVE(ept->ainfo.local))	/* Absolute Path */
865c51f124SMoriah Waterland 			canonize(ept->ainfo.local);
875c51f124SMoriah Waterland 	}
885c51f124SMoriah Waterland 	if (envflag) {
895c51f124SMoriah Waterland 		if (!strchr("isl", ept->ftype)) {
905c51f124SMoriah Waterland 			mapvar(2, ept->ainfo.owner);
915c51f124SMoriah Waterland 			mapvar(2, ept->ainfo.group);
925c51f124SMoriah Waterland 		}
935c51f124SMoriah Waterland 	}
945c51f124SMoriah Waterland 
955c51f124SMoriah Waterland 	if (lflag) {
965c51f124SMoriah Waterland 		tputcfent(ept, stdout);
975c51f124SMoriah Waterland 		return (0);
985c51f124SMoriah Waterland 	} else if (Lflag)
995c51f124SMoriah Waterland 		return (putcfile(ept, stdout));
1005c51f124SMoriah Waterland 
1015c51f124SMoriah Waterland 	errflg = 0;
1025c51f124SMoriah Waterland 	if (device) {
1035c51f124SMoriah Waterland 		if (strchr("dxslcbp", ept->ftype))
1045c51f124SMoriah Waterland 			return (0);
1055c51f124SMoriah Waterland 		if ((path = findspool(ept)) == NULL) {
1065c51f124SMoriah Waterland 			logerr(gettext(ERR_SPOOLED), ept->path);
1075c51f124SMoriah Waterland 			return (-1);
1085c51f124SMoriah Waterland 		}
1095c51f124SMoriah Waterland 
1105c51f124SMoriah Waterland 		/*
1115c51f124SMoriah Waterland 		 * If the package file attributes are to be sync'd up with
1125c51f124SMoriah Waterland 		 * the pkgmap, we fix the attributes here.
1135c51f124SMoriah Waterland 		 */
1145c51f124SMoriah Waterland 		if (fflag) {
1155c51f124SMoriah Waterland 			a_err = 0;
1165c51f124SMoriah Waterland 			/* Clear dangerous bits. */
1175c51f124SMoriah Waterland 			ept->ainfo.mode = (ept->ainfo.mode & S_IAMB);
1185c51f124SMoriah Waterland 			/*
1195c51f124SMoriah Waterland 			 * Make sure the file is readable by the world and
1205c51f124SMoriah Waterland 			 * writeable by root.
1215c51f124SMoriah Waterland 			 */
1225c51f124SMoriah Waterland 			ept->ainfo.mode |= 0644;
1235c51f124SMoriah Waterland 			if (!strchr("in", ept->ftype)) {
1245c51f124SMoriah Waterland 				/* Set the safe attributes. */
1255c51f124SMoriah Waterland 				if (a_err = averify(fflag, &ept->ftype,
1265c51f124SMoriah Waterland 				    path, &ept->ainfo)) {
1275c51f124SMoriah Waterland 					errflg++;
1285c51f124SMoriah Waterland 					if (!qflag || (a_err != VE_EXIST)) {
1295c51f124SMoriah Waterland 						logerr(gettext("ERROR: %s"),
1305c51f124SMoriah Waterland 						    ept->path);
1315c51f124SMoriah Waterland 						logerr(getErrbufAddr());
1325c51f124SMoriah Waterland 					}
1335c51f124SMoriah Waterland 					if (a_err == VE_EXIST)
1345c51f124SMoriah Waterland 						return (-1);
1355c51f124SMoriah Waterland 				}
1365c51f124SMoriah Waterland 			}
1375c51f124SMoriah Waterland 		}
1385c51f124SMoriah Waterland 		/* Report invalid modtimes by passing cverify a -1 */
1395c51f124SMoriah Waterland 		c_err = cverify((!fflag ? (-1) : fflag),  &ept->ftype, path,
140*014740deSToomas Soome 		    &ept->cinfo, 1);
1415c51f124SMoriah Waterland 		if (c_err) {
1425c51f124SMoriah Waterland 			logerr(gettext("ERROR: %s"), path);
1435c51f124SMoriah Waterland 			logerr(getErrbufAddr());
1445c51f124SMoriah Waterland 			return (-1);
1455c51f124SMoriah Waterland 		}
1465c51f124SMoriah Waterland 	} else {
1475c51f124SMoriah Waterland 		a_err = 0;
1485c51f124SMoriah Waterland 		if (aflag && !strchr("in", ept->ftype)) {
1495c51f124SMoriah Waterland 			/* validate attributes */
1505c51f124SMoriah Waterland 			if (a_err = averify(fflag, &ept->ftype, ept->path,
1515c51f124SMoriah Waterland 			    &ept->ainfo)) {
1525c51f124SMoriah Waterland 				errflg++;
1535c51f124SMoriah Waterland 				if (!qflag || (a_err != VE_EXIST)) {
1545c51f124SMoriah Waterland 					logerr(gettext("ERROR: %s"),
1555c51f124SMoriah Waterland 					    ept->path);
1565c51f124SMoriah Waterland 					logerr(getErrbufAddr());
1575c51f124SMoriah Waterland 					if (maptyp && ept->pinfo->status ==
1585c51f124SMoriah Waterland 					    SERVED_FILE)
1595c51f124SMoriah Waterland 						logerr(gettext(MSG_NET_OBJ));
1605c51f124SMoriah Waterland 				}
1615c51f124SMoriah Waterland 				if (a_err == VE_EXIST)
1625c51f124SMoriah Waterland 					return (-1);
1635c51f124SMoriah Waterland 			}
1645c51f124SMoriah Waterland 		}
1655c51f124SMoriah Waterland 		if (cflag && strchr("fev", ept->ftype) &&
1665c51f124SMoriah Waterland 		    (!nflag || ept->ftype != 'v') && /* bug # 1082144 */
1675c51f124SMoriah Waterland 		    (!nflag || ept->ftype != 'e')) {
1685c51f124SMoriah Waterland 			/* validate contents */
1695c51f124SMoriah Waterland 			/* Report invalid modtimes by passing cverify a -1 */
1705c51f124SMoriah Waterland 			if (c_err = cverify((!fflag ? (-1) : fflag),
171*014740deSToomas Soome 			    &ept->ftype, ept->path, &ept->cinfo, 1)) {
1725c51f124SMoriah Waterland 				errflg++;
1735c51f124SMoriah Waterland 				if (!qflag || (c_err != VE_EXIST)) {
1745c51f124SMoriah Waterland 					if (!a_err)
1755c51f124SMoriah Waterland 						logerr(gettext("ERROR: %s"),
1765c51f124SMoriah Waterland 						    ept->path);
1775c51f124SMoriah Waterland 					logerr(getErrbufAddr());
1785c51f124SMoriah Waterland 					if (maptyp && ept->pinfo->status ==
1795c51f124SMoriah Waterland 					    SERVED_FILE)
1805c51f124SMoriah Waterland 						logerr(gettext(MSG_NET_OBJ));
1815c51f124SMoriah Waterland 				}
1825c51f124SMoriah Waterland 				if (c_err == VE_EXIST)
1835c51f124SMoriah Waterland 					return (-1);
1845c51f124SMoriah Waterland 			}
1855c51f124SMoriah Waterland 		}
1865c51f124SMoriah Waterland 		if (xflag && (ept->ftype == 'x')) {
1875c51f124SMoriah Waterland 			/* must do verbose here since ept->path will change */
1885c51f124SMoriah Waterland 			path = strdup(ept->path);
18962224350SCasper H.S. Dik 			if (xdir(maptyp, vfp, server, path))
1905c51f124SMoriah Waterland 				errflg++;
1915c51f124SMoriah Waterland 			(void) strcpy(ept->path, path);
1925c51f124SMoriah Waterland 			free(path);
1935c51f124SMoriah Waterland 		}
1945c51f124SMoriah Waterland 	}
1955c51f124SMoriah Waterland 	if (vflag)
1965c51f124SMoriah Waterland 		(void) fprintf(stderr, "%s\n", ept->path);
1975c51f124SMoriah Waterland 	return (errflg);
1985c51f124SMoriah Waterland }
1995c51f124SMoriah Waterland 
2005c51f124SMoriah Waterland static int
xdir(int maptyp,VFP_T * vfp,PKGserver server,char * dirname)20162224350SCasper H.S. Dik xdir(int maptyp, VFP_T *vfp, PKGserver server, char *dirname)
2025c51f124SMoriah Waterland {
2035c51f124SMoriah Waterland 	DIR		*dirfp;
20462224350SCasper H.S. Dik 	char		badpath[PATH_MAX];
2055c51f124SMoriah Waterland 	int		dirfound;
2065c51f124SMoriah Waterland 	int		errflg;
2075c51f124SMoriah Waterland 	int		len;
2085c51f124SMoriah Waterland 	int		n;
2095c51f124SMoriah Waterland 	struct cfent	mine;
2105c51f124SMoriah Waterland 	struct dirent	*drp;
2115c51f124SMoriah Waterland 	struct pinfo	*pinfo;
212*014740deSToomas Soome 	void		*pos = NULL;
2135c51f124SMoriah Waterland 
21462224350SCasper H.S. Dik 	if (!maptyp)
21562224350SCasper H.S. Dik 		pos = vfpGetCurrCharPtr(vfp); /* get current position in file */
2165c51f124SMoriah Waterland 
2175c51f124SMoriah Waterland 	if ((dirfp = opendir(dirname)) == NULL) {
2185c51f124SMoriah Waterland 		progerr(gettext("unable to open directory <%s>"), dirname);
2195c51f124SMoriah Waterland 		return (-1);
2205c51f124SMoriah Waterland 	}
2215c51f124SMoriah Waterland 	len = strlen(dirname);
2225c51f124SMoriah Waterland 
2235c51f124SMoriah Waterland 	errflg = 0;
2245c51f124SMoriah Waterland 	(void) memset((char *)&mine, '\0', sizeof (struct cfent));
2255c51f124SMoriah Waterland 	while ((drp = readdir(dirfp)) != NULL) {
226c57b7750SToomas Soome 		if (strcmp(drp->d_name, ".") == 0 ||
227c57b7750SToomas Soome 		    strcmp(drp->d_name, "..") == 0)
2285c51f124SMoriah Waterland 			continue;
22962224350SCasper H.S. Dik 		(void) snprintf(badpath, sizeof (badpath), "%s/%s",
23062224350SCasper H.S. Dik 		    dirname, drp->d_name);
23162224350SCasper H.S. Dik 		if (!maptyp) {
23262224350SCasper H.S. Dik 			dirfound = 0;
23362224350SCasper H.S. Dik 			while ((n = NXTENTRY(&mine, vfp)) != 0) {
23462224350SCasper H.S. Dik 				if (n < 0) {
23562224350SCasper H.S. Dik 					char	*errstr = getErrstr();
23662224350SCasper H.S. Dik 					logerr(gettext("ERROR: garbled entry"));
23762224350SCasper H.S. Dik 					logerr(gettext("pathname: %s"),
23862224350SCasper H.S. Dik 					    (mine.path && *mine.path) ?
23962224350SCasper H.S. Dik 					    mine.path : "Unknown");
24062224350SCasper H.S. Dik 					logerr(gettext("problem: %s"),
24162224350SCasper H.S. Dik 					    (errstr && *errstr) ? errstr :
24262224350SCasper H.S. Dik 					    "Unknown");
24362224350SCasper H.S. Dik 					exit(99);
24462224350SCasper H.S. Dik 				}
24562224350SCasper H.S. Dik 				if (strncmp(mine.path, dirname, len) ||
24662224350SCasper H.S. Dik 				    (mine.path[len] != '/'))
24762224350SCasper H.S. Dik 					break;
24862224350SCasper H.S. Dik 				if (strcmp(drp->d_name, &mine.path[len+1]) ==
24962224350SCasper H.S. Dik 				    0) {
25062224350SCasper H.S. Dik 					dirfound++;
25162224350SCasper H.S. Dik 					break;
25262224350SCasper H.S. Dik 				}
2535c51f124SMoriah Waterland 			}
2545c51f124SMoriah Waterland 
25562224350SCasper H.S. Dik 			vfpGetCurrCharPtr(vfp) = pos;
2565c51f124SMoriah Waterland 
25762224350SCasper H.S. Dik 			if (dirfound)
25862224350SCasper H.S. Dik 				continue;
25962224350SCasper H.S. Dik 		} else {
26062224350SCasper H.S. Dik 			if (srchcfile(&mine, badpath, server) == 1) {
26162224350SCasper H.S. Dik 				while ((pinfo = mine.pinfo) != NULL) {
26262224350SCasper H.S. Dik 					mine.pinfo = pinfo->next;
26362224350SCasper H.S. Dik 					free((char *)pinfo);
2645c51f124SMoriah Waterland 				}
26562224350SCasper H.S. Dik 				continue;
2665c51f124SMoriah Waterland 			}
2675c51f124SMoriah Waterland 		}
2685c51f124SMoriah Waterland 
26962224350SCasper H.S. Dik 		if (fflag) {
27062224350SCasper H.S. Dik 			if (unlink(badpath)) {
27162224350SCasper H.S. Dik 				errflg++;
27262224350SCasper H.S. Dik 				logerr(gettext("ERROR: %s"), badpath);
27362224350SCasper H.S. Dik 				logerr(gettext(ERR_RMHIDDEN));
27462224350SCasper H.S. Dik 			}
27562224350SCasper H.S. Dik 		} else {
27662224350SCasper H.S. Dik 			errflg++;
27762224350SCasper H.S. Dik 			logerr(gettext("ERROR: %s"), badpath);
27862224350SCasper H.S. Dik 			logerr(gettext(ERR_HIDDEN));
2795c51f124SMoriah Waterland 		}
2805c51f124SMoriah Waterland 	}
2815c51f124SMoriah Waterland 
2825c51f124SMoriah Waterland 	(void) closedir(dirfp);
2835c51f124SMoriah Waterland 	return (errflg);
2845c51f124SMoriah Waterland }
2855c51f124SMoriah Waterland 
2865c51f124SMoriah Waterland static char *
findspool(struct cfent * ept)2875c51f124SMoriah Waterland findspool(struct cfent *ept)
2885c51f124SMoriah Waterland {
2895c51f124SMoriah Waterland 	static char	path[2*PATH_MAX+1];
2905c51f124SMoriah Waterland 	char		host[PATH_MAX+1];
2915c51f124SMoriah Waterland 
2925c51f124SMoriah Waterland 	(void) strcpy(host, pkgspool);
2935c51f124SMoriah Waterland 	if (ept->ftype == 'i') {
2945c51f124SMoriah Waterland 		if (strcmp(ept->path, "pkginfo"))
2955c51f124SMoriah Waterland 			(void) strcat(host, "/install");
2965c51f124SMoriah Waterland 	} else if (ept->path[0] == '/') {
2975c51f124SMoriah Waterland 		(void) strcat(host, "/root");
2985c51f124SMoriah Waterland 	} else {
2995c51f124SMoriah Waterland 		(void) strcat(host, "/reloc");
3005c51f124SMoriah Waterland 	}
3015c51f124SMoriah Waterland 
3025c51f124SMoriah Waterland 	(void) snprintf(path, sizeof (path), "%s/%s", host,
303*014740deSToomas Soome 	    ept->path + (ept->path[0] == '/'));
3045c51f124SMoriah Waterland 
3055c51f124SMoriah Waterland 	if (access(path, 0) == 0) {
3065c51f124SMoriah Waterland 		return (path);
3075c51f124SMoriah Waterland 	}
3085c51f124SMoriah Waterland 
3095c51f124SMoriah Waterland 	if ((ept->ftype != 'i') && (ept->volno > 0)) {
3105c51f124SMoriah Waterland 		(void) snprintf(path, sizeof (path),
311*014740deSToomas Soome 		    "%s.%d/%s", host, ept->volno,
312*014740deSToomas Soome 		    ept->path + (ept->path[0] == '/'));
3135c51f124SMoriah Waterland 		if (access(path, 0) == 0) {
3145c51f124SMoriah Waterland 			return (path);
3155c51f124SMoriah Waterland 		}
3165c51f124SMoriah Waterland 	}
3175c51f124SMoriah Waterland 	return (NULL);
3185c51f124SMoriah Waterland }
319