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 /*
23*62224350SCasper 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
51*62224350SCasper 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);
59*62224350SCasper 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)62*62224350SCasper H.S. Dik ckentry(int envflag, int maptyp, struct cfent *ept, VFP_T *vfp,
63*62224350SCasper H.S. Dik PKGserver server)
645c51f124SMoriah Waterland {
655c51f124SMoriah Waterland int a_err, c_err,
665c51f124SMoriah Waterland errflg;
675c51f124SMoriah Waterland char *path;
685c51f124SMoriah Waterland char *ir = get_inst_root();
695c51f124SMoriah Waterland
705c51f124SMoriah Waterland if (ept->ftype != 'i') {
715c51f124SMoriah Waterland if (envflag)
725c51f124SMoriah Waterland mappath(2, ept->path);
735c51f124SMoriah Waterland if (!device)
745c51f124SMoriah Waterland basepath(ept->path, maptyp ? NULL : basedir, ir);
755c51f124SMoriah Waterland }
765c51f124SMoriah Waterland canonize(ept->path);
775c51f124SMoriah Waterland if (strchr("sl", ept->ftype)) {
785c51f124SMoriah Waterland if (envflag) /* -e option */
795c51f124SMoriah Waterland mappath(2, ept->ainfo.local);
805c51f124SMoriah Waterland if (!RELATIVE(ept->ainfo.local)) { /* Absolute Path */
815c51f124SMoriah Waterland if (!device) {
825c51f124SMoriah Waterland if (ept->ftype == 'l') /* Hard Link */
835c51f124SMoriah Waterland basepath(ept->ainfo.local, NULL, ir);
845c51f124SMoriah Waterland }
855c51f124SMoriah Waterland }
865c51f124SMoriah Waterland if (!RELATIVE(ept->ainfo.local)) /* Absolute Path */
875c51f124SMoriah Waterland canonize(ept->ainfo.local);
885c51f124SMoriah Waterland }
895c51f124SMoriah Waterland if (envflag) {
905c51f124SMoriah Waterland if (!strchr("isl", ept->ftype)) {
915c51f124SMoriah Waterland mapvar(2, ept->ainfo.owner);
925c51f124SMoriah Waterland mapvar(2, ept->ainfo.group);
935c51f124SMoriah Waterland }
945c51f124SMoriah Waterland }
955c51f124SMoriah Waterland
965c51f124SMoriah Waterland if (lflag) {
975c51f124SMoriah Waterland tputcfent(ept, stdout);
985c51f124SMoriah Waterland return (0);
995c51f124SMoriah Waterland } else if (Lflag)
1005c51f124SMoriah Waterland return (putcfile(ept, stdout));
1015c51f124SMoriah Waterland
1025c51f124SMoriah Waterland errflg = 0;
1035c51f124SMoriah Waterland if (device) {
1045c51f124SMoriah Waterland if (strchr("dxslcbp", ept->ftype))
1055c51f124SMoriah Waterland return (0);
1065c51f124SMoriah Waterland if ((path = findspool(ept)) == NULL) {
1075c51f124SMoriah Waterland logerr(gettext(ERR_SPOOLED), ept->path);
1085c51f124SMoriah Waterland return (-1);
1095c51f124SMoriah Waterland }
1105c51f124SMoriah Waterland
1115c51f124SMoriah Waterland /*
1125c51f124SMoriah Waterland * If the package file attributes are to be sync'd up with
1135c51f124SMoriah Waterland * the pkgmap, we fix the attributes here.
1145c51f124SMoriah Waterland */
1155c51f124SMoriah Waterland if (fflag) {
1165c51f124SMoriah Waterland a_err = 0;
1175c51f124SMoriah Waterland /* Clear dangerous bits. */
1185c51f124SMoriah Waterland ept->ainfo.mode = (ept->ainfo.mode & S_IAMB);
1195c51f124SMoriah Waterland /*
1205c51f124SMoriah Waterland * Make sure the file is readable by the world and
1215c51f124SMoriah Waterland * writeable by root.
1225c51f124SMoriah Waterland */
1235c51f124SMoriah Waterland ept->ainfo.mode |= 0644;
1245c51f124SMoriah Waterland if (!strchr("in", ept->ftype)) {
1255c51f124SMoriah Waterland /* Set the safe attributes. */
1265c51f124SMoriah Waterland if (a_err = averify(fflag, &ept->ftype,
1275c51f124SMoriah Waterland path, &ept->ainfo)) {
1285c51f124SMoriah Waterland errflg++;
1295c51f124SMoriah Waterland if (!qflag || (a_err != VE_EXIST)) {
1305c51f124SMoriah Waterland logerr(gettext("ERROR: %s"),
1315c51f124SMoriah Waterland ept->path);
1325c51f124SMoriah Waterland logerr(getErrbufAddr());
1335c51f124SMoriah Waterland }
1345c51f124SMoriah Waterland if (a_err == VE_EXIST)
1355c51f124SMoriah Waterland return (-1);
1365c51f124SMoriah Waterland }
1375c51f124SMoriah Waterland }
1385c51f124SMoriah Waterland }
1395c51f124SMoriah Waterland /* Report invalid modtimes by passing cverify a -1 */
1405c51f124SMoriah Waterland c_err = cverify((!fflag ? (-1) : fflag), &ept->ftype, path,
1415c51f124SMoriah Waterland &ept->cinfo, 1);
1425c51f124SMoriah Waterland if (c_err) {
1435c51f124SMoriah Waterland logerr(gettext("ERROR: %s"), path);
1445c51f124SMoriah Waterland logerr(getErrbufAddr());
1455c51f124SMoriah Waterland return (-1);
1465c51f124SMoriah Waterland }
1475c51f124SMoriah Waterland } else {
1485c51f124SMoriah Waterland a_err = 0;
1495c51f124SMoriah Waterland if (aflag && !strchr("in", ept->ftype)) {
1505c51f124SMoriah Waterland /* validate attributes */
1515c51f124SMoriah Waterland if (a_err = averify(fflag, &ept->ftype, ept->path,
1525c51f124SMoriah Waterland &ept->ainfo)) {
1535c51f124SMoriah Waterland errflg++;
1545c51f124SMoriah Waterland if (!qflag || (a_err != VE_EXIST)) {
1555c51f124SMoriah Waterland logerr(gettext("ERROR: %s"),
1565c51f124SMoriah Waterland ept->path);
1575c51f124SMoriah Waterland logerr(getErrbufAddr());
1585c51f124SMoriah Waterland if (maptyp && ept->pinfo->status ==
1595c51f124SMoriah Waterland SERVED_FILE)
1605c51f124SMoriah Waterland logerr(gettext(MSG_NET_OBJ));
1615c51f124SMoriah Waterland }
1625c51f124SMoriah Waterland if (a_err == VE_EXIST)
1635c51f124SMoriah Waterland return (-1);
1645c51f124SMoriah Waterland }
1655c51f124SMoriah Waterland }
1665c51f124SMoriah Waterland if (cflag && strchr("fev", ept->ftype) &&
1675c51f124SMoriah Waterland (!nflag || ept->ftype != 'v') && /* bug # 1082144 */
1685c51f124SMoriah Waterland (!nflag || ept->ftype != 'e')) {
1695c51f124SMoriah Waterland /* validate contents */
1705c51f124SMoriah Waterland /* Report invalid modtimes by passing cverify a -1 */
1715c51f124SMoriah Waterland if (c_err = cverify((!fflag ? (-1) : fflag),
1725c51f124SMoriah Waterland &ept->ftype, ept->path, &ept->cinfo, 1)) {
1735c51f124SMoriah Waterland errflg++;
1745c51f124SMoriah Waterland if (!qflag || (c_err != VE_EXIST)) {
1755c51f124SMoriah Waterland if (!a_err)
1765c51f124SMoriah Waterland logerr(gettext("ERROR: %s"),
1775c51f124SMoriah Waterland ept->path);
1785c51f124SMoriah Waterland logerr(getErrbufAddr());
1795c51f124SMoriah Waterland if (maptyp && ept->pinfo->status ==
1805c51f124SMoriah Waterland SERVED_FILE)
1815c51f124SMoriah Waterland logerr(gettext(MSG_NET_OBJ));
1825c51f124SMoriah Waterland }
1835c51f124SMoriah Waterland if (c_err == VE_EXIST)
1845c51f124SMoriah Waterland return (-1);
1855c51f124SMoriah Waterland }
1865c51f124SMoriah Waterland }
1875c51f124SMoriah Waterland if (xflag && (ept->ftype == 'x')) {
1885c51f124SMoriah Waterland /* must do verbose here since ept->path will change */
1895c51f124SMoriah Waterland path = strdup(ept->path);
190*62224350SCasper H.S. Dik if (xdir(maptyp, vfp, server, path))
1915c51f124SMoriah Waterland errflg++;
1925c51f124SMoriah Waterland (void) strcpy(ept->path, path);
1935c51f124SMoriah Waterland free(path);
1945c51f124SMoriah Waterland }
1955c51f124SMoriah Waterland }
1965c51f124SMoriah Waterland if (vflag)
1975c51f124SMoriah Waterland (void) fprintf(stderr, "%s\n", ept->path);
1985c51f124SMoriah Waterland return (errflg);
1995c51f124SMoriah Waterland }
2005c51f124SMoriah Waterland
2015c51f124SMoriah Waterland static int
xdir(int maptyp,VFP_T * vfp,PKGserver server,char * dirname)202*62224350SCasper H.S. Dik xdir(int maptyp, VFP_T *vfp, PKGserver server, char *dirname)
2035c51f124SMoriah Waterland {
2045c51f124SMoriah Waterland DIR *dirfp;
205*62224350SCasper H.S. Dik char badpath[PATH_MAX];
2065c51f124SMoriah Waterland int dirfound;
2075c51f124SMoriah Waterland int errflg;
2085c51f124SMoriah Waterland int len;
2095c51f124SMoriah Waterland int n;
2105c51f124SMoriah Waterland struct cfent mine;
2115c51f124SMoriah Waterland struct dirent *drp;
2125c51f124SMoriah Waterland struct pinfo *pinfo;
2135c51f124SMoriah Waterland void *pos;
2145c51f124SMoriah Waterland
215*62224350SCasper H.S. Dik if (!maptyp)
2165c51f124SMoriah Waterland pos = vfpGetCurrCharPtr(vfp); /* get current position in file */
2175c51f124SMoriah Waterland
2185c51f124SMoriah Waterland if ((dirfp = opendir(dirname)) == NULL) {
2195c51f124SMoriah Waterland progerr(gettext("unable to open directory <%s>"), dirname);
2205c51f124SMoriah Waterland return (-1);
2215c51f124SMoriah Waterland }
2225c51f124SMoriah Waterland len = strlen(dirname);
2235c51f124SMoriah Waterland
2245c51f124SMoriah Waterland errflg = 0;
2255c51f124SMoriah Waterland (void) memset((char *)&mine, '\0', sizeof (struct cfent));
2265c51f124SMoriah Waterland while ((drp = readdir(dirfp)) != NULL) {
2275c51f124SMoriah Waterland if (strcmp(drp->d_name, ".") == NULL ||
2285c51f124SMoriah Waterland strcmp(drp->d_name, "..") == NULL)
2295c51f124SMoriah Waterland continue;
230*62224350SCasper H.S. Dik (void) snprintf(badpath, sizeof (badpath), "%s/%s",
231*62224350SCasper H.S. Dik dirname, drp->d_name);
232*62224350SCasper H.S. Dik if (!maptyp) {
2335c51f124SMoriah Waterland dirfound = 0;
2345c51f124SMoriah Waterland while ((n = NXTENTRY(&mine, vfp)) != 0) {
2355c51f124SMoriah Waterland if (n < 0) {
2365c51f124SMoriah Waterland char *errstr = getErrstr();
2375c51f124SMoriah Waterland logerr(gettext("ERROR: garbled entry"));
2385c51f124SMoriah Waterland logerr(gettext("pathname: %s"),
239*62224350SCasper H.S. Dik (mine.path && *mine.path) ?
240*62224350SCasper H.S. Dik mine.path : "Unknown");
2415c51f124SMoriah Waterland logerr(gettext("problem: %s"),
242*62224350SCasper H.S. Dik (errstr && *errstr) ? errstr :
243*62224350SCasper H.S. Dik "Unknown");
2445c51f124SMoriah Waterland exit(99);
2455c51f124SMoriah Waterland }
2465c51f124SMoriah Waterland if (strncmp(mine.path, dirname, len) ||
2475c51f124SMoriah Waterland (mine.path[len] != '/'))
2485c51f124SMoriah Waterland break;
249*62224350SCasper H.S. Dik if (strcmp(drp->d_name, &mine.path[len+1]) ==
250*62224350SCasper H.S. Dik 0) {
2515c51f124SMoriah Waterland dirfound++;
2525c51f124SMoriah Waterland break;
2535c51f124SMoriah Waterland }
2545c51f124SMoriah Waterland }
2555c51f124SMoriah Waterland
2565c51f124SMoriah Waterland vfpGetCurrCharPtr(vfp) = pos;
2575c51f124SMoriah Waterland
258*62224350SCasper H.S. Dik if (dirfound)
259*62224350SCasper H.S. Dik continue;
260*62224350SCasper H.S. Dik } else {
261*62224350SCasper H.S. Dik if (srchcfile(&mine, badpath, server) == 1) {
262*62224350SCasper H.S. Dik while ((pinfo = mine.pinfo) != NULL) {
263*62224350SCasper H.S. Dik mine.pinfo = pinfo->next;
264*62224350SCasper H.S. Dik free((char *)pinfo);
265*62224350SCasper H.S. Dik }
266*62224350SCasper H.S. Dik continue;
267*62224350SCasper H.S. Dik }
268*62224350SCasper H.S. Dik }
269*62224350SCasper H.S. Dik
2705c51f124SMoriah Waterland if (fflag) {
2715c51f124SMoriah Waterland if (unlink(badpath)) {
2725c51f124SMoriah Waterland errflg++;
2735c51f124SMoriah Waterland logerr(gettext("ERROR: %s"), badpath);
2745c51f124SMoriah Waterland logerr(gettext(ERR_RMHIDDEN));
2755c51f124SMoriah Waterland }
2765c51f124SMoriah Waterland } else {
2775c51f124SMoriah Waterland errflg++;
2785c51f124SMoriah Waterland logerr(gettext("ERROR: %s"), badpath);
2795c51f124SMoriah Waterland logerr(gettext(ERR_HIDDEN));
2805c51f124SMoriah Waterland }
2815c51f124SMoriah Waterland }
2825c51f124SMoriah Waterland
2835c51f124SMoriah Waterland (void) closedir(dirfp);
2845c51f124SMoriah Waterland return (errflg);
2855c51f124SMoriah Waterland }
2865c51f124SMoriah Waterland
2875c51f124SMoriah Waterland static char *
findspool(struct cfent * ept)2885c51f124SMoriah Waterland findspool(struct cfent *ept)
2895c51f124SMoriah Waterland {
2905c51f124SMoriah Waterland static char path[2*PATH_MAX+1];
2915c51f124SMoriah Waterland char host[PATH_MAX+1];
2925c51f124SMoriah Waterland
2935c51f124SMoriah Waterland (void) strcpy(host, pkgspool);
2945c51f124SMoriah Waterland if (ept->ftype == 'i') {
2955c51f124SMoriah Waterland if (strcmp(ept->path, "pkginfo"))
2965c51f124SMoriah Waterland (void) strcat(host, "/install");
2975c51f124SMoriah Waterland } else if (ept->path[0] == '/') {
2985c51f124SMoriah Waterland (void) strcat(host, "/root");
2995c51f124SMoriah Waterland } else {
3005c51f124SMoriah Waterland (void) strcat(host, "/reloc");
3015c51f124SMoriah Waterland }
3025c51f124SMoriah Waterland
3035c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), "%s/%s", host,
3045c51f124SMoriah Waterland ept->path + (ept->path[0] == '/'));
3055c51f124SMoriah Waterland
3065c51f124SMoriah Waterland if (access(path, 0) == 0) {
3075c51f124SMoriah Waterland return (path);
3085c51f124SMoriah Waterland }
3095c51f124SMoriah Waterland
3105c51f124SMoriah Waterland if ((ept->ftype != 'i') && (ept->volno > 0)) {
3115c51f124SMoriah Waterland (void) snprintf(path, sizeof (path),
3125c51f124SMoriah Waterland "%s.%d/%s", host, ept->volno,
3135c51f124SMoriah Waterland ept->path + (ept->path[0] == '/'));
3145c51f124SMoriah Waterland if (access(path, 0) == 0) {
3155c51f124SMoriah Waterland return (path);
3165c51f124SMoriah Waterland }
3175c51f124SMoriah Waterland }
3185c51f124SMoriah Waterland return (NULL);
3195c51f124SMoriah Waterland }
320