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