19781SMoriah.Waterland@Sun.COM /*
29781SMoriah.Waterland@Sun.COM * CDDL HEADER START
39781SMoriah.Waterland@Sun.COM *
49781SMoriah.Waterland@Sun.COM * The contents of this file are subject to the terms of the
59781SMoriah.Waterland@Sun.COM * Common Development and Distribution License (the "License").
69781SMoriah.Waterland@Sun.COM * You may not use this file except in compliance with the License.
79781SMoriah.Waterland@Sun.COM *
89781SMoriah.Waterland@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99781SMoriah.Waterland@Sun.COM * or http://www.opensolaris.org/os/licensing.
109781SMoriah.Waterland@Sun.COM * See the License for the specific language governing permissions
119781SMoriah.Waterland@Sun.COM * and limitations under the License.
129781SMoriah.Waterland@Sun.COM *
139781SMoriah.Waterland@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
149781SMoriah.Waterland@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159781SMoriah.Waterland@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
169781SMoriah.Waterland@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
179781SMoriah.Waterland@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
189781SMoriah.Waterland@Sun.COM *
199781SMoriah.Waterland@Sun.COM * CDDL HEADER END
209781SMoriah.Waterland@Sun.COM */
219781SMoriah.Waterland@Sun.COM
229781SMoriah.Waterland@Sun.COM /*
23*9869SCasper.Dik@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
249781SMoriah.Waterland@Sun.COM * Use is subject to license terms.
259781SMoriah.Waterland@Sun.COM */
269781SMoriah.Waterland@Sun.COM
279781SMoriah.Waterland@Sun.COM /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
289781SMoriah.Waterland@Sun.COM /* All Rights Reserved */
299781SMoriah.Waterland@Sun.COM
309781SMoriah.Waterland@Sun.COM
319781SMoriah.Waterland@Sun.COM #include <stdio.h>
329781SMoriah.Waterland@Sun.COM #include <memory.h>
339781SMoriah.Waterland@Sun.COM #include <string.h>
349781SMoriah.Waterland@Sun.COM #include <limits.h>
359781SMoriah.Waterland@Sun.COM #include <dirent.h>
369781SMoriah.Waterland@Sun.COM #include <sys/types.h>
379781SMoriah.Waterland@Sun.COM #include <sys/stat.h>
389781SMoriah.Waterland@Sun.COM #include <pkgstrct.h>
399781SMoriah.Waterland@Sun.COM #include <locale.h>
409781SMoriah.Waterland@Sun.COM #include <libintl.h>
419781SMoriah.Waterland@Sun.COM #include <unistd.h>
429781SMoriah.Waterland@Sun.COM #include <stdlib.h>
439781SMoriah.Waterland@Sun.COM #include "pkglib.h"
449781SMoriah.Waterland@Sun.COM #include "install.h"
459781SMoriah.Waterland@Sun.COM #include "libadm.h"
469781SMoriah.Waterland@Sun.COM #include "libinst.h"
479781SMoriah.Waterland@Sun.COM
489781SMoriah.Waterland@Sun.COM extern int Lflag, lflag, aflag, cflag, fflag, qflag, nflag, xflag, vflag;
499781SMoriah.Waterland@Sun.COM extern char *basedir, *device, pkgspool[];
509781SMoriah.Waterland@Sun.COM
51*9869SCasper.Dik@Sun.COM #define NXTENTRY(P, VFP) (gpkgmapvfp((P), (VFP)))
529781SMoriah.Waterland@Sun.COM
539781SMoriah.Waterland@Sun.COM #define ERR_SPOOLED "ERROR: unable to locate spooled object <%s>"
549781SMoriah.Waterland@Sun.COM #define MSG_NET_OBJ "It is remote and may be available from the network."
559781SMoriah.Waterland@Sun.COM #define ERR_RMHIDDEN "unable to remove hidden file"
569781SMoriah.Waterland@Sun.COM #define ERR_HIDDEN "ERROR: hidden file in exclusive directory"
579781SMoriah.Waterland@Sun.COM
589781SMoriah.Waterland@Sun.COM static char *findspool(struct cfent *ept);
59*9869SCasper.Dik@Sun.COM static int xdir(int maptyp, VFP_T *vfp, PKGserver server, char *dirname);
609781SMoriah.Waterland@Sun.COM
619781SMoriah.Waterland@Sun.COM int
ckentry(int envflag,int maptyp,struct cfent * ept,VFP_T * vfp,PKGserver server)62*9869SCasper.Dik@Sun.COM ckentry(int envflag, int maptyp, struct cfent *ept, VFP_T *vfp,
63*9869SCasper.Dik@Sun.COM PKGserver server)
649781SMoriah.Waterland@Sun.COM {
659781SMoriah.Waterland@Sun.COM int a_err, c_err,
669781SMoriah.Waterland@Sun.COM errflg;
679781SMoriah.Waterland@Sun.COM char *path;
689781SMoriah.Waterland@Sun.COM char *ir = get_inst_root();
699781SMoriah.Waterland@Sun.COM
709781SMoriah.Waterland@Sun.COM if (ept->ftype != 'i') {
719781SMoriah.Waterland@Sun.COM if (envflag)
729781SMoriah.Waterland@Sun.COM mappath(2, ept->path);
739781SMoriah.Waterland@Sun.COM if (!device)
749781SMoriah.Waterland@Sun.COM basepath(ept->path, maptyp ? NULL : basedir, ir);
759781SMoriah.Waterland@Sun.COM }
769781SMoriah.Waterland@Sun.COM canonize(ept->path);
779781SMoriah.Waterland@Sun.COM if (strchr("sl", ept->ftype)) {
789781SMoriah.Waterland@Sun.COM if (envflag) /* -e option */
799781SMoriah.Waterland@Sun.COM mappath(2, ept->ainfo.local);
809781SMoriah.Waterland@Sun.COM if (!RELATIVE(ept->ainfo.local)) { /* Absolute Path */
819781SMoriah.Waterland@Sun.COM if (!device) {
829781SMoriah.Waterland@Sun.COM if (ept->ftype == 'l') /* Hard Link */
839781SMoriah.Waterland@Sun.COM basepath(ept->ainfo.local, NULL, ir);
849781SMoriah.Waterland@Sun.COM }
859781SMoriah.Waterland@Sun.COM }
869781SMoriah.Waterland@Sun.COM if (!RELATIVE(ept->ainfo.local)) /* Absolute Path */
879781SMoriah.Waterland@Sun.COM canonize(ept->ainfo.local);
889781SMoriah.Waterland@Sun.COM }
899781SMoriah.Waterland@Sun.COM if (envflag) {
909781SMoriah.Waterland@Sun.COM if (!strchr("isl", ept->ftype)) {
919781SMoriah.Waterland@Sun.COM mapvar(2, ept->ainfo.owner);
929781SMoriah.Waterland@Sun.COM mapvar(2, ept->ainfo.group);
939781SMoriah.Waterland@Sun.COM }
949781SMoriah.Waterland@Sun.COM }
959781SMoriah.Waterland@Sun.COM
969781SMoriah.Waterland@Sun.COM if (lflag) {
979781SMoriah.Waterland@Sun.COM tputcfent(ept, stdout);
989781SMoriah.Waterland@Sun.COM return (0);
999781SMoriah.Waterland@Sun.COM } else if (Lflag)
1009781SMoriah.Waterland@Sun.COM return (putcfile(ept, stdout));
1019781SMoriah.Waterland@Sun.COM
1029781SMoriah.Waterland@Sun.COM errflg = 0;
1039781SMoriah.Waterland@Sun.COM if (device) {
1049781SMoriah.Waterland@Sun.COM if (strchr("dxslcbp", ept->ftype))
1059781SMoriah.Waterland@Sun.COM return (0);
1069781SMoriah.Waterland@Sun.COM if ((path = findspool(ept)) == NULL) {
1079781SMoriah.Waterland@Sun.COM logerr(gettext(ERR_SPOOLED), ept->path);
1089781SMoriah.Waterland@Sun.COM return (-1);
1099781SMoriah.Waterland@Sun.COM }
1109781SMoriah.Waterland@Sun.COM
1119781SMoriah.Waterland@Sun.COM /*
1129781SMoriah.Waterland@Sun.COM * If the package file attributes are to be sync'd up with
1139781SMoriah.Waterland@Sun.COM * the pkgmap, we fix the attributes here.
1149781SMoriah.Waterland@Sun.COM */
1159781SMoriah.Waterland@Sun.COM if (fflag) {
1169781SMoriah.Waterland@Sun.COM a_err = 0;
1179781SMoriah.Waterland@Sun.COM /* Clear dangerous bits. */
1189781SMoriah.Waterland@Sun.COM ept->ainfo.mode = (ept->ainfo.mode & S_IAMB);
1199781SMoriah.Waterland@Sun.COM /*
1209781SMoriah.Waterland@Sun.COM * Make sure the file is readable by the world and
1219781SMoriah.Waterland@Sun.COM * writeable by root.
1229781SMoriah.Waterland@Sun.COM */
1239781SMoriah.Waterland@Sun.COM ept->ainfo.mode |= 0644;
1249781SMoriah.Waterland@Sun.COM if (!strchr("in", ept->ftype)) {
1259781SMoriah.Waterland@Sun.COM /* Set the safe attributes. */
1269781SMoriah.Waterland@Sun.COM if (a_err = averify(fflag, &ept->ftype,
1279781SMoriah.Waterland@Sun.COM path, &ept->ainfo)) {
1289781SMoriah.Waterland@Sun.COM errflg++;
1299781SMoriah.Waterland@Sun.COM if (!qflag || (a_err != VE_EXIST)) {
1309781SMoriah.Waterland@Sun.COM logerr(gettext("ERROR: %s"),
1319781SMoriah.Waterland@Sun.COM ept->path);
1329781SMoriah.Waterland@Sun.COM logerr(getErrbufAddr());
1339781SMoriah.Waterland@Sun.COM }
1349781SMoriah.Waterland@Sun.COM if (a_err == VE_EXIST)
1359781SMoriah.Waterland@Sun.COM return (-1);
1369781SMoriah.Waterland@Sun.COM }
1379781SMoriah.Waterland@Sun.COM }
1389781SMoriah.Waterland@Sun.COM }
1399781SMoriah.Waterland@Sun.COM /* Report invalid modtimes by passing cverify a -1 */
1409781SMoriah.Waterland@Sun.COM c_err = cverify((!fflag ? (-1) : fflag), &ept->ftype, path,
1419781SMoriah.Waterland@Sun.COM &ept->cinfo, 1);
1429781SMoriah.Waterland@Sun.COM if (c_err) {
1439781SMoriah.Waterland@Sun.COM logerr(gettext("ERROR: %s"), path);
1449781SMoriah.Waterland@Sun.COM logerr(getErrbufAddr());
1459781SMoriah.Waterland@Sun.COM return (-1);
1469781SMoriah.Waterland@Sun.COM }
1479781SMoriah.Waterland@Sun.COM } else {
1489781SMoriah.Waterland@Sun.COM a_err = 0;
1499781SMoriah.Waterland@Sun.COM if (aflag && !strchr("in", ept->ftype)) {
1509781SMoriah.Waterland@Sun.COM /* validate attributes */
1519781SMoriah.Waterland@Sun.COM if (a_err = averify(fflag, &ept->ftype, ept->path,
1529781SMoriah.Waterland@Sun.COM &ept->ainfo)) {
1539781SMoriah.Waterland@Sun.COM errflg++;
1549781SMoriah.Waterland@Sun.COM if (!qflag || (a_err != VE_EXIST)) {
1559781SMoriah.Waterland@Sun.COM logerr(gettext("ERROR: %s"),
1569781SMoriah.Waterland@Sun.COM ept->path);
1579781SMoriah.Waterland@Sun.COM logerr(getErrbufAddr());
1589781SMoriah.Waterland@Sun.COM if (maptyp && ept->pinfo->status ==
1599781SMoriah.Waterland@Sun.COM SERVED_FILE)
1609781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_NET_OBJ));
1619781SMoriah.Waterland@Sun.COM }
1629781SMoriah.Waterland@Sun.COM if (a_err == VE_EXIST)
1639781SMoriah.Waterland@Sun.COM return (-1);
1649781SMoriah.Waterland@Sun.COM }
1659781SMoriah.Waterland@Sun.COM }
1669781SMoriah.Waterland@Sun.COM if (cflag && strchr("fev", ept->ftype) &&
1679781SMoriah.Waterland@Sun.COM (!nflag || ept->ftype != 'v') && /* bug # 1082144 */
1689781SMoriah.Waterland@Sun.COM (!nflag || ept->ftype != 'e')) {
1699781SMoriah.Waterland@Sun.COM /* validate contents */
1709781SMoriah.Waterland@Sun.COM /* Report invalid modtimes by passing cverify a -1 */
1719781SMoriah.Waterland@Sun.COM if (c_err = cverify((!fflag ? (-1) : fflag),
1729781SMoriah.Waterland@Sun.COM &ept->ftype, ept->path, &ept->cinfo, 1)) {
1739781SMoriah.Waterland@Sun.COM errflg++;
1749781SMoriah.Waterland@Sun.COM if (!qflag || (c_err != VE_EXIST)) {
1759781SMoriah.Waterland@Sun.COM if (!a_err)
1769781SMoriah.Waterland@Sun.COM logerr(gettext("ERROR: %s"),
1779781SMoriah.Waterland@Sun.COM ept->path);
1789781SMoriah.Waterland@Sun.COM logerr(getErrbufAddr());
1799781SMoriah.Waterland@Sun.COM if (maptyp && ept->pinfo->status ==
1809781SMoriah.Waterland@Sun.COM SERVED_FILE)
1819781SMoriah.Waterland@Sun.COM logerr(gettext(MSG_NET_OBJ));
1829781SMoriah.Waterland@Sun.COM }
1839781SMoriah.Waterland@Sun.COM if (c_err == VE_EXIST)
1849781SMoriah.Waterland@Sun.COM return (-1);
1859781SMoriah.Waterland@Sun.COM }
1869781SMoriah.Waterland@Sun.COM }
1879781SMoriah.Waterland@Sun.COM if (xflag && (ept->ftype == 'x')) {
1889781SMoriah.Waterland@Sun.COM /* must do verbose here since ept->path will change */
1899781SMoriah.Waterland@Sun.COM path = strdup(ept->path);
190*9869SCasper.Dik@Sun.COM if (xdir(maptyp, vfp, server, path))
1919781SMoriah.Waterland@Sun.COM errflg++;
1929781SMoriah.Waterland@Sun.COM (void) strcpy(ept->path, path);
1939781SMoriah.Waterland@Sun.COM free(path);
1949781SMoriah.Waterland@Sun.COM }
1959781SMoriah.Waterland@Sun.COM }
1969781SMoriah.Waterland@Sun.COM if (vflag)
1979781SMoriah.Waterland@Sun.COM (void) fprintf(stderr, "%s\n", ept->path);
1989781SMoriah.Waterland@Sun.COM return (errflg);
1999781SMoriah.Waterland@Sun.COM }
2009781SMoriah.Waterland@Sun.COM
2019781SMoriah.Waterland@Sun.COM static int
xdir(int maptyp,VFP_T * vfp,PKGserver server,char * dirname)202*9869SCasper.Dik@Sun.COM xdir(int maptyp, VFP_T *vfp, PKGserver server, char *dirname)
2039781SMoriah.Waterland@Sun.COM {
2049781SMoriah.Waterland@Sun.COM DIR *dirfp;
205*9869SCasper.Dik@Sun.COM char badpath[PATH_MAX];
2069781SMoriah.Waterland@Sun.COM int dirfound;
2079781SMoriah.Waterland@Sun.COM int errflg;
2089781SMoriah.Waterland@Sun.COM int len;
2099781SMoriah.Waterland@Sun.COM int n;
2109781SMoriah.Waterland@Sun.COM struct cfent mine;
2119781SMoriah.Waterland@Sun.COM struct dirent *drp;
2129781SMoriah.Waterland@Sun.COM struct pinfo *pinfo;
2139781SMoriah.Waterland@Sun.COM void *pos;
2149781SMoriah.Waterland@Sun.COM
215*9869SCasper.Dik@Sun.COM if (!maptyp)
216*9869SCasper.Dik@Sun.COM pos = vfpGetCurrCharPtr(vfp); /* get current position in file */
2179781SMoriah.Waterland@Sun.COM
2189781SMoriah.Waterland@Sun.COM if ((dirfp = opendir(dirname)) == NULL) {
2199781SMoriah.Waterland@Sun.COM progerr(gettext("unable to open directory <%s>"), dirname);
2209781SMoriah.Waterland@Sun.COM return (-1);
2219781SMoriah.Waterland@Sun.COM }
2229781SMoriah.Waterland@Sun.COM len = strlen(dirname);
2239781SMoriah.Waterland@Sun.COM
2249781SMoriah.Waterland@Sun.COM errflg = 0;
2259781SMoriah.Waterland@Sun.COM (void) memset((char *)&mine, '\0', sizeof (struct cfent));
2269781SMoriah.Waterland@Sun.COM while ((drp = readdir(dirfp)) != NULL) {
2279781SMoriah.Waterland@Sun.COM if (strcmp(drp->d_name, ".") == NULL ||
2289781SMoriah.Waterland@Sun.COM strcmp(drp->d_name, "..") == NULL)
2299781SMoriah.Waterland@Sun.COM continue;
230*9869SCasper.Dik@Sun.COM (void) snprintf(badpath, sizeof (badpath), "%s/%s",
231*9869SCasper.Dik@Sun.COM dirname, drp->d_name);
232*9869SCasper.Dik@Sun.COM if (!maptyp) {
233*9869SCasper.Dik@Sun.COM dirfound = 0;
234*9869SCasper.Dik@Sun.COM while ((n = NXTENTRY(&mine, vfp)) != 0) {
235*9869SCasper.Dik@Sun.COM if (n < 0) {
236*9869SCasper.Dik@Sun.COM char *errstr = getErrstr();
237*9869SCasper.Dik@Sun.COM logerr(gettext("ERROR: garbled entry"));
238*9869SCasper.Dik@Sun.COM logerr(gettext("pathname: %s"),
239*9869SCasper.Dik@Sun.COM (mine.path && *mine.path) ?
240*9869SCasper.Dik@Sun.COM mine.path : "Unknown");
241*9869SCasper.Dik@Sun.COM logerr(gettext("problem: %s"),
242*9869SCasper.Dik@Sun.COM (errstr && *errstr) ? errstr :
243*9869SCasper.Dik@Sun.COM "Unknown");
244*9869SCasper.Dik@Sun.COM exit(99);
245*9869SCasper.Dik@Sun.COM }
246*9869SCasper.Dik@Sun.COM if (strncmp(mine.path, dirname, len) ||
247*9869SCasper.Dik@Sun.COM (mine.path[len] != '/'))
248*9869SCasper.Dik@Sun.COM break;
249*9869SCasper.Dik@Sun.COM if (strcmp(drp->d_name, &mine.path[len+1]) ==
250*9869SCasper.Dik@Sun.COM 0) {
251*9869SCasper.Dik@Sun.COM dirfound++;
252*9869SCasper.Dik@Sun.COM break;
253*9869SCasper.Dik@Sun.COM }
2549781SMoriah.Waterland@Sun.COM }
255*9869SCasper.Dik@Sun.COM
256*9869SCasper.Dik@Sun.COM vfpGetCurrCharPtr(vfp) = pos;
257*9869SCasper.Dik@Sun.COM
258*9869SCasper.Dik@Sun.COM if (dirfound)
259*9869SCasper.Dik@Sun.COM continue;
260*9869SCasper.Dik@Sun.COM } else {
261*9869SCasper.Dik@Sun.COM if (srchcfile(&mine, badpath, server) == 1) {
262*9869SCasper.Dik@Sun.COM while ((pinfo = mine.pinfo) != NULL) {
263*9869SCasper.Dik@Sun.COM mine.pinfo = pinfo->next;
264*9869SCasper.Dik@Sun.COM free((char *)pinfo);
265*9869SCasper.Dik@Sun.COM }
266*9869SCasper.Dik@Sun.COM continue;
2679781SMoriah.Waterland@Sun.COM }
2689781SMoriah.Waterland@Sun.COM }
2699781SMoriah.Waterland@Sun.COM
270*9869SCasper.Dik@Sun.COM if (fflag) {
271*9869SCasper.Dik@Sun.COM if (unlink(badpath)) {
2729781SMoriah.Waterland@Sun.COM errflg++;
2739781SMoriah.Waterland@Sun.COM logerr(gettext("ERROR: %s"), badpath);
274*9869SCasper.Dik@Sun.COM logerr(gettext(ERR_RMHIDDEN));
2759781SMoriah.Waterland@Sun.COM }
276*9869SCasper.Dik@Sun.COM } else {
277*9869SCasper.Dik@Sun.COM errflg++;
278*9869SCasper.Dik@Sun.COM logerr(gettext("ERROR: %s"), badpath);
279*9869SCasper.Dik@Sun.COM logerr(gettext(ERR_HIDDEN));
2809781SMoriah.Waterland@Sun.COM }
2819781SMoriah.Waterland@Sun.COM }
2829781SMoriah.Waterland@Sun.COM
2839781SMoriah.Waterland@Sun.COM (void) closedir(dirfp);
2849781SMoriah.Waterland@Sun.COM return (errflg);
2859781SMoriah.Waterland@Sun.COM }
2869781SMoriah.Waterland@Sun.COM
2879781SMoriah.Waterland@Sun.COM static char *
findspool(struct cfent * ept)2889781SMoriah.Waterland@Sun.COM findspool(struct cfent *ept)
2899781SMoriah.Waterland@Sun.COM {
2909781SMoriah.Waterland@Sun.COM static char path[2*PATH_MAX+1];
2919781SMoriah.Waterland@Sun.COM char host[PATH_MAX+1];
2929781SMoriah.Waterland@Sun.COM
2939781SMoriah.Waterland@Sun.COM (void) strcpy(host, pkgspool);
2949781SMoriah.Waterland@Sun.COM if (ept->ftype == 'i') {
2959781SMoriah.Waterland@Sun.COM if (strcmp(ept->path, "pkginfo"))
2969781SMoriah.Waterland@Sun.COM (void) strcat(host, "/install");
2979781SMoriah.Waterland@Sun.COM } else if (ept->path[0] == '/') {
2989781SMoriah.Waterland@Sun.COM (void) strcat(host, "/root");
2999781SMoriah.Waterland@Sun.COM } else {
3009781SMoriah.Waterland@Sun.COM (void) strcat(host, "/reloc");
3019781SMoriah.Waterland@Sun.COM }
3029781SMoriah.Waterland@Sun.COM
3039781SMoriah.Waterland@Sun.COM (void) snprintf(path, sizeof (path), "%s/%s", host,
3049781SMoriah.Waterland@Sun.COM ept->path + (ept->path[0] == '/'));
3059781SMoriah.Waterland@Sun.COM
3069781SMoriah.Waterland@Sun.COM if (access(path, 0) == 0) {
3079781SMoriah.Waterland@Sun.COM return (path);
3089781SMoriah.Waterland@Sun.COM }
3099781SMoriah.Waterland@Sun.COM
3109781SMoriah.Waterland@Sun.COM if ((ept->ftype != 'i') && (ept->volno > 0)) {
3119781SMoriah.Waterland@Sun.COM (void) snprintf(path, sizeof (path),
3129781SMoriah.Waterland@Sun.COM "%s.%d/%s", host, ept->volno,
3139781SMoriah.Waterland@Sun.COM ept->path + (ept->path[0] == '/'));
3149781SMoriah.Waterland@Sun.COM if (access(path, 0) == 0) {
3159781SMoriah.Waterland@Sun.COM return (path);
3169781SMoriah.Waterland@Sun.COM }
3179781SMoriah.Waterland@Sun.COM }
3189781SMoriah.Waterland@Sun.COM return (NULL);
3199781SMoriah.Waterland@Sun.COM }
320