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 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 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 * 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