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 2009 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 <limits.h> 33*5c51f124SMoriah Waterland #include <stdlib.h> 34*5c51f124SMoriah Waterland #include <unistd.h> 35*5c51f124SMoriah Waterland #include <string.h> 36*5c51f124SMoriah Waterland #include <signal.h> 37*5c51f124SMoriah Waterland #include <errno.h> 38*5c51f124SMoriah Waterland #include <fcntl.h> 39*5c51f124SMoriah Waterland #include <sys/stat.h> 40*5c51f124SMoriah Waterland #include <sys/types.h> 41*5c51f124SMoriah Waterland #include <pkgstrct.h> 42*5c51f124SMoriah Waterland #include <pkginfo.h> 43*5c51f124SMoriah Waterland #include <pkglocs.h> 44*5c51f124SMoriah Waterland #include <locale.h> 45*5c51f124SMoriah Waterland #include <libintl.h> 46*5c51f124SMoriah Waterland #include <assert.h> 47*5c51f124SMoriah Waterland #include <cfext.h> 48*5c51f124SMoriah Waterland #include <instzones_api.h> 49*5c51f124SMoriah Waterland #include <pkglib.h> 50*5c51f124SMoriah Waterland #include <install.h> 51*5c51f124SMoriah Waterland #include <libinst.h> 52*5c51f124SMoriah Waterland #include <libadm.h> 53*5c51f124SMoriah Waterland #include <messages.h> 54*5c51f124SMoriah Waterland 55*5c51f124SMoriah Waterland struct cfent **eptlist; 56*5c51f124SMoriah Waterland extern int eptnum; 57*5c51f124SMoriah Waterland 58*5c51f124SMoriah Waterland extern char *pkgdir; 59*5c51f124SMoriah Waterland extern char **environ; 60*5c51f124SMoriah Waterland 61*5c51f124SMoriah Waterland /* quit.c */ 62*5c51f124SMoriah Waterland extern sighdlrFunc_t *quitGetTrapHandler(void); 63*5c51f124SMoriah Waterland extern void quitSetSilentExit(boolean_t a_silentExit); 64*5c51f124SMoriah Waterland extern void quitSetZoneName(char *a_zoneName); 65*5c51f124SMoriah Waterland 66*5c51f124SMoriah Waterland 67*5c51f124SMoriah Waterland 68*5c51f124SMoriah Waterland /* check.c */ 69*5c51f124SMoriah Waterland extern void rcksetPreremoveCheck(boolean_t); 70*5c51f124SMoriah Waterland extern void rcksetZoneName(char *); 71*5c51f124SMoriah Waterland extern int rckpriv(void); 72*5c51f124SMoriah Waterland extern int rckdepend(void); 73*5c51f124SMoriah Waterland extern int rckrunlevel(void); 74*5c51f124SMoriah Waterland 75*5c51f124SMoriah Waterland /* predepend.c */ 76*5c51f124SMoriah Waterland extern void predepend(char *oldpkg); 77*5c51f124SMoriah Waterland 78*5c51f124SMoriah Waterland /* delmap.c */ 79*5c51f124SMoriah Waterland extern int delmap(int flag, char *pkginst); 80*5c51f124SMoriah Waterland 81*5c51f124SMoriah Waterland #define DEFPATH "/sbin:/usr/sbin:/usr/bin" 82*5c51f124SMoriah Waterland 83*5c51f124SMoriah Waterland #ifdef ALLOW_EXCEPTION_PKG_LIST 84*5c51f124SMoriah Waterland #define SCRIPT 0 /* Tells exception_pkg() which pkg list to use */ 85*5c51f124SMoriah Waterland #define LINK 1 86*5c51f124SMoriah Waterland #endif 87*5c51f124SMoriah Waterland 88*5c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 89*5c51f124SMoriah Waterland #define TEXT_DOMAIN "SYS_TEST" 90*5c51f124SMoriah Waterland #endif 91*5c51f124SMoriah Waterland 92*5c51f124SMoriah Waterland /* This is the text for the "-O inherited-filesystem=" option */ 93*5c51f124SMoriah Waterland 94*5c51f124SMoriah Waterland #define INHERITFS "inherited-filesystem=" 95*5c51f124SMoriah Waterland #define INHERITFS_LEN ((sizeof (INHERITFS))-1) 96*5c51f124SMoriah Waterland 97*5c51f124SMoriah Waterland /* This is the text for the "-O parent-zone-name=" option */ 98*5c51f124SMoriah Waterland 99*5c51f124SMoriah Waterland #define PARENTZONENAME "parent-zone-name=" 100*5c51f124SMoriah Waterland #define PARENTZONENAME_LEN ((sizeof (PARENTZONENAME))-1) 101*5c51f124SMoriah Waterland 102*5c51f124SMoriah Waterland /* This is the text for the "-O parent-zone-type=" option */ 103*5c51f124SMoriah Waterland 104*5c51f124SMoriah Waterland #define PARENTZONETYPE "parent-zone-type=" 105*5c51f124SMoriah Waterland #define PARENTZONETYPE_LEN ((sizeof (PARENTZONETYPE))-1) 106*5c51f124SMoriah Waterland 107*5c51f124SMoriah Waterland struct admin adm; /* holds info about installation admin */ 108*5c51f124SMoriah Waterland int dreboot; /* non-zero if reboot required after installation */ 109*5c51f124SMoriah Waterland int ireboot; /* non-zero if immediate reboot required */ 110*5c51f124SMoriah Waterland int failflag; /* non-zero if fatal error has occurred */ 111*5c51f124SMoriah Waterland int warnflag; /* non-zero if non-fatal error has occurred */ 112*5c51f124SMoriah Waterland int pkgverbose; /* non-zero if verbose mode is selected */ 113*5c51f124SMoriah Waterland int started; 114*5c51f124SMoriah Waterland int nocnflct = 0; /* pkgdbmerg needs this defined */ 115*5c51f124SMoriah Waterland int nosetuid = 0; /* pkgdbmerg needs this defined */ 116*5c51f124SMoriah Waterland 117*5c51f124SMoriah Waterland char *pkginst; /* current package (source) instance to process */ 118*5c51f124SMoriah Waterland 119*5c51f124SMoriah Waterland int dbchg; 120*5c51f124SMoriah Waterland char *msgtext; 121*5c51f124SMoriah Waterland char pkgloc[PATH_MAX]; 122*5c51f124SMoriah Waterland 123*5c51f124SMoriah Waterland /* 124*5c51f124SMoriah Waterland * The following variable is the name of the device to which stdin 125*5c51f124SMoriah Waterland * is connected during execution of a procedure script. /dev/null is 126*5c51f124SMoriah Waterland * correct for all ABI compliant packages. For non-ABI-compliant 127*5c51f124SMoriah Waterland * packages, the '-o' command line switch changes this to /dev/tty 128*5c51f124SMoriah Waterland * to allow user interaction during these scripts. -- JST 129*5c51f124SMoriah Waterland */ 130*5c51f124SMoriah Waterland static char *script_in = PROC_STDIN; /* assume ABI compliance */ 131*5c51f124SMoriah Waterland 132*5c51f124SMoriah Waterland static char *client_mntdir; /* mount point for client's basedir */ 133*5c51f124SMoriah Waterland static char pkgbin[PATH_MAX], 134*5c51f124SMoriah Waterland rlockfile[PATH_MAX], 135*5c51f124SMoriah Waterland *admnfile, /* file to use for installation admin */ 136*5c51f124SMoriah Waterland *tmpdir; /* location to place temporary files */ 137*5c51f124SMoriah Waterland 138*5c51f124SMoriah Waterland static boolean_t path_valid(char *path); 139*5c51f124SMoriah Waterland static void ckreturn(int retcode, char *msg); 140*5c51f124SMoriah Waterland static void rmclass(char *aclass, int rm_remote, char *a_zoneName); 141*5c51f124SMoriah Waterland static void usage(void); 142*5c51f124SMoriah Waterland 143*5c51f124SMoriah Waterland /* 144*5c51f124SMoriah Waterland * Set by -O debug: debug output is enabled? 145*5c51f124SMoriah Waterland */ 146*5c51f124SMoriah Waterland static boolean_t debugFlag = B_FALSE; 147*5c51f124SMoriah Waterland 148*5c51f124SMoriah Waterland /* 149*5c51f124SMoriah Waterland * Set by -O preremovecheck: do remove dependency checking only 150*5c51f124SMoriah Waterland */ 151*5c51f124SMoriah Waterland static boolean_t preremoveCheck = B_FALSE; 152*5c51f124SMoriah Waterland 153*5c51f124SMoriah Waterland /* Set by -O parent-zone-name= */ 154*5c51f124SMoriah Waterland 155*5c51f124SMoriah Waterland static char *parentZoneName = (char *)NULL; 156*5c51f124SMoriah Waterland 157*5c51f124SMoriah Waterland /* Set by -O parent-zone-type= */ 158*5c51f124SMoriah Waterland 159*5c51f124SMoriah Waterland static char *parentZoneType = (char *)NULL; 160*5c51f124SMoriah Waterland 161*5c51f124SMoriah Waterland static int nointeract; /* != 0 no interaction with user should occur */ 162*5c51f124SMoriah Waterland 163*5c51f124SMoriah Waterland 164*5c51f124SMoriah Waterland 165*5c51f124SMoriah Waterland int 166*5c51f124SMoriah Waterland main(int argc, char *argv[]) 167*5c51f124SMoriah Waterland { 168*5c51f124SMoriah Waterland FILE *fp; 169*5c51f124SMoriah Waterland char *abi_comp_ptr; 170*5c51f124SMoriah Waterland char *abi_sym_ptr; 171*5c51f124SMoriah Waterland char *p; 172*5c51f124SMoriah Waterland char *prog_full_name = NULL; 173*5c51f124SMoriah Waterland char *pt; 174*5c51f124SMoriah Waterland char *value; 175*5c51f124SMoriah Waterland char *vfstab_file = NULL; 176*5c51f124SMoriah Waterland char *zoneName = (char *)NULL; 177*5c51f124SMoriah Waterland char cmdbin[PATH_MAX]; 178*5c51f124SMoriah Waterland char param[MAX_PKG_PARAM_LENGTH]; 179*5c51f124SMoriah Waterland char path[PATH_MAX]; 180*5c51f124SMoriah Waterland char script[PATH_MAX]; 181*5c51f124SMoriah Waterland int c; 182*5c51f124SMoriah Waterland int err; 183*5c51f124SMoriah Waterland int fd; 184*5c51f124SMoriah Waterland int i; 185*5c51f124SMoriah Waterland int map_client = 1; 186*5c51f124SMoriah Waterland int n; 187*5c51f124SMoriah Waterland int nodelete = 0; /* do not delete file or run scripts */ 188*5c51f124SMoriah Waterland int pkgrmremote = 0; /* dont remove remote objects */ 189*5c51f124SMoriah Waterland struct sigaction nact; 190*5c51f124SMoriah Waterland struct sigaction oact; 191*5c51f124SMoriah Waterland 192*5c51f124SMoriah Waterland /* reset contents of all default paths */ 193*5c51f124SMoriah Waterland 194*5c51f124SMoriah Waterland (void) memset(cmdbin, '\0', sizeof (cmdbin)); 195*5c51f124SMoriah Waterland 196*5c51f124SMoriah Waterland /* initialize locale environment */ 197*5c51f124SMoriah Waterland 198*5c51f124SMoriah Waterland (void) setlocale(LC_ALL, ""); 199*5c51f124SMoriah Waterland (void) textdomain(TEXT_DOMAIN); 200*5c51f124SMoriah Waterland 201*5c51f124SMoriah Waterland /* initialize program name */ 202*5c51f124SMoriah Waterland 203*5c51f124SMoriah Waterland prog_full_name = argv[0]; 204*5c51f124SMoriah Waterland (void) set_prog_name(argv[0]); 205*5c51f124SMoriah Waterland 206*5c51f124SMoriah Waterland /* tell spmi zones interface how to access package output functions */ 207*5c51f124SMoriah Waterland 208*5c51f124SMoriah Waterland z_set_output_functions(echo, echoDebug, progerr); 209*5c51f124SMoriah Waterland 210*5c51f124SMoriah Waterland /* exit if not root */ 211*5c51f124SMoriah Waterland 212*5c51f124SMoriah Waterland if (getuid()) { 213*5c51f124SMoriah Waterland progerr(ERR_NOT_ROOT, get_prog_name()); 214*5c51f124SMoriah Waterland exit(1); 215*5c51f124SMoriah Waterland /* NOTREACHED */ 216*5c51f124SMoriah Waterland } 217*5c51f124SMoriah Waterland 218*5c51f124SMoriah Waterland /* Read PKG_INSTALL_ROOT from the environment, if it's there. */ 219*5c51f124SMoriah Waterland 220*5c51f124SMoriah Waterland if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) { 221*5c51f124SMoriah Waterland progerr(ERR_ROOT_SET); 222*5c51f124SMoriah Waterland exit(1); 223*5c51f124SMoriah Waterland } 224*5c51f124SMoriah Waterland 225*5c51f124SMoriah Waterland /* parse command line options */ 226*5c51f124SMoriah Waterland 227*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, "?Aa:b:FMN:nO:oR:V:vy")) != EOF) { 228*5c51f124SMoriah Waterland switch (c) { 229*5c51f124SMoriah Waterland /* 230*5c51f124SMoriah Waterland * Same as pkgrm: Allow admin to remove package objects from 231*5c51f124SMoriah Waterland * a shared area from a reference client. 232*5c51f124SMoriah Waterland */ 233*5c51f124SMoriah Waterland case 'A': 234*5c51f124SMoriah Waterland pkgrmremote++; 235*5c51f124SMoriah Waterland break; 236*5c51f124SMoriah Waterland 237*5c51f124SMoriah Waterland /* 238*5c51f124SMoriah Waterland * Same as pkgrm: Use the installation 239*5c51f124SMoriah Waterland * administration file, admin, in place of the 240*5c51f124SMoriah Waterland * default admin file. pkgrm first looks in the 241*5c51f124SMoriah Waterland * current working directory for the administration 242*5c51f124SMoriah Waterland * file. If the specified administration file is not 243*5c51f124SMoriah Waterland * in the current working directory, pkgrm looks in 244*5c51f124SMoriah Waterland * the /var/sadm/install/admin directory for the 245*5c51f124SMoriah Waterland * administration file. 246*5c51f124SMoriah Waterland */ 247*5c51f124SMoriah Waterland case 'a': 248*5c51f124SMoriah Waterland admnfile = flex_device(optarg, 0); 249*5c51f124SMoriah Waterland break; 250*5c51f124SMoriah Waterland 251*5c51f124SMoriah Waterland /* 252*5c51f124SMoriah Waterland * Same as pkgrm: location where package executables 253*5c51f124SMoriah Waterland * can be found - default is /usr/sadm/install/bin. 254*5c51f124SMoriah Waterland */ 255*5c51f124SMoriah Waterland case 'b': 256*5c51f124SMoriah Waterland if (!path_valid(optarg)) { 257*5c51f124SMoriah Waterland progerr(ERR_PATH, optarg); 258*5c51f124SMoriah Waterland exit(1); 259*5c51f124SMoriah Waterland } 260*5c51f124SMoriah Waterland if (isdir(optarg) != 0) { 261*5c51f124SMoriah Waterland char *p = strerror(errno); 262*5c51f124SMoriah Waterland progerr(ERR_CANNOT_USE_DIR, optarg, p); 263*5c51f124SMoriah Waterland exit(1); 264*5c51f124SMoriah Waterland } 265*5c51f124SMoriah Waterland (void) strlcpy(cmdbin, optarg, sizeof (cmdbin)); 266*5c51f124SMoriah Waterland break; 267*5c51f124SMoriah Waterland 268*5c51f124SMoriah Waterland /* 269*5c51f124SMoriah Waterland * Same as pkgrm: suppresses the removal of any 270*5c51f124SMoriah Waterland * files and any class action scripts, and suppresses 271*5c51f124SMoriah Waterland * the running of any class action scripts. The 272*5c51f124SMoriah Waterland * package files remain but the package looks like it 273*5c51f124SMoriah Waterland * is not installed. This is mainly for use by the 274*5c51f124SMoriah Waterland * upgrade process. 275*5c51f124SMoriah Waterland */ 276*5c51f124SMoriah Waterland case 'F': 277*5c51f124SMoriah Waterland nodelete++; 278*5c51f124SMoriah Waterland break; 279*5c51f124SMoriah Waterland 280*5c51f124SMoriah Waterland /* 281*5c51f124SMoriah Waterland * Same as pkgrm: Instruct pkgrm not to use the 282*5c51f124SMoriah Waterland * $root_path/etc/vfstab file for determining the 283*5c51f124SMoriah Waterland * client's mount points. This option assumes the 284*5c51f124SMoriah Waterland * mount points are correct on the server and it 285*5c51f124SMoriah Waterland * behaves consistently with Solaris 2.5 and earlier 286*5c51f124SMoriah Waterland * releases. 287*5c51f124SMoriah Waterland */ 288*5c51f124SMoriah Waterland case 'M': 289*5c51f124SMoriah Waterland map_client = 0; 290*5c51f124SMoriah Waterland break; 291*5c51f124SMoriah Waterland 292*5c51f124SMoriah Waterland /* 293*5c51f124SMoriah Waterland * Different from pkgrm: specify program name to use 294*5c51f124SMoriah Waterland * for messages. 295*5c51f124SMoriah Waterland */ 296*5c51f124SMoriah Waterland case 'N': 297*5c51f124SMoriah Waterland (void) set_prog_name(optarg); 298*5c51f124SMoriah Waterland break; 299*5c51f124SMoriah Waterland 300*5c51f124SMoriah Waterland /* 301*5c51f124SMoriah Waterland * Same as pkgrm: package removal occurs in 302*5c51f124SMoriah Waterland * non-interactive mode. Suppress output of the list of 303*5c51f124SMoriah Waterland * removed files. The default mode is interactive. 304*5c51f124SMoriah Waterland */ 305*5c51f124SMoriah Waterland case 'n': 306*5c51f124SMoriah Waterland nointeract++; 307*5c51f124SMoriah Waterland (void) echoSetFlag(B_FALSE); 308*5c51f124SMoriah Waterland break; 309*5c51f124SMoriah Waterland 310*5c51f124SMoriah Waterland /* 311*5c51f124SMoriah Waterland * Almost same as pkgrm: the -O option allows the behavior 312*5c51f124SMoriah Waterland * of the package tools to be modified. Recognized options: 313*5c51f124SMoriah Waterland * -> debug 314*5c51f124SMoriah Waterland * ---> enable debugging output 315*5c51f124SMoriah Waterland * -> preremovecheck 316*5c51f124SMoriah Waterland * ---> perform a "pre removal" check of the specified 317*5c51f124SMoriah Waterland * ---> package - suppress all regular output and cause a 318*5c51f124SMoriah Waterland * ---> series of one or more "name=value" pair format lines 319*5c51f124SMoriah Waterland * ---> to be output that describes the "removability" of 320*5c51f124SMoriah Waterland * ---> the specified package 321*5c51f124SMoriah Waterland * -> enable-hollow-package-support 322*5c51f124SMoriah Waterland * --> Enable hollow package support. When specified, for any 323*5c51f124SMoriah Waterland * --> package that has SUNW_PKG_HOLLOW=true: 324*5c51f124SMoriah Waterland * --> Do not calculate and verify package size against target 325*5c51f124SMoriah Waterland * --> Do not run any package procedure or class action scripts 326*5c51f124SMoriah Waterland * --> Do not create or remove any target directories 327*5c51f124SMoriah Waterland * --> Do not perform any script locking 328*5c51f124SMoriah Waterland * --> Do not install or uninstall any components of any package 329*5c51f124SMoriah Waterland * --> Do not output any status or database update messages 330*5c51f124SMoriah Waterland */ 331*5c51f124SMoriah Waterland case 'O': 332*5c51f124SMoriah Waterland for (p = strtok(optarg, ","); p != (char *)NULL; 333*5c51f124SMoriah Waterland p = strtok(NULL, ",")) { 334*5c51f124SMoriah Waterland 335*5c51f124SMoriah Waterland /* process debug option */ 336*5c51f124SMoriah Waterland 337*5c51f124SMoriah Waterland if (strcmp(p, "debug") == 0) { 338*5c51f124SMoriah Waterland /* set debug flag/enable debug output */ 339*5c51f124SMoriah Waterland debugFlag = B_TRUE; 340*5c51f124SMoriah Waterland (void) echoDebugSetFlag(debugFlag); 341*5c51f124SMoriah Waterland 342*5c51f124SMoriah Waterland /* debug info on arguments to pkgadd */ 343*5c51f124SMoriah Waterland for (n = 0; n < argc && argv[n]; n++) { 344*5c51f124SMoriah Waterland echoDebug(DBG_ARG, n, argv[n]); 345*5c51f124SMoriah Waterland } 346*5c51f124SMoriah Waterland 347*5c51f124SMoriah Waterland continue; 348*5c51f124SMoriah Waterland } 349*5c51f124SMoriah Waterland 350*5c51f124SMoriah Waterland /* process enable-hollow-package-support opt */ 351*5c51f124SMoriah Waterland 352*5c51f124SMoriah Waterland if (strcmp(p, 353*5c51f124SMoriah Waterland "enable-hollow-package-support") == 0) { 354*5c51f124SMoriah Waterland set_depend_pkginfo_DB(B_TRUE); 355*5c51f124SMoriah Waterland continue; 356*5c51f124SMoriah Waterland } 357*5c51f124SMoriah Waterland 358*5c51f124SMoriah Waterland /* process inherited-filesystem= option */ 359*5c51f124SMoriah Waterland 360*5c51f124SMoriah Waterland if (strncmp(p, INHERITFS, INHERITFS_LEN) == 0) { 361*5c51f124SMoriah Waterland if (z_add_inherited_file_system( 362*5c51f124SMoriah Waterland p+INHERITFS_LEN) == B_FALSE) { 363*5c51f124SMoriah Waterland progerr(ERR_NOSUCH_INHERITED, 364*5c51f124SMoriah Waterland p+INHERITFS_LEN); 365*5c51f124SMoriah Waterland quit(1); 366*5c51f124SMoriah Waterland /* NOTREACHED */ 367*5c51f124SMoriah Waterland } 368*5c51f124SMoriah Waterland continue; 369*5c51f124SMoriah Waterland } 370*5c51f124SMoriah Waterland 371*5c51f124SMoriah Waterland /* process preremovecheck option */ 372*5c51f124SMoriah Waterland 373*5c51f124SMoriah Waterland if (strcmp(p, "preremovecheck") == 0) { 374*5c51f124SMoriah Waterland preremoveCheck = B_TRUE; 375*5c51f124SMoriah Waterland nointeract++; /* -n */ 376*5c51f124SMoriah Waterland nodelete++; /* -F */ 377*5c51f124SMoriah Waterland quitSetSilentExit(B_TRUE); 378*5c51f124SMoriah Waterland continue; 379*5c51f124SMoriah Waterland } 380*5c51f124SMoriah Waterland 381*5c51f124SMoriah Waterland /* process addzonename option */ 382*5c51f124SMoriah Waterland 383*5c51f124SMoriah Waterland if (strcmp(p, "addzonename") == 0) { 384*5c51f124SMoriah Waterland zoneName = z_get_zonename(); 385*5c51f124SMoriah Waterland quitSetZoneName(zoneName); 386*5c51f124SMoriah Waterland continue; 387*5c51f124SMoriah Waterland } 388*5c51f124SMoriah Waterland 389*5c51f124SMoriah Waterland /* process parent-zone-name option */ 390*5c51f124SMoriah Waterland 391*5c51f124SMoriah Waterland if (strncmp(p, PARENTZONENAME, 392*5c51f124SMoriah Waterland PARENTZONENAME_LEN) == 0) { 393*5c51f124SMoriah Waterland parentZoneName = p+PARENTZONENAME_LEN; 394*5c51f124SMoriah Waterland continue; 395*5c51f124SMoriah Waterland } 396*5c51f124SMoriah Waterland 397*5c51f124SMoriah Waterland /* process parent-zone-type option */ 398*5c51f124SMoriah Waterland 399*5c51f124SMoriah Waterland if (strncmp(p, PARENTZONETYPE, 400*5c51f124SMoriah Waterland PARENTZONETYPE_LEN) == 0) { 401*5c51f124SMoriah Waterland parentZoneType = p+PARENTZONETYPE_LEN; 402*5c51f124SMoriah Waterland continue; 403*5c51f124SMoriah Waterland } 404*5c51f124SMoriah Waterland 405*5c51f124SMoriah Waterland /* option not recognized - issue warning */ 406*5c51f124SMoriah Waterland 407*5c51f124SMoriah Waterland progerr(ERR_INVALID_O_OPTION, p); 408*5c51f124SMoriah Waterland continue; 409*5c51f124SMoriah Waterland } 410*5c51f124SMoriah Waterland break; 411*5c51f124SMoriah Waterland 412*5c51f124SMoriah Waterland /* 413*5c51f124SMoriah Waterland * Different from pkgrm: This is an old non-ABI package 414*5c51f124SMoriah Waterland */ 415*5c51f124SMoriah Waterland 416*5c51f124SMoriah Waterland case 'o': 417*5c51f124SMoriah Waterland script_in = PROC_XSTDIN; 418*5c51f124SMoriah Waterland break; 419*5c51f124SMoriah Waterland 420*5c51f124SMoriah Waterland /* 421*5c51f124SMoriah Waterland * Same as pkgrm: defines the full path name of a 422*5c51f124SMoriah Waterland * directory to use as the root_path. All files, 423*5c51f124SMoriah Waterland * including package system information files, are 424*5c51f124SMoriah Waterland * relocated to a directory tree starting in the 425*5c51f124SMoriah Waterland * specified root_path. 426*5c51f124SMoriah Waterland */ 427*5c51f124SMoriah Waterland case 'R': 428*5c51f124SMoriah Waterland if (!set_inst_root(optarg)) { 429*5c51f124SMoriah Waterland progerr(ERR_ROOT_CMD); 430*5c51f124SMoriah Waterland exit(1); 431*5c51f124SMoriah Waterland } 432*5c51f124SMoriah Waterland break; 433*5c51f124SMoriah Waterland 434*5c51f124SMoriah Waterland /* 435*5c51f124SMoriah Waterland * Same as pkgrm: allow admin to establish the client 436*5c51f124SMoriah Waterland * filesystem using a vfstab-like file of stable format. 437*5c51f124SMoriah Waterland */ 438*5c51f124SMoriah Waterland case 'V': 439*5c51f124SMoriah Waterland vfstab_file = flex_device(optarg, 2); 440*5c51f124SMoriah Waterland map_client = 1; 441*5c51f124SMoriah Waterland break; 442*5c51f124SMoriah Waterland 443*5c51f124SMoriah Waterland /* 444*5c51f124SMoriah Waterland * Same as pkgrm: trace all of the scripts that 445*5c51f124SMoriah Waterland * get executed by pkgrm, located in the 446*5c51f124SMoriah Waterland * pkginst/install directory. This option is used for 447*5c51f124SMoriah Waterland * debugging the procedural and non-procedural 448*5c51f124SMoriah Waterland * scripts. 449*5c51f124SMoriah Waterland */ 450*5c51f124SMoriah Waterland case 'v': 451*5c51f124SMoriah Waterland pkgverbose++; 452*5c51f124SMoriah Waterland break; 453*5c51f124SMoriah Waterland 454*5c51f124SMoriah Waterland /* 455*5c51f124SMoriah Waterland * Different from pkgrm: process this package using 456*5c51f124SMoriah Waterland * old non-ABI symlinks 457*5c51f124SMoriah Waterland */ 458*5c51f124SMoriah Waterland case 'y': 459*5c51f124SMoriah Waterland set_nonABI_symlinks(); 460*5c51f124SMoriah Waterland break; 461*5c51f124SMoriah Waterland 462*5c51f124SMoriah Waterland default: 463*5c51f124SMoriah Waterland usage(); 464*5c51f124SMoriah Waterland /*NOTREACHED*/ 465*5c51f124SMoriah Waterland /* 466*5c51f124SMoriah Waterland * Although usage() calls a noreturn function, 467*5c51f124SMoriah Waterland * needed to add return (1); so that main() would 468*5c51f124SMoriah Waterland * pass compilation checks. The statement below 469*5c51f124SMoriah Waterland * should never be executed. 470*5c51f124SMoriah Waterland */ 471*5c51f124SMoriah Waterland return (1); 472*5c51f124SMoriah Waterland } 473*5c51f124SMoriah Waterland } 474*5c51f124SMoriah Waterland 475*5c51f124SMoriah Waterland /* 476*5c51f124SMoriah Waterland * ******************************************************************** 477*5c51f124SMoriah Waterland * validate command line options 478*5c51f124SMoriah Waterland * ******************************************************************** 479*5c51f124SMoriah Waterland */ 480*5c51f124SMoriah Waterland 481*5c51f124SMoriah Waterland (void) echoDebugSetFlag(debugFlag); 482*5c51f124SMoriah Waterland (void) log_set_verbose(debugFlag); 483*5c51f124SMoriah Waterland 484*5c51f124SMoriah Waterland if (z_running_in_global_zone()) { 485*5c51f124SMoriah Waterland echoDebug(DBG_ENTRY_IN_GZ, prog_full_name); 486*5c51f124SMoriah Waterland } else { 487*5c51f124SMoriah Waterland echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(), 488*5c51f124SMoriah Waterland z_get_zonename()); 489*5c51f124SMoriah Waterland } 490*5c51f124SMoriah Waterland 491*5c51f124SMoriah Waterland /* establish cmdbin path */ 492*5c51f124SMoriah Waterland 493*5c51f124SMoriah Waterland if (cmdbin[0] == '\0') { 494*5c51f124SMoriah Waterland (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin)); 495*5c51f124SMoriah Waterland } 496*5c51f124SMoriah Waterland 497*5c51f124SMoriah Waterland /* Read the mount table */ 498*5c51f124SMoriah Waterland 499*5c51f124SMoriah Waterland if (get_mntinfo(map_client, vfstab_file)) { 500*5c51f124SMoriah Waterland quit(99); 501*5c51f124SMoriah Waterland } 502*5c51f124SMoriah Waterland 503*5c51f124SMoriah Waterland /* 504*5c51f124SMoriah Waterland * This function defines the standard /var/... directories used later 505*5c51f124SMoriah Waterland * to construct the paths to the various databases. 506*5c51f124SMoriah Waterland */ 507*5c51f124SMoriah Waterland 508*5c51f124SMoriah Waterland set_PKGpaths(get_inst_root()); 509*5c51f124SMoriah Waterland 510*5c51f124SMoriah Waterland /* 511*5c51f124SMoriah Waterland * If this is being removed from a client whose /var filesystem is 512*5c51f124SMoriah Waterland * mounted in some odd way, remap the administrative paths to the 513*5c51f124SMoriah Waterland * real filesystem. This could be avoided by simply mounting up the 514*5c51f124SMoriah Waterland * client now; but we aren't yet to the point in the process where 515*5c51f124SMoriah Waterland * modification of the filesystem is permitted. 516*5c51f124SMoriah Waterland */ 517*5c51f124SMoriah Waterland if (is_an_inst_root()) { 518*5c51f124SMoriah Waterland int fsys_value; 519*5c51f124SMoriah Waterland 520*5c51f124SMoriah Waterland fsys_value = fsys(get_PKGLOC()); 521*5c51f124SMoriah Waterland if (use_srvr_map_n(fsys_value)) 522*5c51f124SMoriah Waterland set_PKGLOC(server_map(get_PKGLOC(), fsys_value)); 523*5c51f124SMoriah Waterland 524*5c51f124SMoriah Waterland fsys_value = fsys(get_PKGADM()); 525*5c51f124SMoriah Waterland if (use_srvr_map_n(fsys_value)) 526*5c51f124SMoriah Waterland set_PKGADM(server_map(get_PKGADM(), fsys_value)); 527*5c51f124SMoriah Waterland } else { 528*5c51f124SMoriah Waterland pkgrmremote = 0; /* Makes no sense on local host. */ 529*5c51f124SMoriah Waterland } 530*5c51f124SMoriah Waterland 531*5c51f124SMoriah Waterland /* 532*5c51f124SMoriah Waterland * hook SIGINT and SIGHUP interrupts into quit.c's trap handler 533*5c51f124SMoriah Waterland */ 534*5c51f124SMoriah Waterland 535*5c51f124SMoriah Waterland /* hold SIGINT/SIGHUP interrupts */ 536*5c51f124SMoriah Waterland 537*5c51f124SMoriah Waterland (void) sighold(SIGHUP); 538*5c51f124SMoriah Waterland (void) sighold(SIGINT); 539*5c51f124SMoriah Waterland 540*5c51f124SMoriah Waterland /* connect quit.c:trap() to SIGINT */ 541*5c51f124SMoriah Waterland 542*5c51f124SMoriah Waterland nact.sa_handler = quitGetTrapHandler(); 543*5c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 544*5c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 545*5c51f124SMoriah Waterland 546*5c51f124SMoriah Waterland (void) sigaction(SIGINT, &nact, &oact); 547*5c51f124SMoriah Waterland 548*5c51f124SMoriah Waterland /* connect quit.c:trap() to SIGHUP */ 549*5c51f124SMoriah Waterland 550*5c51f124SMoriah Waterland nact.sa_handler = quitGetTrapHandler(); 551*5c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 552*5c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 553*5c51f124SMoriah Waterland 554*5c51f124SMoriah Waterland (void) sigaction(SIGHUP, &nact, &oact); 555*5c51f124SMoriah Waterland 556*5c51f124SMoriah Waterland /* release hold on signals */ 557*5c51f124SMoriah Waterland 558*5c51f124SMoriah Waterland (void) sigrelse(SIGHUP); 559*5c51f124SMoriah Waterland (void) sigrelse(SIGINT); 560*5c51f124SMoriah Waterland 561*5c51f124SMoriah Waterland pkginst = argv[optind++]; 562*5c51f124SMoriah Waterland if (optind != argc) { 563*5c51f124SMoriah Waterland usage(); 564*5c51f124SMoriah Waterland } 565*5c51f124SMoriah Waterland 566*5c51f124SMoriah Waterland /* validate package software database (contents) file */ 567*5c51f124SMoriah Waterland 568*5c51f124SMoriah Waterland if (vcfile() == 0) { 569*5c51f124SMoriah Waterland quit(99); 570*5c51f124SMoriah Waterland } 571*5c51f124SMoriah Waterland 572*5c51f124SMoriah Waterland /* 573*5c51f124SMoriah Waterland * Acquire the package lock - currently at "remove initialization" 574*5c51f124SMoriah Waterland */ 575*5c51f124SMoriah Waterland 576*5c51f124SMoriah Waterland if (!lockinst(get_prog_name(), pkginst, "remove-initial")) { 577*5c51f124SMoriah Waterland quit(99); 578*5c51f124SMoriah Waterland } 579*5c51f124SMoriah Waterland 580*5c51f124SMoriah Waterland /* establish temporary directory to use */ 581*5c51f124SMoriah Waterland 582*5c51f124SMoriah Waterland tmpdir = getenv("TMPDIR"); 583*5c51f124SMoriah Waterland if (tmpdir == NULL) { 584*5c51f124SMoriah Waterland tmpdir = P_tmpdir; 585*5c51f124SMoriah Waterland } 586*5c51f124SMoriah Waterland 587*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_TMPDIR, tmpdir); 588*5c51f124SMoriah Waterland 589*5c51f124SMoriah Waterland /* 590*5c51f124SMoriah Waterland * Initialize installation admin parameters by reading 591*5c51f124SMoriah Waterland * the adminfile. 592*5c51f124SMoriah Waterland */ 593*5c51f124SMoriah Waterland 594*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_ADMINFILE, admnfile ? admnfile : ""); 595*5c51f124SMoriah Waterland setadminFile(admnfile); 596*5c51f124SMoriah Waterland 597*5c51f124SMoriah Waterland /* 598*5c51f124SMoriah Waterland * about to perform first operation that could be modified by the 599*5c51f124SMoriah Waterland * preremove check option - if preremove check is selected (that is, 600*5c51f124SMoriah Waterland * only gathering dependencies), then output a debug message to 601*5c51f124SMoriah Waterland * indicate that the check is beginning. Also turn echo() output 602*5c51f124SMoriah Waterland * off and set various other flags. 603*5c51f124SMoriah Waterland */ 604*5c51f124SMoriah Waterland 605*5c51f124SMoriah Waterland if (preremoveCheck == B_TRUE) { 606*5c51f124SMoriah Waterland (void) echoSetFlag(B_FALSE); 607*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PRERMCHK, pkginst ? pkginst : "", 608*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 609*5c51f124SMoriah Waterland rcksetPreremoveCheck(B_TRUE); 610*5c51f124SMoriah Waterland rcksetZoneName(zoneName); 611*5c51f124SMoriah Waterland } 612*5c51f124SMoriah Waterland 613*5c51f124SMoriah Waterland (void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s", get_PKGLOC(), 614*5c51f124SMoriah Waterland pkginst); 615*5c51f124SMoriah Waterland (void) snprintf(pkgbin, sizeof (pkgbin), "%s/install", pkgloc); 616*5c51f124SMoriah Waterland (void) snprintf(rlockfile, sizeof (rlockfile), "%s/!R-Lock!", pkgloc); 617*5c51f124SMoriah Waterland 618*5c51f124SMoriah Waterland if (chdir(pkgbin)) { 619*5c51f124SMoriah Waterland progerr(ERR_CHDIR, pkgbin); 620*5c51f124SMoriah Waterland quit(99); 621*5c51f124SMoriah Waterland } 622*5c51f124SMoriah Waterland 623*5c51f124SMoriah Waterland echo(MSG_PREREMOVE_REMINST, pkginst); 624*5c51f124SMoriah Waterland 625*5c51f124SMoriah Waterland /* 626*5c51f124SMoriah Waterland * if a lock file is present, then a previous attempt to remove this 627*5c51f124SMoriah Waterland * package may have been unsuccessful. 628*5c51f124SMoriah Waterland */ 629*5c51f124SMoriah Waterland 630*5c51f124SMoriah Waterland if (access(rlockfile, F_OK) == 0) { 631*5c51f124SMoriah Waterland echo(ERR_UNSUCC); 632*5c51f124SMoriah Waterland echoDebug(DBG_PKGINSTALL_HAS_LOCKFILE, pkginst, rlockfile, 633*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 634*5c51f124SMoriah Waterland } 635*5c51f124SMoriah Waterland 636*5c51f124SMoriah Waterland /* 637*5c51f124SMoriah Waterland * Process all parameters from the pkginfo file 638*5c51f124SMoriah Waterland * and place them in the execution environment 639*5c51f124SMoriah Waterland */ 640*5c51f124SMoriah Waterland 641*5c51f124SMoriah Waterland /* Add DB retreival of the pkginfo parameters here */ 642*5c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), "%s/pkginfo", pkgloc); 643*5c51f124SMoriah Waterland if ((fp = fopen(path, "r")) == NULL) { 644*5c51f124SMoriah Waterland progerr(ERR_PKGINFO, path); 645*5c51f124SMoriah Waterland quit(99); 646*5c51f124SMoriah Waterland } 647*5c51f124SMoriah Waterland 648*5c51f124SMoriah Waterland /* Mount up the client if necessary. */ 649*5c51f124SMoriah Waterland if (map_client && !mount_client()) { 650*5c51f124SMoriah Waterland logerr(MSG_MANMOUNT); 651*5c51f124SMoriah Waterland } 652*5c51f124SMoriah Waterland 653*5c51f124SMoriah Waterland /* Get mount point of client */ 654*5c51f124SMoriah Waterland client_mntdir = getenv("CLIENT_MNTDIR"); 655*5c51f124SMoriah Waterland 656*5c51f124SMoriah Waterland getuserlocale(); 657*5c51f124SMoriah Waterland 658*5c51f124SMoriah Waterland /* 659*5c51f124SMoriah Waterland * current environment has been read; clear environment out 660*5c51f124SMoriah Waterland * so putparam() can be used to populate the new environment 661*5c51f124SMoriah Waterland * to be passed to any executables/scripts. 662*5c51f124SMoriah Waterland */ 663*5c51f124SMoriah Waterland 664*5c51f124SMoriah Waterland environ = NULL; 665*5c51f124SMoriah Waterland 666*5c51f124SMoriah Waterland if (nonABI_symlinks()) { 667*5c51f124SMoriah Waterland putparam("PKG_NONABI_SYMLINKS", "TRUE"); 668*5c51f124SMoriah Waterland } 669*5c51f124SMoriah Waterland 670*5c51f124SMoriah Waterland /* 671*5c51f124SMoriah Waterland * read the pkginfo file and fix any PKGSAV path - the correct 672*5c51f124SMoriah Waterland * install_root will be prepended to the existing path. 673*5c51f124SMoriah Waterland */ 674*5c51f124SMoriah Waterland 675*5c51f124SMoriah Waterland param[0] = '\0'; 676*5c51f124SMoriah Waterland while (value = fpkgparam(fp, param)) { 677*5c51f124SMoriah Waterland int validx = 0; 678*5c51f124SMoriah Waterland char *newvalue; 679*5c51f124SMoriah Waterland 680*5c51f124SMoriah Waterland /* strip out any setting of PATH */ 681*5c51f124SMoriah Waterland 682*5c51f124SMoriah Waterland if (strcmp(param, "PATH") == 0) { 683*5c51f124SMoriah Waterland free(value); 684*5c51f124SMoriah Waterland param[0] = '\0'; 685*5c51f124SMoriah Waterland continue; 686*5c51f124SMoriah Waterland } 687*5c51f124SMoriah Waterland 688*5c51f124SMoriah Waterland /* if not PKGSAV then write out unchanged */ 689*5c51f124SMoriah Waterland 690*5c51f124SMoriah Waterland if (strcmp(param, "PKGSAV") != 0) { 691*5c51f124SMoriah Waterland putparam(param, value); 692*5c51f124SMoriah Waterland free(value); 693*5c51f124SMoriah Waterland param[0] = '\0'; 694*5c51f124SMoriah Waterland continue; 695*5c51f124SMoriah Waterland } 696*5c51f124SMoriah Waterland 697*5c51f124SMoriah Waterland /* 698*5c51f124SMoriah Waterland * PKGSAV parameter found - interpret the directory: 699*5c51f124SMoriah Waterland * If in host:path format or marked with the leading "//", 700*5c51f124SMoriah Waterland * then there is no client-relative translation - take it 701*5c51f124SMoriah Waterland * literally later rather than use fixpath(). 702*5c51f124SMoriah Waterland */ 703*5c51f124SMoriah Waterland 704*5c51f124SMoriah Waterland if (strstr(value, ":/")) { 705*5c51f124SMoriah Waterland /* no modification needed */ 706*5c51f124SMoriah Waterland validx = 0; 707*5c51f124SMoriah Waterland } else if (strstr(value, "//") == value) { 708*5c51f124SMoriah Waterland validx = 1; 709*5c51f124SMoriah Waterland } else if (is_an_inst_root()) { 710*5c51f124SMoriah Waterland /* This PKGSAV needs to be made client-relative. */ 711*5c51f124SMoriah Waterland newvalue = fixpath(value); 712*5c51f124SMoriah Waterland free(value); 713*5c51f124SMoriah Waterland value = newvalue; 714*5c51f124SMoriah Waterland } 715*5c51f124SMoriah Waterland putparam(param, value+validx); 716*5c51f124SMoriah Waterland free(value); 717*5c51f124SMoriah Waterland param[0] = '\0'; 718*5c51f124SMoriah Waterland } 719*5c51f124SMoriah Waterland 720*5c51f124SMoriah Waterland (void) fclose(fp); 721*5c51f124SMoriah Waterland 722*5c51f124SMoriah Waterland /* write parent condition information to environment */ 723*5c51f124SMoriah Waterland 724*5c51f124SMoriah Waterland putConditionInfo(parentZoneName, parentZoneType); 725*5c51f124SMoriah Waterland 726*5c51f124SMoriah Waterland putuserlocale(); 727*5c51f124SMoriah Waterland 728*5c51f124SMoriah Waterland /* 729*5c51f124SMoriah Waterland * Now do all the various setups based on ABI compliance 730*5c51f124SMoriah Waterland */ 731*5c51f124SMoriah Waterland 732*5c51f124SMoriah Waterland /* Read the environment provided by the pkginfo file */ 733*5c51f124SMoriah Waterland abi_comp_ptr = getenv("NONABI_SCRIPTS"); 734*5c51f124SMoriah Waterland 735*5c51f124SMoriah Waterland /* if not ABI compliant set global flag */ 736*5c51f124SMoriah Waterland abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS"); 737*5c51f124SMoriah Waterland if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) { 738*5c51f124SMoriah Waterland set_nonABI_symlinks(); 739*5c51f124SMoriah Waterland } 740*5c51f124SMoriah Waterland 741*5c51f124SMoriah Waterland /* 742*5c51f124SMoriah Waterland * If pkginfo says it's not compliant then set non_abi_scripts. 743*5c51f124SMoriah Waterland * Oh, for two releases, set it from exception package names as 744*5c51f124SMoriah Waterland * well. 745*5c51f124SMoriah Waterland */ 746*5c51f124SMoriah Waterland /* 747*5c51f124SMoriah Waterland * ********************************************************************* 748*5c51f124SMoriah Waterland * this feature is removed starting with Solaris 10 - there is no built 749*5c51f124SMoriah Waterland * in list of packages that should be run "the old way" 750*5c51f124SMoriah Waterland * ********************************************************************* 751*5c51f124SMoriah Waterland */ 752*5c51f124SMoriah Waterland 753*5c51f124SMoriah Waterland #ifdef ALLOW_EXCEPTION_PKG_LIST 754*5c51f124SMoriah Waterland if (exception_pkg(pkginst, SCRIPT) || 755*5c51f124SMoriah Waterland (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0)) 756*5c51f124SMoriah Waterland script_in = PROC_XSTDIN; 757*5c51f124SMoriah Waterland #else 758*5c51f124SMoriah Waterland if (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0) { 759*5c51f124SMoriah Waterland script_in = PROC_XSTDIN; 760*5c51f124SMoriah Waterland } 761*5c51f124SMoriah Waterland #endif 762*5c51f124SMoriah Waterland /* 763*5c51f124SMoriah Waterland * ********************************************************************* 764*5c51f124SMoriah Waterland * this feature is removed starting with Solaris 10 - there is no built 765*5c51f124SMoriah Waterland * in list of packages that should be run "the old way" 766*5c51f124SMoriah Waterland * ********************************************************************* 767*5c51f124SMoriah Waterland */ 768*5c51f124SMoriah Waterland 769*5c51f124SMoriah Waterland #ifdef ALLOW_EXCEPTION_PKG_LIST 770*5c51f124SMoriah Waterland /* Until 2.9, set it from the execption list */ 771*5c51f124SMoriah Waterland if (exception_pkg(pkginst, LINK)) { 772*5c51f124SMoriah Waterland set_nonABI_symlinks(); 773*5c51f124SMoriah Waterland } 774*5c51f124SMoriah Waterland #endif 775*5c51f124SMoriah Waterland 776*5c51f124SMoriah Waterland /* 777*5c51f124SMoriah Waterland * Since this is a removal, we can tell whether it's absolute or 778*5c51f124SMoriah Waterland * not from the resident pkginfo file read above. 779*5c51f124SMoriah Waterland */ 780*5c51f124SMoriah Waterland if ((err = set_basedirs((getenv("BASEDIR") != NULL), adm.basedir, 781*5c51f124SMoriah Waterland pkginst, nointeract)) != 0) { 782*5c51f124SMoriah Waterland quit(err); 783*5c51f124SMoriah Waterland } 784*5c51f124SMoriah Waterland 785*5c51f124SMoriah Waterland /* 786*5c51f124SMoriah Waterland * See if were are removing a package that only wants to update 787*5c51f124SMoriah Waterland * the database or only remove files associated with CAS's. We 788*5c51f124SMoriah Waterland * only check the PKG_HOLLOW_VARIABLE variable if told to do so by 789*5c51f124SMoriah Waterland * the caller. 790*5c51f124SMoriah Waterland */ 791*5c51f124SMoriah Waterland 792*5c51f124SMoriah Waterland if (is_depend_pkginfo_DB()) { 793*5c51f124SMoriah Waterland pt = getenv(PKG_HOLLOW_VARIABLE); 794*5c51f124SMoriah Waterland 795*5c51f124SMoriah Waterland if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) { 796*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED); 797*5c51f124SMoriah Waterland 798*5c51f124SMoriah Waterland /* 799*5c51f124SMoriah Waterland * this is a hollow package and hollow package support 800*5c51f124SMoriah Waterland * is enabled -- override admin settings to suppress 801*5c51f124SMoriah Waterland * checks that do not make sense since no scripts will 802*5c51f124SMoriah Waterland * be executed and no files will be removed. 803*5c51f124SMoriah Waterland */ 804*5c51f124SMoriah Waterland 805*5c51f124SMoriah Waterland setadminSetting("conflict", "nocheck"); 806*5c51f124SMoriah Waterland setadminSetting("setuid", "nocheck"); 807*5c51f124SMoriah Waterland setadminSetting("action", "nocheck"); 808*5c51f124SMoriah Waterland setadminSetting("partial", "nocheck"); 809*5c51f124SMoriah Waterland setadminSetting("space", "nocheck"); 810*5c51f124SMoriah Waterland setadminSetting("authentication", "nocheck"); 811*5c51f124SMoriah Waterland } else { 812*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED); 813*5c51f124SMoriah Waterland set_depend_pkginfo_DB(B_FALSE); 814*5c51f124SMoriah Waterland } 815*5c51f124SMoriah Waterland } 816*5c51f124SMoriah Waterland 817*5c51f124SMoriah Waterland put_path_params(); 818*5c51f124SMoriah Waterland 819*5c51f124SMoriah Waterland /* If client mount point, add it to pkgremove environment */ 820*5c51f124SMoriah Waterland 821*5c51f124SMoriah Waterland if (client_mntdir != NULL) { 822*5c51f124SMoriah Waterland putparam("CLIENT_MNTDIR", client_mntdir); 823*5c51f124SMoriah Waterland } 824*5c51f124SMoriah Waterland 825*5c51f124SMoriah Waterland /* Establish the class list and the class attributes. */ 826*5c51f124SMoriah Waterland 827*5c51f124SMoriah Waterland if ((value = getenv("CLASSES")) != NULL) { 828*5c51f124SMoriah Waterland cl_sets(qstrdup(value)); 829*5c51f124SMoriah Waterland } else { 830*5c51f124SMoriah Waterland progerr(ERR_CLASSES, path); 831*5c51f124SMoriah Waterland quit(99); 832*5c51f124SMoriah Waterland } 833*5c51f124SMoriah Waterland 834*5c51f124SMoriah Waterland /* establish path and tmpdir */ 835*5c51f124SMoriah Waterland 836*5c51f124SMoriah Waterland if (cmdbin[0] == '\0') { 837*5c51f124SMoriah Waterland (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin)); 838*5c51f124SMoriah Waterland } 839*5c51f124SMoriah Waterland 840*5c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin); 841*5c51f124SMoriah Waterland putparam("PATH", path); 842*5c51f124SMoriah Waterland 843*5c51f124SMoriah Waterland putparam("TMPDIR", tmpdir); 844*5c51f124SMoriah Waterland 845*5c51f124SMoriah Waterland /* 846*5c51f124SMoriah Waterland * Check ulimit requirement (provided in pkginfo). The purpose of 847*5c51f124SMoriah Waterland * this limit is to terminate pathological file growth resulting from 848*5c51f124SMoriah Waterland * file edits in scripts. It does not apply to files in the pkgmap 849*5c51f124SMoriah Waterland * and it does not apply to any database files manipulated by the 850*5c51f124SMoriah Waterland * installation service. 851*5c51f124SMoriah Waterland */ 852*5c51f124SMoriah Waterland if (value = getenv("ULIMIT")) { 853*5c51f124SMoriah Waterland if (assign_ulimit(value) == -1) { 854*5c51f124SMoriah Waterland progerr(ERR_BADULIMIT, value); 855*5c51f124SMoriah Waterland warnflag++; 856*5c51f124SMoriah Waterland } 857*5c51f124SMoriah Waterland putparam("PKG_ULIMIT", "TRUE"); 858*5c51f124SMoriah Waterland } 859*5c51f124SMoriah Waterland 860*5c51f124SMoriah Waterland /* 861*5c51f124SMoriah Waterland * If only gathering dependencies, check and output status of all 862*5c51f124SMoriah Waterland * remaining dependencies and exit. 863*5c51f124SMoriah Waterland */ 864*5c51f124SMoriah Waterland 865*5c51f124SMoriah Waterland if (preremoveCheck == B_TRUE) { 866*5c51f124SMoriah Waterland /* 867*5c51f124SMoriah Waterland * make sure current runlevel is appropriate 868*5c51f124SMoriah Waterland */ 869*5c51f124SMoriah Waterland 870*5c51f124SMoriah Waterland (void) fprintf(stdout, "rckrunlevel=%d\n", rckrunlevel()); 871*5c51f124SMoriah Waterland 872*5c51f124SMoriah Waterland /* 873*5c51f124SMoriah Waterland * determine if any packaging scripts provided with 874*5c51f124SMoriah Waterland * this package will execute as a priviledged user 875*5c51f124SMoriah Waterland */ 876*5c51f124SMoriah Waterland 877*5c51f124SMoriah Waterland (void) fprintf(stdout, "rckpriv=%d\n", rckpriv()); 878*5c51f124SMoriah Waterland 879*5c51f124SMoriah Waterland /* 880*5c51f124SMoriah Waterland * verify package dependencies 881*5c51f124SMoriah Waterland */ 882*5c51f124SMoriah Waterland 883*5c51f124SMoriah Waterland (void) fprintf(stdout, "rckdepend=%d\n", rckdepend()); 884*5c51f124SMoriah Waterland 885*5c51f124SMoriah Waterland /* 886*5c51f124SMoriah Waterland * ****** preremove check done - exit ****** 887*5c51f124SMoriah Waterland */ 888*5c51f124SMoriah Waterland 889*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PRERMCHK_OK); 890*5c51f124SMoriah Waterland quit(0); 891*5c51f124SMoriah Waterland /*NOTREACHED*/ 892*5c51f124SMoriah Waterland } 893*5c51f124SMoriah Waterland 894*5c51f124SMoriah Waterland /* 895*5c51f124SMoriah Waterland * Not gathering dependencies only, proceed to check dependencies 896*5c51f124SMoriah Waterland * and continue with the package removal operation. 897*5c51f124SMoriah Waterland */ 898*5c51f124SMoriah Waterland 899*5c51f124SMoriah Waterland /* 900*5c51f124SMoriah Waterland * make sure current runlevel is appropriate 901*5c51f124SMoriah Waterland */ 902*5c51f124SMoriah Waterland 903*5c51f124SMoriah Waterland n = rckrunlevel(); 904*5c51f124SMoriah Waterland 905*5c51f124SMoriah Waterland if (n != 0) { 906*5c51f124SMoriah Waterland quit(n); 907*5c51f124SMoriah Waterland /* NOTREACHED */ 908*5c51f124SMoriah Waterland } 909*5c51f124SMoriah Waterland 910*5c51f124SMoriah Waterland /* 911*5c51f124SMoriah Waterland * determine if any packaging scripts provided with 912*5c51f124SMoriah Waterland * this package will execute as a priviledged user 913*5c51f124SMoriah Waterland */ 914*5c51f124SMoriah Waterland 915*5c51f124SMoriah Waterland n = rckpriv(); 916*5c51f124SMoriah Waterland 917*5c51f124SMoriah Waterland if (n != 0) { 918*5c51f124SMoriah Waterland quit(n); 919*5c51f124SMoriah Waterland /* NOTREACHED */ 920*5c51f124SMoriah Waterland } 921*5c51f124SMoriah Waterland 922*5c51f124SMoriah Waterland /* 923*5c51f124SMoriah Waterland * verify package dependencies 924*5c51f124SMoriah Waterland */ 925*5c51f124SMoriah Waterland n = rckdepend(); 926*5c51f124SMoriah Waterland 927*5c51f124SMoriah Waterland if (n != 0) { 928*5c51f124SMoriah Waterland quit(n); 929*5c51f124SMoriah Waterland /* NOTREACHED */ 930*5c51f124SMoriah Waterland } 931*5c51f124SMoriah Waterland 932*5c51f124SMoriah Waterland /* 933*5c51f124SMoriah Waterland * ********************************************************************* 934*5c51f124SMoriah Waterland * the actual removal of the package begins here 935*5c51f124SMoriah Waterland * ********************************************************************* 936*5c51f124SMoriah Waterland */ 937*5c51f124SMoriah Waterland 938*5c51f124SMoriah Waterland /* 939*5c51f124SMoriah Waterland * create lockfile to indicate start of removal 940*5c51f124SMoriah Waterland */ 941*5c51f124SMoriah Waterland started++; 942*5c51f124SMoriah Waterland if ((fd = open(rlockfile, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { 943*5c51f124SMoriah Waterland progerr(ERR_LOCKFILE, rlockfile); 944*5c51f124SMoriah Waterland quit(99); 945*5c51f124SMoriah Waterland } else { 946*5c51f124SMoriah Waterland (void) close(fd); 947*5c51f124SMoriah Waterland } 948*5c51f124SMoriah Waterland 949*5c51f124SMoriah Waterland if (zoneName == (char *)NULL) { 950*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_PROCPKG_GZ); 951*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PROCPKG_GZ, pkginst, rlockfile); 952*5c51f124SMoriah Waterland } else { 953*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_PROCPKG_LZ, zoneName); 954*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PROCPKG_LZ, pkginst, rlockfile, 955*5c51f124SMoriah Waterland zoneName); 956*5c51f124SMoriah Waterland } 957*5c51f124SMoriah Waterland if (delmap(0, pkginst) != 0) { 958*5c51f124SMoriah Waterland progerr(ERR_DB_QUERY, pkginst); 959*5c51f124SMoriah Waterland quit(99); 960*5c51f124SMoriah Waterland } 961*5c51f124SMoriah Waterland 962*5c51f124SMoriah Waterland /* 963*5c51f124SMoriah Waterland * Run a preremove script if one is provided by the package. 964*5c51f124SMoriah Waterland * Don't execute preremove script if only updating the DB. 965*5c51f124SMoriah Waterland * Don't execute preremove script if files are not being deleted. 966*5c51f124SMoriah Waterland * Don't execute preremove script if one or more files reside in 967*5c51f124SMoriah Waterland * an inherited FS. 968*5c51f124SMoriah Waterland */ 969*5c51f124SMoriah Waterland 970*5c51f124SMoriah Waterland /* update the lock - at the preremove script */ 971*5c51f124SMoriah Waterland lockupd("preremove"); 972*5c51f124SMoriah Waterland 973*5c51f124SMoriah Waterland /* execute preremove script if one is provided */ 974*5c51f124SMoriah Waterland (void) snprintf(script, sizeof (script), "%s/preremove", pkgbin); 975*5c51f124SMoriah Waterland if (access(script, F_OK) != 0) { 976*5c51f124SMoriah Waterland /* no script present */ 977*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_POC_NONE, pkginst, 978*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 979*5c51f124SMoriah Waterland } else if (nodelete) { 980*5c51f124SMoriah Waterland /* not deleting files: skip preremove script */ 981*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_POC_NODEL, pkginst, script, 982*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 983*5c51f124SMoriah Waterland } else if (is_depend_pkginfo_DB()) { 984*5c51f124SMoriah Waterland /* updating db only: skip preremove script */ 985*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_POC_DBUPD, pkginst, script, 986*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 987*5c51f124SMoriah Waterland } else { 988*5c51f124SMoriah Waterland /* script present and ok to run: run the script */ 989*5c51f124SMoriah Waterland set_ulimit("preremove", ERR_PREREMOVE); 990*5c51f124SMoriah Waterland if (zoneName == (char *)NULL) { 991*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_EXEPOC_GZ); 992*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_EXEPOC_GZ, pkginst, script); 993*5c51f124SMoriah Waterland } else { 994*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_EXEPOC_LZ, zoneName); 995*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_EXEPOC_LZ, pkginst, script, 996*5c51f124SMoriah Waterland zoneName); 997*5c51f124SMoriah Waterland } 998*5c51f124SMoriah Waterland putparam("PKG_PROC_SCRIPT", "preremove"); 999*5c51f124SMoriah Waterland if (pkgverbose) { 1000*5c51f124SMoriah Waterland ckreturn(pkgexecl(script_in, PROC_STDOUT, 1001*5c51f124SMoriah Waterland PROC_USER, PROC_GRP, SHELL, "-x", 1002*5c51f124SMoriah Waterland script, NULL), ERR_PREREMOVE); 1003*5c51f124SMoriah Waterland } else { 1004*5c51f124SMoriah Waterland ckreturn(pkgexecl(script_in, PROC_STDOUT, 1005*5c51f124SMoriah Waterland PROC_USER, PROC_GRP, SHELL, script, 1006*5c51f124SMoriah Waterland NULL), ERR_PREREMOVE); 1007*5c51f124SMoriah Waterland } 1008*5c51f124SMoriah Waterland clr_ulimit(); 1009*5c51f124SMoriah Waterland } 1010*5c51f124SMoriah Waterland 1011*5c51f124SMoriah Waterland /* update the lock - doing removal */ 1012*5c51f124SMoriah Waterland 1013*5c51f124SMoriah Waterland lockupd("remove"); 1014*5c51f124SMoriah Waterland 1015*5c51f124SMoriah Waterland /* 1016*5c51f124SMoriah Waterland * Ensure that the contents file is updated even if the db has 1017*5c51f124SMoriah Waterland * been upgraded, in the case that there are relevant entries 1018*5c51f124SMoriah Waterland * in a special_contents file. The return value is ignored 1019*5c51f124SMoriah Waterland * since we do not want special_contents operation to prevent 1020*5c51f124SMoriah Waterland * pkgremove from succeeding. We do report errors to stderr. 1021*5c51f124SMoriah Waterland */ 1022*5c51f124SMoriah Waterland 1023*5c51f124SMoriah Waterland /* 1024*5c51f124SMoriah Waterland * Remove all components belonging to this package. 1025*5c51f124SMoriah Waterland * Don't remove components if only updating the DB. 1026*5c51f124SMoriah Waterland * Don't remove components if files are not being deleted. 1027*5c51f124SMoriah Waterland */ 1028*5c51f124SMoriah Waterland 1029*5c51f124SMoriah Waterland if (nodelete) { 1030*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_REM_NODEL, pkginst, 1031*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 1032*5c51f124SMoriah Waterland } else if (is_depend_pkginfo_DB()) { 1033*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_REM_DBUPD, pkginst, 1034*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 1035*5c51f124SMoriah Waterland } else { 1036*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_REM, pkginst, 1037*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 1038*5c51f124SMoriah Waterland /* 1039*5c51f124SMoriah Waterland * remove package one class at a time 1040*5c51f124SMoriah Waterland */ 1041*5c51f124SMoriah Waterland 1042*5c51f124SMoriah Waterland /* reverse order of classes */ 1043*5c51f124SMoriah Waterland for (i = cl_getn() - 1; i >= 0; i--) { 1044*5c51f124SMoriah Waterland rmclass(cl_nam(i), pkgrmremote, zoneName); 1045*5c51f124SMoriah Waterland } 1046*5c51f124SMoriah Waterland 1047*5c51f124SMoriah Waterland rmclass(NULL, pkgrmremote, zoneName); 1048*5c51f124SMoriah Waterland } 1049*5c51f124SMoriah Waterland 1050*5c51f124SMoriah Waterland z_destroyMountTable(); 1051*5c51f124SMoriah Waterland 1052*5c51f124SMoriah Waterland /* 1053*5c51f124SMoriah Waterland * Execute postremove script, if any 1054*5c51f124SMoriah Waterland * Don't execute postremove script if only updating the DB. 1055*5c51f124SMoriah Waterland * Don't execute postremove script if files are not being deleted. 1056*5c51f124SMoriah Waterland */ 1057*5c51f124SMoriah Waterland 1058*5c51f124SMoriah Waterland /* update the lock - at the postremove script */ 1059*5c51f124SMoriah Waterland lockupd("postremove"); 1060*5c51f124SMoriah Waterland 1061*5c51f124SMoriah Waterland /* execute postremove script if one is provided */ 1062*5c51f124SMoriah Waterland (void) snprintf(script, sizeof (script), "%s/postremove", pkgbin); 1063*5c51f124SMoriah Waterland if (access(script, F_OK) != 0) { 1064*5c51f124SMoriah Waterland /* no script present */ 1065*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PIC_NONE, pkginst, 1066*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 1067*5c51f124SMoriah Waterland } else if (nodelete) { 1068*5c51f124SMoriah Waterland /* not deleting files: skip postremove script */ 1069*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PIC_NODEL, pkginst, script, 1070*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 1071*5c51f124SMoriah Waterland } else if (is_depend_pkginfo_DB()) { 1072*5c51f124SMoriah Waterland /* updating db only: skip postremove script */ 1073*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PIC_DBUPD, pkginst, script, 1074*5c51f124SMoriah Waterland zoneName ? zoneName : "global"); 1075*5c51f124SMoriah Waterland } else { 1076*5c51f124SMoriah Waterland /* script present and ok to run: run the script */ 1077*5c51f124SMoriah Waterland set_ulimit("postremove", ERR_POSTREMOVE); 1078*5c51f124SMoriah Waterland if (zoneName == (char *)NULL) { 1079*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_EXEPIC_GZ); 1080*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_EXEPIC_GZ, pkginst, script); 1081*5c51f124SMoriah Waterland } else { 1082*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_EXEPIC_LZ, zoneName); 1083*5c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_EXEPIC_LZ, pkginst, script, 1084*5c51f124SMoriah Waterland zoneName); 1085*5c51f124SMoriah Waterland } 1086*5c51f124SMoriah Waterland putparam("PKG_PROC_SCRIPT", "postremove"); 1087*5c51f124SMoriah Waterland putparam("TMPDIR", tmpdir); 1088*5c51f124SMoriah Waterland if (pkgverbose) { 1089*5c51f124SMoriah Waterland ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER, 1090*5c51f124SMoriah Waterland PROC_GRP, SHELL, "-x", script, NULL), 1091*5c51f124SMoriah Waterland ERR_POSTREMOVE); 1092*5c51f124SMoriah Waterland } else { 1093*5c51f124SMoriah Waterland ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER, 1094*5c51f124SMoriah Waterland PROC_GRP, SHELL, script, NULL), 1095*5c51f124SMoriah Waterland ERR_POSTREMOVE); 1096*5c51f124SMoriah Waterland } 1097*5c51f124SMoriah Waterland clr_ulimit(); 1098*5c51f124SMoriah Waterland } 1099*5c51f124SMoriah Waterland 1100*5c51f124SMoriah Waterland if (zoneName == (char *)NULL) { 1101*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_UPDINF_GZ); 1102*5c51f124SMoriah Waterland } else { 1103*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_UPDINF_LZ, zoneName); 1104*5c51f124SMoriah Waterland } 1105*5c51f124SMoriah Waterland 1106*5c51f124SMoriah Waterland if (delmap(1, pkginst) != 0) { 1107*5c51f124SMoriah Waterland progerr(ERR_DB_QUERY, pkginst); 1108*5c51f124SMoriah Waterland quit(99); 1109*5c51f124SMoriah Waterland } 1110*5c51f124SMoriah Waterland 1111*5c51f124SMoriah Waterland if (!warnflag && !failflag) { 1112*5c51f124SMoriah Waterland if (pt = getenv("PREDEPEND")) 1113*5c51f124SMoriah Waterland predepend(pt); 1114*5c51f124SMoriah Waterland (void) chdir("/"); 1115*5c51f124SMoriah Waterland if (rrmdir(pkgloc)) 1116*5c51f124SMoriah Waterland warnflag++; 1117*5c51f124SMoriah Waterland } 1118*5c51f124SMoriah Waterland 1119*5c51f124SMoriah Waterland if ((z_running_in_global_zone() == B_TRUE) && 1120*5c51f124SMoriah Waterland (pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE)) { 1121*5c51f124SMoriah Waterland boolean_t b; 1122*5c51f124SMoriah Waterland 1123*5c51f124SMoriah Waterland b = pkgRemovePackageFromGzonlyList(get_inst_root(), pkginst); 1124*5c51f124SMoriah Waterland if (b == B_FALSE) { 1125*5c51f124SMoriah Waterland progerr(ERR_PKGREMOVE_GZONLY_REMOVE, pkginst); 1126*5c51f124SMoriah Waterland ckreturn(1, NULL); 1127*5c51f124SMoriah Waterland } 1128*5c51f124SMoriah Waterland } 1129*5c51f124SMoriah Waterland 1130*5c51f124SMoriah Waterland /* release the generic package lock */ 1131*5c51f124SMoriah Waterland 1132*5c51f124SMoriah Waterland (void) unlockinst(); 1133*5c51f124SMoriah Waterland 1134*5c51f124SMoriah Waterland quit(0); 1135*5c51f124SMoriah Waterland /* LINTED: no return */ 1136*5c51f124SMoriah Waterland } 1137*5c51f124SMoriah Waterland 1138*5c51f124SMoriah Waterland int 1139*5c51f124SMoriah Waterland issymlink(char *path) 1140*5c51f124SMoriah Waterland { 1141*5c51f124SMoriah Waterland struct stat statbuf; 1142*5c51f124SMoriah Waterland 1143*5c51f124SMoriah Waterland /* 1144*5c51f124SMoriah Waterland * Obtain status of path; if symbolic link get link's status 1145*5c51f124SMoriah Waterland */ 1146*5c51f124SMoriah Waterland 1147*5c51f124SMoriah Waterland if (lstat(path, &statbuf) != 0) { 1148*5c51f124SMoriah Waterland return (1); /* not symlink */ 1149*5c51f124SMoriah Waterland } 1150*5c51f124SMoriah Waterland 1151*5c51f124SMoriah Waterland /* 1152*5c51f124SMoriah Waterland * Status obtained - if symbolic link, return 0 1153*5c51f124SMoriah Waterland */ 1154*5c51f124SMoriah Waterland 1155*5c51f124SMoriah Waterland if ((statbuf.st_mode & S_IFMT) == S_IFLNK) { 1156*5c51f124SMoriah Waterland return (0); /* is a symlink */ 1157*5c51f124SMoriah Waterland } 1158*5c51f124SMoriah Waterland 1159*5c51f124SMoriah Waterland /* 1160*5c51f124SMoriah Waterland * Not a symbolic link - return 1 1161*5c51f124SMoriah Waterland */ 1162*5c51f124SMoriah Waterland 1163*5c51f124SMoriah Waterland return (1); /* not symlink */ 1164*5c51f124SMoriah Waterland } 1165*5c51f124SMoriah Waterland 1166*5c51f124SMoriah Waterland static void 1167*5c51f124SMoriah Waterland rmclass(char *aclass, int rm_remote, char *a_zoneName) 1168*5c51f124SMoriah Waterland { 1169*5c51f124SMoriah Waterland struct cfent *ept; 1170*5c51f124SMoriah Waterland FILE *fp; 1171*5c51f124SMoriah Waterland char tmpfile[PATH_MAX]; 1172*5c51f124SMoriah Waterland char script[PATH_MAX]; 1173*5c51f124SMoriah Waterland int i; 1174*5c51f124SMoriah Waterland char *tmp_path; 1175*5c51f124SMoriah Waterland char *save_path = NULL; 1176*5c51f124SMoriah Waterland struct stat st; 1177*5c51f124SMoriah Waterland 1178*5c51f124SMoriah Waterland if (aclass == NULL) { 1179*5c51f124SMoriah Waterland for (i = 0; i < eptnum; i++) { 1180*5c51f124SMoriah Waterland if (eptlist[i] != NULL) { 1181*5c51f124SMoriah Waterland rmclass(eptlist[i]->pkg_class, 1182*5c51f124SMoriah Waterland rm_remote, a_zoneName); 1183*5c51f124SMoriah Waterland } 1184*5c51f124SMoriah Waterland } 1185*5c51f124SMoriah Waterland return; 1186*5c51f124SMoriah Waterland } 1187*5c51f124SMoriah Waterland 1188*5c51f124SMoriah Waterland /* locate class action script to execute */ 1189*5c51f124SMoriah Waterland (void) snprintf(script, sizeof (script), "%s/r.%s", pkgbin, aclass); 1190*5c51f124SMoriah Waterland if (access(script, F_OK) != 0) { 1191*5c51f124SMoriah Waterland (void) snprintf(script, sizeof (script), "%s/r.%s", 1192*5c51f124SMoriah Waterland PKGSCR, aclass); 1193*5c51f124SMoriah Waterland if (access(script, F_OK) != 0) 1194*5c51f124SMoriah Waterland script[0] = '\0'; 1195*5c51f124SMoriah Waterland } 1196*5c51f124SMoriah Waterland if (script[0] != '\0') { 1197*5c51f124SMoriah Waterland int td; 1198*5c51f124SMoriah Waterland 1199*5c51f124SMoriah Waterland (void) snprintf(tmpfile, sizeof (tmpfile), "%s/RMLISTXXXXXX", 1200*5c51f124SMoriah Waterland tmpdir); 1201*5c51f124SMoriah Waterland td = mkstemp(tmpfile); 1202*5c51f124SMoriah Waterland if (td == -1) { 1203*5c51f124SMoriah Waterland progerr(ERR_TMPFILE); 1204*5c51f124SMoriah Waterland quit(99); 1205*5c51f124SMoriah Waterland } 1206*5c51f124SMoriah Waterland if ((fp = fdopen(td, "w")) == NULL) { 1207*5c51f124SMoriah Waterland progerr(ERR_WTMPFILE, tmpfile); 1208*5c51f124SMoriah Waterland quit(99); 1209*5c51f124SMoriah Waterland } 1210*5c51f124SMoriah Waterland } 1211*5c51f124SMoriah Waterland 1212*5c51f124SMoriah Waterland if (a_zoneName == (char *)NULL) { 1213*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_REMPATHCLASS_GZ, aclass); 1214*5c51f124SMoriah Waterland } else { 1215*5c51f124SMoriah Waterland echo(MSG_PKGREMOVE_REMPATHCLASS_LZ, aclass, a_zoneName); 1216*5c51f124SMoriah Waterland } 1217*5c51f124SMoriah Waterland 1218*5c51f124SMoriah Waterland /* process paths in reverse order */ 1219*5c51f124SMoriah Waterland i = eptnum; 1220*5c51f124SMoriah Waterland while (--i >= 0) { 1221*5c51f124SMoriah Waterland ept = eptlist[i]; 1222*5c51f124SMoriah Waterland 1223*5c51f124SMoriah Waterland if ((ept == NULL) || strcmp(aclass, ept->pkg_class)) { 1224*5c51f124SMoriah Waterland continue; 1225*5c51f124SMoriah Waterland } 1226*5c51f124SMoriah Waterland 1227*5c51f124SMoriah Waterland /* save the path, and prepend the ir */ 1228*5c51f124SMoriah Waterland if (is_an_inst_root()) { 1229*5c51f124SMoriah Waterland save_path = ept->path; 1230*5c51f124SMoriah Waterland tmp_path = fixpath(ept->path); 1231*5c51f124SMoriah Waterland ept->path = tmp_path; 1232*5c51f124SMoriah Waterland } 1233*5c51f124SMoriah Waterland 1234*5c51f124SMoriah Waterland if (!ept->ftype || (ept->ftype == '^' && !script[0])) { 1235*5c51f124SMoriah Waterland /* 1236*5c51f124SMoriah Waterland * A path owned by more than one package is marked with 1237*5c51f124SMoriah Waterland * a NULL ftype (seems odd, but that's how it's 1238*5c51f124SMoriah Waterland * done). Such files are sacro sanct. Shared editable 1239*5c51f124SMoriah Waterland * files are a special case, and are marked with an 1240*5c51f124SMoriah Waterland * ftype of '^'. These files should only be ignored if 1241*5c51f124SMoriah Waterland * no class action script is present. It is the CAS's 1242*5c51f124SMoriah Waterland * responsibility to not remove the editable object. 1243*5c51f124SMoriah Waterland */ 1244*5c51f124SMoriah Waterland echo(MSG_SHARED, ept->path); 1245*5c51f124SMoriah Waterland } else if (ept->pinfo->status == SERVED_FILE && !rm_remote) { 1246*5c51f124SMoriah Waterland /* 1247*5c51f124SMoriah Waterland * If the path is provided to the client from a 1248*5c51f124SMoriah Waterland * server, don't remove anything unless explicitly 1249*5c51f124SMoriah Waterland * requested through the "-f" option. 1250*5c51f124SMoriah Waterland */ 1251*5c51f124SMoriah Waterland echo(MSG_SERVER, ept->path); 1252*5c51f124SMoriah Waterland } else if (z_path_is_inherited(ept->path, ept->ftype, 1253*5c51f124SMoriah Waterland get_inst_root())) { 1254*5c51f124SMoriah Waterland /* 1255*5c51f124SMoriah Waterland * object is in an area inherited from the global zone, 1256*5c51f124SMoriah Waterland * and the object cannot be removed - output a message 1257*5c51f124SMoriah Waterland * indicating the object cannot be removed and continue. 1258*5c51f124SMoriah Waterland */ 1259*5c51f124SMoriah Waterland echo(MSG_NOTREMOVED_INHERITED, ept->path); 1260*5c51f124SMoriah Waterland } else if (script[0]) { 1261*5c51f124SMoriah Waterland /* 1262*5c51f124SMoriah Waterland * If there's a class action script, just put the 1263*5c51f124SMoriah Waterland * path name into the list. 1264*5c51f124SMoriah Waterland */ 1265*5c51f124SMoriah Waterland (void) fprintf(fp, "%s\n", ept->path); 1266*5c51f124SMoriah Waterland } else if (strchr("dx", ept->ftype) != NULL || 1267*5c51f124SMoriah Waterland (lstat(ept->path, &st) == 0 && S_ISDIR(st.st_mode))) { 1268*5c51f124SMoriah Waterland /* Directories are rmdir()'d. */ 1269*5c51f124SMoriah Waterland 1270*5c51f124SMoriah Waterland if (rmdir(ept->path)) { 1271*5c51f124SMoriah Waterland if (errno == EBUSY) { 1272*5c51f124SMoriah Waterland echo(MSG_DIRBUSY, ept->path); 1273*5c51f124SMoriah Waterland } else if (errno == EEXIST) { 1274*5c51f124SMoriah Waterland echo(MSG_NOTEMPTY, ept->path); 1275*5c51f124SMoriah Waterland } else if (errno != ENOENT) { 1276*5c51f124SMoriah Waterland progerr(ERR_RMDIR, ept->path); 1277*5c51f124SMoriah Waterland warnflag++; 1278*5c51f124SMoriah Waterland } 1279*5c51f124SMoriah Waterland } else { 1280*5c51f124SMoriah Waterland if (ept->pinfo->status == SERVED_FILE) { 1281*5c51f124SMoriah Waterland echo(MSG_RMSRVR, ept->path); 1282*5c51f124SMoriah Waterland } else { 1283*5c51f124SMoriah Waterland echo("%s", ept->path); 1284*5c51f124SMoriah Waterland } 1285*5c51f124SMoriah Waterland } 1286*5c51f124SMoriah Waterland 1287*5c51f124SMoriah Waterland } else { 1288*5c51f124SMoriah Waterland /* 1289*5c51f124SMoriah Waterland * Before removing this object one more 1290*5c51f124SMoriah Waterland * check should be done to assure that a 1291*5c51f124SMoriah Waterland * shared object is not removed. 1292*5c51f124SMoriah Waterland * This can happen if the original object 1293*5c51f124SMoriah Waterland * was incorrectly updated with the 1294*5c51f124SMoriah Waterland * incorrect class identifier. 1295*5c51f124SMoriah Waterland * This handles pathologcal cases that 1296*5c51f124SMoriah Waterland * weren't handled above. 1297*5c51f124SMoriah Waterland */ 1298*5c51f124SMoriah Waterland if (ept->npkgs > 1) { 1299*5c51f124SMoriah Waterland echo(MSG_SHARED, ept->path); 1300*5c51f124SMoriah Waterland continue; 1301*5c51f124SMoriah Waterland } 1302*5c51f124SMoriah Waterland 1303*5c51f124SMoriah Waterland /* Regular files are unlink()'d. */ 1304*5c51f124SMoriah Waterland 1305*5c51f124SMoriah Waterland if (unlink(ept->path)) { 1306*5c51f124SMoriah Waterland if (errno != ENOENT) { 1307*5c51f124SMoriah Waterland progerr(ERR_RMPATH, ept->path); 1308*5c51f124SMoriah Waterland warnflag++; 1309*5c51f124SMoriah Waterland } 1310*5c51f124SMoriah Waterland } else { 1311*5c51f124SMoriah Waterland if (ept->pinfo->status == SERVED_FILE) { 1312*5c51f124SMoriah Waterland echo(MSG_RMSRVR, ept->path); 1313*5c51f124SMoriah Waterland } else { 1314*5c51f124SMoriah Waterland echo("%s", ept->path); 1315*5c51f124SMoriah Waterland } 1316*5c51f124SMoriah Waterland } 1317*5c51f124SMoriah Waterland } 1318*5c51f124SMoriah Waterland 1319*5c51f124SMoriah Waterland /* restore the original path */ 1320*5c51f124SMoriah Waterland 1321*5c51f124SMoriah Waterland if (is_an_inst_root()) { 1322*5c51f124SMoriah Waterland ept->path = save_path; 1323*5c51f124SMoriah Waterland } 1324*5c51f124SMoriah Waterland 1325*5c51f124SMoriah Waterland /* 1326*5c51f124SMoriah Waterland * free memory allocated for this entry memory used for 1327*5c51f124SMoriah Waterland * pathnames will be freed later by a call to pathdup() 1328*5c51f124SMoriah Waterland */ 1329*5c51f124SMoriah Waterland 1330*5c51f124SMoriah Waterland if (eptlist[i]) { 1331*5c51f124SMoriah Waterland free(eptlist[i]); 1332*5c51f124SMoriah Waterland } 1333*5c51f124SMoriah Waterland eptlist[i] = NULL; 1334*5c51f124SMoriah Waterland } 1335*5c51f124SMoriah Waterland if (script[0]) { 1336*5c51f124SMoriah Waterland (void) fclose(fp); 1337*5c51f124SMoriah Waterland set_ulimit(script, ERR_CASFAIL); 1338*5c51f124SMoriah Waterland if (pkgverbose) 1339*5c51f124SMoriah Waterland ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER, 1340*5c51f124SMoriah Waterland CAS_GRP, SHELL, "-x", script, NULL), 1341*5c51f124SMoriah Waterland ERR_CASFAIL); 1342*5c51f124SMoriah Waterland else 1343*5c51f124SMoriah Waterland ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER, 1344*5c51f124SMoriah Waterland CAS_GRP, SHELL, script, NULL), 1345*5c51f124SMoriah Waterland ERR_CASFAIL); 1346*5c51f124SMoriah Waterland clr_ulimit(); 1347*5c51f124SMoriah Waterland if (isfile(NULL, tmpfile) == 0) { 1348*5c51f124SMoriah Waterland if (unlink(tmpfile) == -1) 1349*5c51f124SMoriah Waterland progerr(ERR_RMPATH, tmpfile); 1350*5c51f124SMoriah Waterland } 1351*5c51f124SMoriah Waterland } 1352*5c51f124SMoriah Waterland } 1353*5c51f124SMoriah Waterland 1354*5c51f124SMoriah Waterland static void 1355*5c51f124SMoriah Waterland ckreturn(int retcode, char *msg) 1356*5c51f124SMoriah Waterland { 1357*5c51f124SMoriah Waterland switch (retcode) { 1358*5c51f124SMoriah Waterland case 2: 1359*5c51f124SMoriah Waterland case 12: 1360*5c51f124SMoriah Waterland case 22: 1361*5c51f124SMoriah Waterland warnflag++; 1362*5c51f124SMoriah Waterland /*FALLTHRU*/ 1363*5c51f124SMoriah Waterland if (msg) 1364*5c51f124SMoriah Waterland progerr(msg); 1365*5c51f124SMoriah Waterland case 10: 1366*5c51f124SMoriah Waterland case 20: 1367*5c51f124SMoriah Waterland if (retcode >= 10) 1368*5c51f124SMoriah Waterland dreboot++; 1369*5c51f124SMoriah Waterland if (retcode >= 20) 1370*5c51f124SMoriah Waterland ireboot++; 1371*5c51f124SMoriah Waterland /*FALLTHRU*/ 1372*5c51f124SMoriah Waterland case 0: 1373*5c51f124SMoriah Waterland break; /* okay */ 1374*5c51f124SMoriah Waterland 1375*5c51f124SMoriah Waterland case -1: 1376*5c51f124SMoriah Waterland retcode = 99; 1377*5c51f124SMoriah Waterland /*FALLTHRU*/ 1378*5c51f124SMoriah Waterland case 99: 1379*5c51f124SMoriah Waterland case 1: 1380*5c51f124SMoriah Waterland case 11: 1381*5c51f124SMoriah Waterland case 21: 1382*5c51f124SMoriah Waterland case 4: 1383*5c51f124SMoriah Waterland case 14: 1384*5c51f124SMoriah Waterland case 24: 1385*5c51f124SMoriah Waterland case 5: 1386*5c51f124SMoriah Waterland case 15: 1387*5c51f124SMoriah Waterland case 25: 1388*5c51f124SMoriah Waterland if (msg) 1389*5c51f124SMoriah Waterland progerr(msg); 1390*5c51f124SMoriah Waterland /*FALLTHRU*/ 1391*5c51f124SMoriah Waterland case 3: 1392*5c51f124SMoriah Waterland case 13: 1393*5c51f124SMoriah Waterland case 23: 1394*5c51f124SMoriah Waterland quit(retcode); 1395*5c51f124SMoriah Waterland /* NOT REACHED */ 1396*5c51f124SMoriah Waterland default: 1397*5c51f124SMoriah Waterland if (msg) 1398*5c51f124SMoriah Waterland progerr(msg); 1399*5c51f124SMoriah Waterland quit(1); 1400*5c51f124SMoriah Waterland } 1401*5c51f124SMoriah Waterland } 1402*5c51f124SMoriah Waterland 1403*5c51f124SMoriah Waterland static void 1404*5c51f124SMoriah Waterland usage(void) 1405*5c51f124SMoriah Waterland { 1406*5c51f124SMoriah Waterland (void) fprintf(stderr, ERR_USAGE_PKGREMOVE); 1407*5c51f124SMoriah Waterland 1408*5c51f124SMoriah Waterland exit(1); 1409*5c51f124SMoriah Waterland } 1410*5c51f124SMoriah Waterland 1411*5c51f124SMoriah Waterland /* 1412*5c51f124SMoriah Waterland * Name: path_valid 1413*5c51f124SMoriah Waterland * Description: Checks a string for being a valid path 1414*5c51f124SMoriah Waterland * 1415*5c51f124SMoriah Waterland * Arguments: path - path to validate 1416*5c51f124SMoriah Waterland * 1417*5c51f124SMoriah Waterland * Returns : B_TRUE - success, B_FALSE otherwise. 1418*5c51f124SMoriah Waterland * B_FALSE means path was null, too long (>PATH_MAX), 1419*5c51f124SMoriah Waterland * or too short (<1) 1420*5c51f124SMoriah Waterland */ 1421*5c51f124SMoriah Waterland static boolean_t 1422*5c51f124SMoriah Waterland path_valid(char *path) 1423*5c51f124SMoriah Waterland { 1424*5c51f124SMoriah Waterland if (path == NULL) { 1425*5c51f124SMoriah Waterland return (B_FALSE); 1426*5c51f124SMoriah Waterland } else if (strlen(path) > PATH_MAX) { 1427*5c51f124SMoriah Waterland return (B_FALSE); 1428*5c51f124SMoriah Waterland } else if (strlen(path) >= 1) { 1429*5c51f124SMoriah Waterland return (B_TRUE); 1430*5c51f124SMoriah Waterland } else { 1431*5c51f124SMoriah Waterland /* path < 1 */ 1432*5c51f124SMoriah Waterland return (B_FALSE); 1433*5c51f124SMoriah Waterland } 1434*5c51f124SMoriah Waterland } 1435