15c51f124SMoriah Waterland /* 25c51f124SMoriah Waterland * CDDL HEADER START 35c51f124SMoriah Waterland * 45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 55c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 65c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 75c51f124SMoriah Waterland * 85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 105c51f124SMoriah Waterland * See the License for the specific language governing permissions 115c51f124SMoriah Waterland * and limitations under the License. 125c51f124SMoriah Waterland * 135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 185c51f124SMoriah Waterland * 195c51f124SMoriah Waterland * CDDL HEADER END 205c51f124SMoriah Waterland */ 215c51f124SMoriah Waterland 225c51f124SMoriah Waterland /* 23*6e1ae2a3SGary Pennington * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 245c51f124SMoriah Waterland */ 255c51f124SMoriah Waterland 265c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 275c51f124SMoriah Waterland /* All Rights Reserved */ 285c51f124SMoriah Waterland 295c51f124SMoriah Waterland 305c51f124SMoriah Waterland #include <stdio.h> 315c51f124SMoriah Waterland #include <limits.h> 325c51f124SMoriah Waterland #include <stdlib.h> 335c51f124SMoriah Waterland #include <unistd.h> 345c51f124SMoriah Waterland #include <string.h> 355c51f124SMoriah Waterland #include <signal.h> 365c51f124SMoriah Waterland #include <errno.h> 375c51f124SMoriah Waterland #include <fcntl.h> 385c51f124SMoriah Waterland #include <sys/stat.h> 395c51f124SMoriah Waterland #include <sys/types.h> 405c51f124SMoriah Waterland #include <pkgstrct.h> 415c51f124SMoriah Waterland #include <pkginfo.h> 425c51f124SMoriah Waterland #include <pkglocs.h> 435c51f124SMoriah Waterland #include <locale.h> 445c51f124SMoriah Waterland #include <libintl.h> 455c51f124SMoriah Waterland #include <assert.h> 465c51f124SMoriah Waterland #include <cfext.h> 475c51f124SMoriah Waterland #include <instzones_api.h> 485c51f124SMoriah Waterland #include <pkglib.h> 495c51f124SMoriah Waterland #include <install.h> 505c51f124SMoriah Waterland #include <libinst.h> 515c51f124SMoriah Waterland #include <libadm.h> 525c51f124SMoriah Waterland #include <messages.h> 535c51f124SMoriah Waterland 545c51f124SMoriah Waterland struct cfent **eptlist; 555c51f124SMoriah Waterland extern int eptnum; 565c51f124SMoriah Waterland 575c51f124SMoriah Waterland extern char *pkgdir; 585c51f124SMoriah Waterland extern char **environ; 595c51f124SMoriah Waterland 605c51f124SMoriah Waterland /* quit.c */ 615c51f124SMoriah Waterland extern sighdlrFunc_t *quitGetTrapHandler(void); 625c51f124SMoriah Waterland extern void quitSetSilentExit(boolean_t a_silentExit); 635c51f124SMoriah Waterland extern void quitSetZoneName(char *a_zoneName); 645c51f124SMoriah Waterland 655c51f124SMoriah Waterland 665c51f124SMoriah Waterland 675c51f124SMoriah Waterland /* check.c */ 685c51f124SMoriah Waterland extern void rcksetPreremoveCheck(boolean_t); 695c51f124SMoriah Waterland extern void rcksetZoneName(char *); 705c51f124SMoriah Waterland extern int rckpriv(void); 715c51f124SMoriah Waterland extern int rckdepend(void); 725c51f124SMoriah Waterland extern int rckrunlevel(void); 735c51f124SMoriah Waterland 745c51f124SMoriah Waterland /* predepend.c */ 755c51f124SMoriah Waterland extern void predepend(char *oldpkg); 765c51f124SMoriah Waterland 775c51f124SMoriah Waterland /* delmap.c */ 7862224350SCasper H.S. Dik extern int delmap(int flag, char *pkginst, PKGserver *server, VFP_T **tfp); 795c51f124SMoriah Waterland 805c51f124SMoriah Waterland #define DEFPATH "/sbin:/usr/sbin:/usr/bin" 815c51f124SMoriah Waterland 825c51f124SMoriah Waterland #ifdef ALLOW_EXCEPTION_PKG_LIST 835c51f124SMoriah Waterland #define SCRIPT 0 /* Tells exception_pkg() which pkg list to use */ 845c51f124SMoriah Waterland #define LINK 1 855c51f124SMoriah Waterland #endif 865c51f124SMoriah Waterland 875c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 885c51f124SMoriah Waterland #define TEXT_DOMAIN "SYS_TEST" 895c51f124SMoriah Waterland #endif 905c51f124SMoriah Waterland 915c51f124SMoriah Waterland /* This is the text for the "-O parent-zone-name=" option */ 925c51f124SMoriah Waterland 935c51f124SMoriah Waterland #define PARENTZONENAME "parent-zone-name=" 945c51f124SMoriah Waterland #define PARENTZONENAME_LEN ((sizeof (PARENTZONENAME))-1) 955c51f124SMoriah Waterland 965c51f124SMoriah Waterland /* This is the text for the "-O parent-zone-type=" option */ 975c51f124SMoriah Waterland 985c51f124SMoriah Waterland #define PARENTZONETYPE "parent-zone-type=" 995c51f124SMoriah Waterland #define PARENTZONETYPE_LEN ((sizeof (PARENTZONETYPE))-1) 1005c51f124SMoriah Waterland 1015c51f124SMoriah Waterland struct admin adm; /* holds info about installation admin */ 1025c51f124SMoriah Waterland int dreboot; /* non-zero if reboot required after installation */ 1035c51f124SMoriah Waterland int ireboot; /* non-zero if immediate reboot required */ 1045c51f124SMoriah Waterland int failflag; /* non-zero if fatal error has occurred */ 1055c51f124SMoriah Waterland int warnflag; /* non-zero if non-fatal error has occurred */ 1065c51f124SMoriah Waterland int pkgverbose; /* non-zero if verbose mode is selected */ 1075c51f124SMoriah Waterland int started; 1085c51f124SMoriah Waterland int nocnflct = 0; /* pkgdbmerg needs this defined */ 1095c51f124SMoriah Waterland int nosetuid = 0; /* pkgdbmerg needs this defined */ 1105c51f124SMoriah Waterland 1115c51f124SMoriah Waterland char *pkginst; /* current package (source) instance to process */ 1125c51f124SMoriah Waterland 1135c51f124SMoriah Waterland int dbchg; 1145c51f124SMoriah Waterland char *msgtext; 1155c51f124SMoriah Waterland char pkgloc[PATH_MAX]; 1165c51f124SMoriah Waterland 1175c51f124SMoriah Waterland /* 1185c51f124SMoriah Waterland * The following variable is the name of the device to which stdin 1195c51f124SMoriah Waterland * is connected during execution of a procedure script. /dev/null is 1205c51f124SMoriah Waterland * correct for all ABI compliant packages. For non-ABI-compliant 1215c51f124SMoriah Waterland * packages, the '-o' command line switch changes this to /dev/tty 1225c51f124SMoriah Waterland * to allow user interaction during these scripts. -- JST 1235c51f124SMoriah Waterland */ 1245c51f124SMoriah Waterland static char *script_in = PROC_STDIN; /* assume ABI compliance */ 1255c51f124SMoriah Waterland 1265c51f124SMoriah Waterland static char *client_mntdir; /* mount point for client's basedir */ 1275c51f124SMoriah Waterland static char pkgbin[PATH_MAX], 1285c51f124SMoriah Waterland rlockfile[PATH_MAX], 1295c51f124SMoriah Waterland *admnfile, /* file to use for installation admin */ 1305c51f124SMoriah Waterland *tmpdir; /* location to place temporary files */ 1315c51f124SMoriah Waterland 1325c51f124SMoriah Waterland static boolean_t path_valid(char *path); 1335c51f124SMoriah Waterland static void ckreturn(int retcode, char *msg); 1345c51f124SMoriah Waterland static void rmclass(char *aclass, int rm_remote, char *a_zoneName); 1355c51f124SMoriah Waterland static void usage(void); 1365c51f124SMoriah Waterland 1375c51f124SMoriah Waterland /* 1385c51f124SMoriah Waterland * Set by -O debug: debug output is enabled? 1395c51f124SMoriah Waterland */ 1405c51f124SMoriah Waterland static boolean_t debugFlag = B_FALSE; 1415c51f124SMoriah Waterland 1425c51f124SMoriah Waterland /* 1435c51f124SMoriah Waterland * Set by -O preremovecheck: do remove dependency checking only 1445c51f124SMoriah Waterland */ 1455c51f124SMoriah Waterland static boolean_t preremoveCheck = B_FALSE; 1465c51f124SMoriah Waterland 1475c51f124SMoriah Waterland /* Set by -O parent-zone-name= */ 1485c51f124SMoriah Waterland 1495c51f124SMoriah Waterland static char *parentZoneName = (char *)NULL; 1505c51f124SMoriah Waterland 1515c51f124SMoriah Waterland /* Set by -O parent-zone-type= */ 1525c51f124SMoriah Waterland 1535c51f124SMoriah Waterland static char *parentZoneType = (char *)NULL; 1545c51f124SMoriah Waterland 1555c51f124SMoriah Waterland static int nointeract; /* != 0 no interaction with user should occur */ 1565c51f124SMoriah Waterland 1575c51f124SMoriah Waterland 1585c51f124SMoriah Waterland 1595c51f124SMoriah Waterland int 1605c51f124SMoriah Waterland main(int argc, char *argv[]) 1615c51f124SMoriah Waterland { 1625c51f124SMoriah Waterland FILE *fp; 1635c51f124SMoriah Waterland char *abi_comp_ptr; 1645c51f124SMoriah Waterland char *abi_sym_ptr; 1655c51f124SMoriah Waterland char *p; 1665c51f124SMoriah Waterland char *prog_full_name = NULL; 1675c51f124SMoriah Waterland char *pt; 1685c51f124SMoriah Waterland char *value; 1695c51f124SMoriah Waterland char *vfstab_file = NULL; 1705c51f124SMoriah Waterland char *zoneName = (char *)NULL; 1715c51f124SMoriah Waterland char cmdbin[PATH_MAX]; 1725c51f124SMoriah Waterland char param[MAX_PKG_PARAM_LENGTH]; 1735c51f124SMoriah Waterland char path[PATH_MAX]; 1745c51f124SMoriah Waterland char script[PATH_MAX]; 1755c51f124SMoriah Waterland int c; 1765c51f124SMoriah Waterland int err; 1775c51f124SMoriah Waterland int fd; 1785c51f124SMoriah Waterland int i; 1795c51f124SMoriah Waterland int map_client = 1; 1805c51f124SMoriah Waterland int n; 1815c51f124SMoriah Waterland int nodelete = 0; /* do not delete file or run scripts */ 1825c51f124SMoriah Waterland int pkgrmremote = 0; /* dont remove remote objects */ 1835c51f124SMoriah Waterland struct sigaction nact; 1845c51f124SMoriah Waterland struct sigaction oact; 18562224350SCasper H.S. Dik PKGserver pkgserver = NULL; 18662224350SCasper H.S. Dik VFP_T *tmpfp; 1875c51f124SMoriah Waterland 1885c51f124SMoriah Waterland /* reset contents of all default paths */ 1895c51f124SMoriah Waterland 1905c51f124SMoriah Waterland (void) memset(cmdbin, '\0', sizeof (cmdbin)); 1915c51f124SMoriah Waterland 1925c51f124SMoriah Waterland /* initialize locale environment */ 1935c51f124SMoriah Waterland 1945c51f124SMoriah Waterland (void) setlocale(LC_ALL, ""); 1955c51f124SMoriah Waterland (void) textdomain(TEXT_DOMAIN); 1965c51f124SMoriah Waterland 1975c51f124SMoriah Waterland /* initialize program name */ 1985c51f124SMoriah Waterland 1995c51f124SMoriah Waterland prog_full_name = argv[0]; 2005c51f124SMoriah Waterland (void) set_prog_name(argv[0]); 2015c51f124SMoriah Waterland 2025c51f124SMoriah Waterland /* tell spmi zones interface how to access package output functions */ 2035c51f124SMoriah Waterland 2045c51f124SMoriah Waterland z_set_output_functions(echo, echoDebug, progerr); 2055c51f124SMoriah Waterland 2065c51f124SMoriah Waterland /* exit if not root */ 2075c51f124SMoriah Waterland 2085c51f124SMoriah Waterland if (getuid()) { 2095c51f124SMoriah Waterland progerr(ERR_NOT_ROOT, get_prog_name()); 2105c51f124SMoriah Waterland exit(1); 2115c51f124SMoriah Waterland /* NOTREACHED */ 2125c51f124SMoriah Waterland } 2135c51f124SMoriah Waterland 2145c51f124SMoriah Waterland /* Read PKG_INSTALL_ROOT from the environment, if it's there. */ 2155c51f124SMoriah Waterland 2165c51f124SMoriah Waterland if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) { 2175c51f124SMoriah Waterland progerr(ERR_ROOT_SET); 2185c51f124SMoriah Waterland exit(1); 2195c51f124SMoriah Waterland } 2205c51f124SMoriah Waterland 22162224350SCasper H.S. Dik pkgserversetmode(DEFAULTMODE); 22262224350SCasper H.S. Dik 2235c51f124SMoriah Waterland /* parse command line options */ 2245c51f124SMoriah Waterland 2255c51f124SMoriah Waterland while ((c = getopt(argc, argv, "?Aa:b:FMN:nO:oR:V:vy")) != EOF) { 2265c51f124SMoriah Waterland switch (c) { 2275c51f124SMoriah Waterland /* 2285c51f124SMoriah Waterland * Same as pkgrm: Allow admin to remove package objects from 2295c51f124SMoriah Waterland * a shared area from a reference client. 2305c51f124SMoriah Waterland */ 2315c51f124SMoriah Waterland case 'A': 2325c51f124SMoriah Waterland pkgrmremote++; 2335c51f124SMoriah Waterland break; 2345c51f124SMoriah Waterland 2355c51f124SMoriah Waterland /* 2365c51f124SMoriah Waterland * Same as pkgrm: Use the installation 2375c51f124SMoriah Waterland * administration file, admin, in place of the 2385c51f124SMoriah Waterland * default admin file. pkgrm first looks in the 2395c51f124SMoriah Waterland * current working directory for the administration 2405c51f124SMoriah Waterland * file. If the specified administration file is not 2415c51f124SMoriah Waterland * in the current working directory, pkgrm looks in 2425c51f124SMoriah Waterland * the /var/sadm/install/admin directory for the 2435c51f124SMoriah Waterland * administration file. 2445c51f124SMoriah Waterland */ 2455c51f124SMoriah Waterland case 'a': 2465c51f124SMoriah Waterland admnfile = flex_device(optarg, 0); 2475c51f124SMoriah Waterland break; 2485c51f124SMoriah Waterland 2495c51f124SMoriah Waterland /* 2505c51f124SMoriah Waterland * Same as pkgrm: location where package executables 2515c51f124SMoriah Waterland * can be found - default is /usr/sadm/install/bin. 2525c51f124SMoriah Waterland */ 2535c51f124SMoriah Waterland case 'b': 2545c51f124SMoriah Waterland if (!path_valid(optarg)) { 2555c51f124SMoriah Waterland progerr(ERR_PATH, optarg); 2565c51f124SMoriah Waterland exit(1); 2575c51f124SMoriah Waterland } 2585c51f124SMoriah Waterland if (isdir(optarg) != 0) { 2595c51f124SMoriah Waterland char *p = strerror(errno); 2605c51f124SMoriah Waterland progerr(ERR_CANNOT_USE_DIR, optarg, p); 2615c51f124SMoriah Waterland exit(1); 2625c51f124SMoriah Waterland } 2635c51f124SMoriah Waterland (void) strlcpy(cmdbin, optarg, sizeof (cmdbin)); 2645c51f124SMoriah Waterland break; 2655c51f124SMoriah Waterland 2665c51f124SMoriah Waterland /* 2675c51f124SMoriah Waterland * Same as pkgrm: suppresses the removal of any 2685c51f124SMoriah Waterland * files and any class action scripts, and suppresses 2695c51f124SMoriah Waterland * the running of any class action scripts. The 2705c51f124SMoriah Waterland * package files remain but the package looks like it 2715c51f124SMoriah Waterland * is not installed. This is mainly for use by the 2725c51f124SMoriah Waterland * upgrade process. 2735c51f124SMoriah Waterland */ 2745c51f124SMoriah Waterland case 'F': 2755c51f124SMoriah Waterland nodelete++; 2765c51f124SMoriah Waterland break; 2775c51f124SMoriah Waterland 2785c51f124SMoriah Waterland /* 2795c51f124SMoriah Waterland * Same as pkgrm: Instruct pkgrm not to use the 2805c51f124SMoriah Waterland * $root_path/etc/vfstab file for determining the 2815c51f124SMoriah Waterland * client's mount points. This option assumes the 2825c51f124SMoriah Waterland * mount points are correct on the server and it 2835c51f124SMoriah Waterland * behaves consistently with Solaris 2.5 and earlier 2845c51f124SMoriah Waterland * releases. 2855c51f124SMoriah Waterland */ 2865c51f124SMoriah Waterland case 'M': 2875c51f124SMoriah Waterland map_client = 0; 2885c51f124SMoriah Waterland break; 2895c51f124SMoriah Waterland 2905c51f124SMoriah Waterland /* 2915c51f124SMoriah Waterland * Different from pkgrm: specify program name to use 2925c51f124SMoriah Waterland * for messages. 2935c51f124SMoriah Waterland */ 2945c51f124SMoriah Waterland case 'N': 2955c51f124SMoriah Waterland (void) set_prog_name(optarg); 2965c51f124SMoriah Waterland break; 2975c51f124SMoriah Waterland 2985c51f124SMoriah Waterland /* 2995c51f124SMoriah Waterland * Same as pkgrm: package removal occurs in 3005c51f124SMoriah Waterland * non-interactive mode. Suppress output of the list of 3015c51f124SMoriah Waterland * removed files. The default mode is interactive. 3025c51f124SMoriah Waterland */ 3035c51f124SMoriah Waterland case 'n': 3045c51f124SMoriah Waterland nointeract++; 3055c51f124SMoriah Waterland (void) echoSetFlag(B_FALSE); 3065c51f124SMoriah Waterland break; 3075c51f124SMoriah Waterland 3085c51f124SMoriah Waterland /* 3095c51f124SMoriah Waterland * Almost same as pkgrm: the -O option allows the behavior 3105c51f124SMoriah Waterland * of the package tools to be modified. Recognized options: 3115c51f124SMoriah Waterland * -> debug 3125c51f124SMoriah Waterland * ---> enable debugging output 3135c51f124SMoriah Waterland * -> preremovecheck 3145c51f124SMoriah Waterland * ---> perform a "pre removal" check of the specified 3155c51f124SMoriah Waterland * ---> package - suppress all regular output and cause a 3165c51f124SMoriah Waterland * ---> series of one or more "name=value" pair format lines 3175c51f124SMoriah Waterland * ---> to be output that describes the "removability" of 3185c51f124SMoriah Waterland * ---> the specified package 3195c51f124SMoriah Waterland * -> enable-hollow-package-support 3205c51f124SMoriah Waterland * --> Enable hollow package support. When specified, for any 3215c51f124SMoriah Waterland * --> package that has SUNW_PKG_HOLLOW=true: 3225c51f124SMoriah Waterland * --> Do not calculate and verify package size against target 3235c51f124SMoriah Waterland * --> Do not run any package procedure or class action scripts 3245c51f124SMoriah Waterland * --> Do not create or remove any target directories 3255c51f124SMoriah Waterland * --> Do not perform any script locking 3265c51f124SMoriah Waterland * --> Do not install or uninstall any components of any package 3275c51f124SMoriah Waterland * --> Do not output any status or database update messages 3285c51f124SMoriah Waterland */ 3295c51f124SMoriah Waterland case 'O': 3305c51f124SMoriah Waterland for (p = strtok(optarg, ","); p != (char *)NULL; 3315c51f124SMoriah Waterland p = strtok(NULL, ",")) { 3325c51f124SMoriah Waterland 3335c51f124SMoriah Waterland /* process debug option */ 3345c51f124SMoriah Waterland 3355c51f124SMoriah Waterland if (strcmp(p, "debug") == 0) { 3365c51f124SMoriah Waterland /* set debug flag/enable debug output */ 3375c51f124SMoriah Waterland debugFlag = B_TRUE; 3385c51f124SMoriah Waterland (void) echoDebugSetFlag(debugFlag); 3395c51f124SMoriah Waterland 3405c51f124SMoriah Waterland /* debug info on arguments to pkgadd */ 3415c51f124SMoriah Waterland for (n = 0; n < argc && argv[n]; n++) { 3425c51f124SMoriah Waterland echoDebug(DBG_ARG, n, argv[n]); 3435c51f124SMoriah Waterland } 3445c51f124SMoriah Waterland 3455c51f124SMoriah Waterland continue; 3465c51f124SMoriah Waterland } 3475c51f124SMoriah Waterland 3485c51f124SMoriah Waterland /* process enable-hollow-package-support opt */ 3495c51f124SMoriah Waterland 3505c51f124SMoriah Waterland if (strcmp(p, 3515c51f124SMoriah Waterland "enable-hollow-package-support") == 0) { 3525c51f124SMoriah Waterland set_depend_pkginfo_DB(B_TRUE); 3535c51f124SMoriah Waterland continue; 3545c51f124SMoriah Waterland } 3555c51f124SMoriah Waterland 3565c51f124SMoriah Waterland /* process preremovecheck option */ 3575c51f124SMoriah Waterland 3585c51f124SMoriah Waterland if (strcmp(p, "preremovecheck") == 0) { 3595c51f124SMoriah Waterland preremoveCheck = B_TRUE; 3605c51f124SMoriah Waterland nointeract++; /* -n */ 3615c51f124SMoriah Waterland nodelete++; /* -F */ 3625c51f124SMoriah Waterland quitSetSilentExit(B_TRUE); 3635c51f124SMoriah Waterland continue; 3645c51f124SMoriah Waterland } 3655c51f124SMoriah Waterland 3665c51f124SMoriah Waterland /* process addzonename option */ 3675c51f124SMoriah Waterland 3685c51f124SMoriah Waterland if (strcmp(p, "addzonename") == 0) { 3695c51f124SMoriah Waterland zoneName = z_get_zonename(); 3705c51f124SMoriah Waterland quitSetZoneName(zoneName); 3715c51f124SMoriah Waterland continue; 3725c51f124SMoriah Waterland } 3735c51f124SMoriah Waterland 3745c51f124SMoriah Waterland /* process parent-zone-name option */ 3755c51f124SMoriah Waterland 3765c51f124SMoriah Waterland if (strncmp(p, PARENTZONENAME, 3775c51f124SMoriah Waterland PARENTZONENAME_LEN) == 0) { 3785c51f124SMoriah Waterland parentZoneName = p+PARENTZONENAME_LEN; 3795c51f124SMoriah Waterland continue; 3805c51f124SMoriah Waterland } 3815c51f124SMoriah Waterland 3825c51f124SMoriah Waterland /* process parent-zone-type option */ 3835c51f124SMoriah Waterland 3845c51f124SMoriah Waterland if (strncmp(p, PARENTZONETYPE, 3855c51f124SMoriah Waterland PARENTZONETYPE_LEN) == 0) { 3865c51f124SMoriah Waterland parentZoneType = p+PARENTZONETYPE_LEN; 3875c51f124SMoriah Waterland continue; 3885c51f124SMoriah Waterland } 3895c51f124SMoriah Waterland 39062224350SCasper H.S. Dik if (strncmp(p, PKGSERV_MODE, 39162224350SCasper H.S. Dik PKGSERV_MODE_LEN) == 0) { 39262224350SCasper H.S. Dik pkgserversetmode(pkgparsemode(p + 39362224350SCasper H.S. Dik PKGSERV_MODE_LEN)); 39462224350SCasper H.S. Dik continue; 39562224350SCasper H.S. Dik } 3965c51f124SMoriah Waterland /* option not recognized - issue warning */ 3975c51f124SMoriah Waterland 3985c51f124SMoriah Waterland progerr(ERR_INVALID_O_OPTION, p); 3995c51f124SMoriah Waterland continue; 4005c51f124SMoriah Waterland } 4015c51f124SMoriah Waterland break; 4025c51f124SMoriah Waterland 4035c51f124SMoriah Waterland /* 4045c51f124SMoriah Waterland * Different from pkgrm: This is an old non-ABI package 4055c51f124SMoriah Waterland */ 4065c51f124SMoriah Waterland 4075c51f124SMoriah Waterland case 'o': 4085c51f124SMoriah Waterland script_in = PROC_XSTDIN; 4095c51f124SMoriah Waterland break; 4105c51f124SMoriah Waterland 4115c51f124SMoriah Waterland /* 4125c51f124SMoriah Waterland * Same as pkgrm: defines the full path name of a 4135c51f124SMoriah Waterland * directory to use as the root_path. All files, 4145c51f124SMoriah Waterland * including package system information files, are 4155c51f124SMoriah Waterland * relocated to a directory tree starting in the 4165c51f124SMoriah Waterland * specified root_path. 4175c51f124SMoriah Waterland */ 4185c51f124SMoriah Waterland case 'R': 4195c51f124SMoriah Waterland if (!set_inst_root(optarg)) { 4205c51f124SMoriah Waterland progerr(ERR_ROOT_CMD); 4215c51f124SMoriah Waterland exit(1); 4225c51f124SMoriah Waterland } 4235c51f124SMoriah Waterland break; 4245c51f124SMoriah Waterland 4255c51f124SMoriah Waterland /* 4265c51f124SMoriah Waterland * Same as pkgrm: allow admin to establish the client 4275c51f124SMoriah Waterland * filesystem using a vfstab-like file of stable format. 4285c51f124SMoriah Waterland */ 4295c51f124SMoriah Waterland case 'V': 4305c51f124SMoriah Waterland vfstab_file = flex_device(optarg, 2); 4315c51f124SMoriah Waterland map_client = 1; 4325c51f124SMoriah Waterland break; 4335c51f124SMoriah Waterland 4345c51f124SMoriah Waterland /* 4355c51f124SMoriah Waterland * Same as pkgrm: trace all of the scripts that 4365c51f124SMoriah Waterland * get executed by pkgrm, located in the 4375c51f124SMoriah Waterland * pkginst/install directory. This option is used for 4385c51f124SMoriah Waterland * debugging the procedural and non-procedural 4395c51f124SMoriah Waterland * scripts. 4405c51f124SMoriah Waterland */ 4415c51f124SMoriah Waterland case 'v': 4425c51f124SMoriah Waterland pkgverbose++; 4435c51f124SMoriah Waterland break; 4445c51f124SMoriah Waterland 4455c51f124SMoriah Waterland /* 4465c51f124SMoriah Waterland * Different from pkgrm: process this package using 4475c51f124SMoriah Waterland * old non-ABI symlinks 4485c51f124SMoriah Waterland */ 4495c51f124SMoriah Waterland case 'y': 4505c51f124SMoriah Waterland set_nonABI_symlinks(); 4515c51f124SMoriah Waterland break; 4525c51f124SMoriah Waterland 4535c51f124SMoriah Waterland default: 4545c51f124SMoriah Waterland usage(); 4555c51f124SMoriah Waterland /*NOTREACHED*/ 4565c51f124SMoriah Waterland /* 4575c51f124SMoriah Waterland * Although usage() calls a noreturn function, 4585c51f124SMoriah Waterland * needed to add return (1); so that main() would 4595c51f124SMoriah Waterland * pass compilation checks. The statement below 4605c51f124SMoriah Waterland * should never be executed. 4615c51f124SMoriah Waterland */ 4625c51f124SMoriah Waterland return (1); 4635c51f124SMoriah Waterland } 4645c51f124SMoriah Waterland } 4655c51f124SMoriah Waterland 4665c51f124SMoriah Waterland /* 4675c51f124SMoriah Waterland * ******************************************************************** 4685c51f124SMoriah Waterland * validate command line options 4695c51f124SMoriah Waterland * ******************************************************************** 4705c51f124SMoriah Waterland */ 4715c51f124SMoriah Waterland 4725c51f124SMoriah Waterland (void) echoDebugSetFlag(debugFlag); 4735c51f124SMoriah Waterland (void) log_set_verbose(debugFlag); 4745c51f124SMoriah Waterland 4755c51f124SMoriah Waterland if (z_running_in_global_zone()) { 4765c51f124SMoriah Waterland echoDebug(DBG_ENTRY_IN_GZ, prog_full_name); 4775c51f124SMoriah Waterland } else { 4785c51f124SMoriah Waterland echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(), 4795c51f124SMoriah Waterland z_get_zonename()); 4805c51f124SMoriah Waterland } 4815c51f124SMoriah Waterland 4825c51f124SMoriah Waterland /* establish cmdbin path */ 4835c51f124SMoriah Waterland 4845c51f124SMoriah Waterland if (cmdbin[0] == '\0') { 4855c51f124SMoriah Waterland (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin)); 4865c51f124SMoriah Waterland } 4875c51f124SMoriah Waterland 4885c51f124SMoriah Waterland /* Read the mount table */ 4895c51f124SMoriah Waterland 4905c51f124SMoriah Waterland if (get_mntinfo(map_client, vfstab_file)) { 4915c51f124SMoriah Waterland quit(99); 4925c51f124SMoriah Waterland } 4935c51f124SMoriah Waterland 4945c51f124SMoriah Waterland /* 4955c51f124SMoriah Waterland * This function defines the standard /var/... directories used later 4965c51f124SMoriah Waterland * to construct the paths to the various databases. 4975c51f124SMoriah Waterland */ 4985c51f124SMoriah Waterland 4995c51f124SMoriah Waterland set_PKGpaths(get_inst_root()); 5005c51f124SMoriah Waterland 5015c51f124SMoriah Waterland /* 5025c51f124SMoriah Waterland * If this is being removed from a client whose /var filesystem is 5035c51f124SMoriah Waterland * mounted in some odd way, remap the administrative paths to the 5045c51f124SMoriah Waterland * real filesystem. This could be avoided by simply mounting up the 5055c51f124SMoriah Waterland * client now; but we aren't yet to the point in the process where 5065c51f124SMoriah Waterland * modification of the filesystem is permitted. 5075c51f124SMoriah Waterland */ 5085c51f124SMoriah Waterland if (is_an_inst_root()) { 5095c51f124SMoriah Waterland int fsys_value; 5105c51f124SMoriah Waterland 5115c51f124SMoriah Waterland fsys_value = fsys(get_PKGLOC()); 5125c51f124SMoriah Waterland if (use_srvr_map_n(fsys_value)) 5135c51f124SMoriah Waterland set_PKGLOC(server_map(get_PKGLOC(), fsys_value)); 5145c51f124SMoriah Waterland 5155c51f124SMoriah Waterland fsys_value = fsys(get_PKGADM()); 5165c51f124SMoriah Waterland if (use_srvr_map_n(fsys_value)) 5175c51f124SMoriah Waterland set_PKGADM(server_map(get_PKGADM(), fsys_value)); 5185c51f124SMoriah Waterland } else { 5195c51f124SMoriah Waterland pkgrmremote = 0; /* Makes no sense on local host. */ 5205c51f124SMoriah Waterland } 5215c51f124SMoriah Waterland 5225c51f124SMoriah Waterland /* 5235c51f124SMoriah Waterland * hook SIGINT and SIGHUP interrupts into quit.c's trap handler 5245c51f124SMoriah Waterland */ 5255c51f124SMoriah Waterland 5265c51f124SMoriah Waterland /* hold SIGINT/SIGHUP interrupts */ 5275c51f124SMoriah Waterland 5285c51f124SMoriah Waterland (void) sighold(SIGHUP); 5295c51f124SMoriah Waterland (void) sighold(SIGINT); 5305c51f124SMoriah Waterland 5315c51f124SMoriah Waterland /* connect quit.c:trap() to SIGINT */ 5325c51f124SMoriah Waterland 5335c51f124SMoriah Waterland nact.sa_handler = quitGetTrapHandler(); 5345c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 5355c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 5365c51f124SMoriah Waterland 5375c51f124SMoriah Waterland (void) sigaction(SIGINT, &nact, &oact); 5385c51f124SMoriah Waterland 5395c51f124SMoriah Waterland /* connect quit.c:trap() to SIGHUP */ 5405c51f124SMoriah Waterland 5415c51f124SMoriah Waterland nact.sa_handler = quitGetTrapHandler(); 5425c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 5435c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 5445c51f124SMoriah Waterland 5455c51f124SMoriah Waterland (void) sigaction(SIGHUP, &nact, &oact); 5465c51f124SMoriah Waterland 5475c51f124SMoriah Waterland /* release hold on signals */ 5485c51f124SMoriah Waterland 5495c51f124SMoriah Waterland (void) sigrelse(SIGHUP); 5505c51f124SMoriah Waterland (void) sigrelse(SIGINT); 5515c51f124SMoriah Waterland 5525c51f124SMoriah Waterland pkginst = argv[optind++]; 5535c51f124SMoriah Waterland if (optind != argc) { 5545c51f124SMoriah Waterland usage(); 5555c51f124SMoriah Waterland } 5565c51f124SMoriah Waterland 5575c51f124SMoriah Waterland /* validate package software database (contents) file */ 5585c51f124SMoriah Waterland 5595c51f124SMoriah Waterland if (vcfile() == 0) { 5605c51f124SMoriah Waterland quit(99); 5615c51f124SMoriah Waterland } 5625c51f124SMoriah Waterland 5635c51f124SMoriah Waterland /* 5645c51f124SMoriah Waterland * Acquire the package lock - currently at "remove initialization" 5655c51f124SMoriah Waterland */ 5665c51f124SMoriah Waterland 5675c51f124SMoriah Waterland if (!lockinst(get_prog_name(), pkginst, "remove-initial")) { 5685c51f124SMoriah Waterland quit(99); 5695c51f124SMoriah Waterland } 5705c51f124SMoriah Waterland 5715c51f124SMoriah Waterland /* establish temporary directory to use */ 5725c51f124SMoriah Waterland 5735c51f124SMoriah Waterland tmpdir = getenv("TMPDIR"); 5745c51f124SMoriah Waterland if (tmpdir == NULL) { 5755c51f124SMoriah Waterland tmpdir = P_tmpdir; 5765c51f124SMoriah Waterland } 5775c51f124SMoriah Waterland 5785c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_TMPDIR, tmpdir); 5795c51f124SMoriah Waterland 5805c51f124SMoriah Waterland /* 5815c51f124SMoriah Waterland * Initialize installation admin parameters by reading 5825c51f124SMoriah Waterland * the adminfile. 5835c51f124SMoriah Waterland */ 5845c51f124SMoriah Waterland 5855c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_ADMINFILE, admnfile ? admnfile : ""); 5865c51f124SMoriah Waterland setadminFile(admnfile); 5875c51f124SMoriah Waterland 5885c51f124SMoriah Waterland /* 5895c51f124SMoriah Waterland * about to perform first operation that could be modified by the 5905c51f124SMoriah Waterland * preremove check option - if preremove check is selected (that is, 5915c51f124SMoriah Waterland * only gathering dependencies), then output a debug message to 5925c51f124SMoriah Waterland * indicate that the check is beginning. Also turn echo() output 5935c51f124SMoriah Waterland * off and set various other flags. 5945c51f124SMoriah Waterland */ 5955c51f124SMoriah Waterland 5965c51f124SMoriah Waterland if (preremoveCheck == B_TRUE) { 5975c51f124SMoriah Waterland (void) echoSetFlag(B_FALSE); 5985c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PRERMCHK, pkginst ? pkginst : "", 5995c51f124SMoriah Waterland zoneName ? zoneName : "global"); 6005c51f124SMoriah Waterland rcksetPreremoveCheck(B_TRUE); 6015c51f124SMoriah Waterland rcksetZoneName(zoneName); 6025c51f124SMoriah Waterland } 6035c51f124SMoriah Waterland 6045c51f124SMoriah Waterland (void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s", get_PKGLOC(), 6055c51f124SMoriah Waterland pkginst); 6065c51f124SMoriah Waterland (void) snprintf(pkgbin, sizeof (pkgbin), "%s/install", pkgloc); 6075c51f124SMoriah Waterland (void) snprintf(rlockfile, sizeof (rlockfile), "%s/!R-Lock!", pkgloc); 6085c51f124SMoriah Waterland 6095c51f124SMoriah Waterland if (chdir(pkgbin)) { 6105c51f124SMoriah Waterland progerr(ERR_CHDIR, pkgbin); 6115c51f124SMoriah Waterland quit(99); 6125c51f124SMoriah Waterland } 6135c51f124SMoriah Waterland 6145c51f124SMoriah Waterland echo(MSG_PREREMOVE_REMINST, pkginst); 6155c51f124SMoriah Waterland 6165c51f124SMoriah Waterland /* 6175c51f124SMoriah Waterland * if a lock file is present, then a previous attempt to remove this 6185c51f124SMoriah Waterland * package may have been unsuccessful. 6195c51f124SMoriah Waterland */ 6205c51f124SMoriah Waterland 6215c51f124SMoriah Waterland if (access(rlockfile, F_OK) == 0) { 6225c51f124SMoriah Waterland echo(ERR_UNSUCC); 6235c51f124SMoriah Waterland echoDebug(DBG_PKGINSTALL_HAS_LOCKFILE, pkginst, rlockfile, 6245c51f124SMoriah Waterland zoneName ? zoneName : "global"); 6255c51f124SMoriah Waterland } 6265c51f124SMoriah Waterland 6275c51f124SMoriah Waterland /* 6285c51f124SMoriah Waterland * Process all parameters from the pkginfo file 6295c51f124SMoriah Waterland * and place them in the execution environment 6305c51f124SMoriah Waterland */ 6315c51f124SMoriah Waterland 6325c51f124SMoriah Waterland /* Add DB retreival of the pkginfo parameters here */ 6335c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), "%s/pkginfo", pkgloc); 6345c51f124SMoriah Waterland if ((fp = fopen(path, "r")) == NULL) { 6355c51f124SMoriah Waterland progerr(ERR_PKGINFO, path); 6365c51f124SMoriah Waterland quit(99); 6375c51f124SMoriah Waterland } 6385c51f124SMoriah Waterland 6395c51f124SMoriah Waterland /* Mount up the client if necessary. */ 6405c51f124SMoriah Waterland if (map_client && !mount_client()) { 6415c51f124SMoriah Waterland logerr(MSG_MANMOUNT); 6425c51f124SMoriah Waterland } 6435c51f124SMoriah Waterland 6445c51f124SMoriah Waterland /* Get mount point of client */ 6455c51f124SMoriah Waterland client_mntdir = getenv("CLIENT_MNTDIR"); 6465c51f124SMoriah Waterland 6475c51f124SMoriah Waterland getuserlocale(); 6485c51f124SMoriah Waterland 6495c51f124SMoriah Waterland /* 6505c51f124SMoriah Waterland * current environment has been read; clear environment out 6515c51f124SMoriah Waterland * so putparam() can be used to populate the new environment 6525c51f124SMoriah Waterland * to be passed to any executables/scripts. 6535c51f124SMoriah Waterland */ 6545c51f124SMoriah Waterland 6555c51f124SMoriah Waterland environ = NULL; 6565c51f124SMoriah Waterland 6575c51f124SMoriah Waterland if (nonABI_symlinks()) { 6585c51f124SMoriah Waterland putparam("PKG_NONABI_SYMLINKS", "TRUE"); 6595c51f124SMoriah Waterland } 6605c51f124SMoriah Waterland 6615c51f124SMoriah Waterland /* 6625c51f124SMoriah Waterland * read the pkginfo file and fix any PKGSAV path - the correct 6635c51f124SMoriah Waterland * install_root will be prepended to the existing path. 6645c51f124SMoriah Waterland */ 6655c51f124SMoriah Waterland 6665c51f124SMoriah Waterland param[0] = '\0'; 6675c51f124SMoriah Waterland while (value = fpkgparam(fp, param)) { 6685c51f124SMoriah Waterland int validx = 0; 6695c51f124SMoriah Waterland char *newvalue; 6705c51f124SMoriah Waterland 6715c51f124SMoriah Waterland /* strip out any setting of PATH */ 6725c51f124SMoriah Waterland 6735c51f124SMoriah Waterland if (strcmp(param, "PATH") == 0) { 6745c51f124SMoriah Waterland free(value); 6755c51f124SMoriah Waterland param[0] = '\0'; 6765c51f124SMoriah Waterland continue; 6775c51f124SMoriah Waterland } 6785c51f124SMoriah Waterland 6795c51f124SMoriah Waterland /* if not PKGSAV then write out unchanged */ 6805c51f124SMoriah Waterland 6815c51f124SMoriah Waterland if (strcmp(param, "PKGSAV") != 0) { 6825c51f124SMoriah Waterland putparam(param, value); 6835c51f124SMoriah Waterland free(value); 6845c51f124SMoriah Waterland param[0] = '\0'; 6855c51f124SMoriah Waterland continue; 6865c51f124SMoriah Waterland } 6875c51f124SMoriah Waterland 6885c51f124SMoriah Waterland /* 6895c51f124SMoriah Waterland * PKGSAV parameter found - interpret the directory: 6905c51f124SMoriah Waterland * If in host:path format or marked with the leading "//", 6915c51f124SMoriah Waterland * then there is no client-relative translation - take it 6925c51f124SMoriah Waterland * literally later rather than use fixpath(). 6935c51f124SMoriah Waterland */ 6945c51f124SMoriah Waterland 6955c51f124SMoriah Waterland if (strstr(value, ":/")) { 6965c51f124SMoriah Waterland /* no modification needed */ 6975c51f124SMoriah Waterland validx = 0; 6985c51f124SMoriah Waterland } else if (strstr(value, "//") == value) { 6995c51f124SMoriah Waterland validx = 1; 7005c51f124SMoriah Waterland } else if (is_an_inst_root()) { 7015c51f124SMoriah Waterland /* This PKGSAV needs to be made client-relative. */ 7025c51f124SMoriah Waterland newvalue = fixpath(value); 7035c51f124SMoriah Waterland free(value); 7045c51f124SMoriah Waterland value = newvalue; 7055c51f124SMoriah Waterland } 7065c51f124SMoriah Waterland putparam(param, value+validx); 7075c51f124SMoriah Waterland free(value); 7085c51f124SMoriah Waterland param[0] = '\0'; 7095c51f124SMoriah Waterland } 7105c51f124SMoriah Waterland 7115c51f124SMoriah Waterland (void) fclose(fp); 7125c51f124SMoriah Waterland 7135c51f124SMoriah Waterland /* write parent condition information to environment */ 7145c51f124SMoriah Waterland 7155c51f124SMoriah Waterland putConditionInfo(parentZoneName, parentZoneType); 7165c51f124SMoriah Waterland 7175c51f124SMoriah Waterland putuserlocale(); 7185c51f124SMoriah Waterland 7195c51f124SMoriah Waterland /* 7205c51f124SMoriah Waterland * Now do all the various setups based on ABI compliance 7215c51f124SMoriah Waterland */ 7225c51f124SMoriah Waterland 7235c51f124SMoriah Waterland /* Read the environment provided by the pkginfo file */ 7245c51f124SMoriah Waterland abi_comp_ptr = getenv("NONABI_SCRIPTS"); 7255c51f124SMoriah Waterland 7265c51f124SMoriah Waterland /* if not ABI compliant set global flag */ 7275c51f124SMoriah Waterland abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS"); 7285c51f124SMoriah Waterland if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) { 7295c51f124SMoriah Waterland set_nonABI_symlinks(); 7305c51f124SMoriah Waterland } 7315c51f124SMoriah Waterland 7325c51f124SMoriah Waterland /* 7335c51f124SMoriah Waterland * If pkginfo says it's not compliant then set non_abi_scripts. 7345c51f124SMoriah Waterland * Oh, for two releases, set it from exception package names as 7355c51f124SMoriah Waterland * well. 7365c51f124SMoriah Waterland */ 7375c51f124SMoriah Waterland /* 7385c51f124SMoriah Waterland * ********************************************************************* 7395c51f124SMoriah Waterland * this feature is removed starting with Solaris 10 - there is no built 7405c51f124SMoriah Waterland * in list of packages that should be run "the old way" 7415c51f124SMoriah Waterland * ********************************************************************* 7425c51f124SMoriah Waterland */ 7435c51f124SMoriah Waterland 7445c51f124SMoriah Waterland #ifdef ALLOW_EXCEPTION_PKG_LIST 7455c51f124SMoriah Waterland if (exception_pkg(pkginst, SCRIPT) || 7465c51f124SMoriah Waterland (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0)) 7475c51f124SMoriah Waterland script_in = PROC_XSTDIN; 7485c51f124SMoriah Waterland #else 7495c51f124SMoriah Waterland if (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0) { 7505c51f124SMoriah Waterland script_in = PROC_XSTDIN; 7515c51f124SMoriah Waterland } 7525c51f124SMoriah Waterland #endif 7535c51f124SMoriah Waterland /* 7545c51f124SMoriah Waterland * ********************************************************************* 7555c51f124SMoriah Waterland * this feature is removed starting with Solaris 10 - there is no built 7565c51f124SMoriah Waterland * in list of packages that should be run "the old way" 7575c51f124SMoriah Waterland * ********************************************************************* 7585c51f124SMoriah Waterland */ 7595c51f124SMoriah Waterland 7605c51f124SMoriah Waterland #ifdef ALLOW_EXCEPTION_PKG_LIST 7615c51f124SMoriah Waterland /* Until 2.9, set it from the execption list */ 7625c51f124SMoriah Waterland if (exception_pkg(pkginst, LINK)) { 7635c51f124SMoriah Waterland set_nonABI_symlinks(); 7645c51f124SMoriah Waterland } 7655c51f124SMoriah Waterland #endif 7665c51f124SMoriah Waterland 7675c51f124SMoriah Waterland /* 7685c51f124SMoriah Waterland * Since this is a removal, we can tell whether it's absolute or 7695c51f124SMoriah Waterland * not from the resident pkginfo file read above. 7705c51f124SMoriah Waterland */ 7715c51f124SMoriah Waterland if ((err = set_basedirs((getenv("BASEDIR") != NULL), adm.basedir, 7725c51f124SMoriah Waterland pkginst, nointeract)) != 0) { 7735c51f124SMoriah Waterland quit(err); 7745c51f124SMoriah Waterland } 7755c51f124SMoriah Waterland 7765c51f124SMoriah Waterland /* 7775c51f124SMoriah Waterland * See if were are removing a package that only wants to update 7785c51f124SMoriah Waterland * the database or only remove files associated with CAS's. We 7795c51f124SMoriah Waterland * only check the PKG_HOLLOW_VARIABLE variable if told to do so by 7805c51f124SMoriah Waterland * the caller. 7815c51f124SMoriah Waterland */ 7825c51f124SMoriah Waterland 7835c51f124SMoriah Waterland if (is_depend_pkginfo_DB()) { 7845c51f124SMoriah Waterland pt = getenv(PKG_HOLLOW_VARIABLE); 7855c51f124SMoriah Waterland 7865c51f124SMoriah Waterland if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) { 7875c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED); 7885c51f124SMoriah Waterland 7895c51f124SMoriah Waterland /* 7905c51f124SMoriah Waterland * this is a hollow package and hollow package support 7915c51f124SMoriah Waterland * is enabled -- override admin settings to suppress 7925c51f124SMoriah Waterland * checks that do not make sense since no scripts will 7935c51f124SMoriah Waterland * be executed and no files will be removed. 7945c51f124SMoriah Waterland */ 7955c51f124SMoriah Waterland 7965c51f124SMoriah Waterland setadminSetting("conflict", "nocheck"); 7975c51f124SMoriah Waterland setadminSetting("setuid", "nocheck"); 7985c51f124SMoriah Waterland setadminSetting("action", "nocheck"); 7995c51f124SMoriah Waterland setadminSetting("partial", "nocheck"); 8005c51f124SMoriah Waterland setadminSetting("space", "nocheck"); 8015c51f124SMoriah Waterland setadminSetting("authentication", "nocheck"); 8025c51f124SMoriah Waterland } else { 8035c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED); 8045c51f124SMoriah Waterland set_depend_pkginfo_DB(B_FALSE); 8055c51f124SMoriah Waterland } 8065c51f124SMoriah Waterland } 8075c51f124SMoriah Waterland 8085c51f124SMoriah Waterland put_path_params(); 8095c51f124SMoriah Waterland 8105c51f124SMoriah Waterland /* If client mount point, add it to pkgremove environment */ 8115c51f124SMoriah Waterland 8125c51f124SMoriah Waterland if (client_mntdir != NULL) { 8135c51f124SMoriah Waterland putparam("CLIENT_MNTDIR", client_mntdir); 8145c51f124SMoriah Waterland } 8155c51f124SMoriah Waterland 8165c51f124SMoriah Waterland /* Establish the class list and the class attributes. */ 8175c51f124SMoriah Waterland 8185c51f124SMoriah Waterland if ((value = getenv("CLASSES")) != NULL) { 8195c51f124SMoriah Waterland cl_sets(qstrdup(value)); 8205c51f124SMoriah Waterland } else { 8215c51f124SMoriah Waterland progerr(ERR_CLASSES, path); 8225c51f124SMoriah Waterland quit(99); 8235c51f124SMoriah Waterland } 8245c51f124SMoriah Waterland 8255c51f124SMoriah Waterland /* establish path and tmpdir */ 8265c51f124SMoriah Waterland 8275c51f124SMoriah Waterland if (cmdbin[0] == '\0') { 8285c51f124SMoriah Waterland (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin)); 8295c51f124SMoriah Waterland } 8305c51f124SMoriah Waterland 8315c51f124SMoriah Waterland (void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin); 8325c51f124SMoriah Waterland putparam("PATH", path); 8335c51f124SMoriah Waterland 8345c51f124SMoriah Waterland putparam("TMPDIR", tmpdir); 8355c51f124SMoriah Waterland 8365c51f124SMoriah Waterland /* 8375c51f124SMoriah Waterland * Check ulimit requirement (provided in pkginfo). The purpose of 8385c51f124SMoriah Waterland * this limit is to terminate pathological file growth resulting from 8395c51f124SMoriah Waterland * file edits in scripts. It does not apply to files in the pkgmap 8405c51f124SMoriah Waterland * and it does not apply to any database files manipulated by the 8415c51f124SMoriah Waterland * installation service. 8425c51f124SMoriah Waterland */ 8435c51f124SMoriah Waterland if (value = getenv("ULIMIT")) { 8445c51f124SMoriah Waterland if (assign_ulimit(value) == -1) { 8455c51f124SMoriah Waterland progerr(ERR_BADULIMIT, value); 8465c51f124SMoriah Waterland warnflag++; 8475c51f124SMoriah Waterland } 8485c51f124SMoriah Waterland putparam("PKG_ULIMIT", "TRUE"); 8495c51f124SMoriah Waterland } 8505c51f124SMoriah Waterland 8515c51f124SMoriah Waterland /* 8525c51f124SMoriah Waterland * If only gathering dependencies, check and output status of all 8535c51f124SMoriah Waterland * remaining dependencies and exit. 8545c51f124SMoriah Waterland */ 8555c51f124SMoriah Waterland 8565c51f124SMoriah Waterland if (preremoveCheck == B_TRUE) { 8575c51f124SMoriah Waterland /* 8585c51f124SMoriah Waterland * make sure current runlevel is appropriate 8595c51f124SMoriah Waterland */ 8605c51f124SMoriah Waterland 8615c51f124SMoriah Waterland (void) fprintf(stdout, "rckrunlevel=%d\n", rckrunlevel()); 8625c51f124SMoriah Waterland 8635c51f124SMoriah Waterland /* 8645c51f124SMoriah Waterland * determine if any packaging scripts provided with 8655c51f124SMoriah Waterland * this package will execute as a priviledged user 8665c51f124SMoriah Waterland */ 8675c51f124SMoriah Waterland 8685c51f124SMoriah Waterland (void) fprintf(stdout, "rckpriv=%d\n", rckpriv()); 8695c51f124SMoriah Waterland 8705c51f124SMoriah Waterland /* 8715c51f124SMoriah Waterland * verify package dependencies 8725c51f124SMoriah Waterland */ 8735c51f124SMoriah Waterland 8745c51f124SMoriah Waterland (void) fprintf(stdout, "rckdepend=%d\n", rckdepend()); 8755c51f124SMoriah Waterland 8765c51f124SMoriah Waterland /* 8775c51f124SMoriah Waterland * ****** preremove check done - exit ****** 8785c51f124SMoriah Waterland */ 8795c51f124SMoriah Waterland 8805c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PRERMCHK_OK); 8815c51f124SMoriah Waterland quit(0); 8825c51f124SMoriah Waterland /*NOTREACHED*/ 8835c51f124SMoriah Waterland } 8845c51f124SMoriah Waterland 8855c51f124SMoriah Waterland /* 8865c51f124SMoriah Waterland * Not gathering dependencies only, proceed to check dependencies 8875c51f124SMoriah Waterland * and continue with the package removal operation. 8885c51f124SMoriah Waterland */ 8895c51f124SMoriah Waterland 8905c51f124SMoriah Waterland /* 8915c51f124SMoriah Waterland * make sure current runlevel is appropriate 8925c51f124SMoriah Waterland */ 8935c51f124SMoriah Waterland 8945c51f124SMoriah Waterland n = rckrunlevel(); 8955c51f124SMoriah Waterland 8965c51f124SMoriah Waterland if (n != 0) { 8975c51f124SMoriah Waterland quit(n); 8985c51f124SMoriah Waterland /* NOTREACHED */ 8995c51f124SMoriah Waterland } 9005c51f124SMoriah Waterland 9015c51f124SMoriah Waterland /* 9025c51f124SMoriah Waterland * determine if any packaging scripts provided with 9035c51f124SMoriah Waterland * this package will execute as a priviledged user 9045c51f124SMoriah Waterland */ 9055c51f124SMoriah Waterland 9065c51f124SMoriah Waterland n = rckpriv(); 9075c51f124SMoriah Waterland 9085c51f124SMoriah Waterland if (n != 0) { 9095c51f124SMoriah Waterland quit(n); 9105c51f124SMoriah Waterland /* NOTREACHED */ 9115c51f124SMoriah Waterland } 9125c51f124SMoriah Waterland 9135c51f124SMoriah Waterland /* 9145c51f124SMoriah Waterland * verify package dependencies 9155c51f124SMoriah Waterland */ 9165c51f124SMoriah Waterland n = rckdepend(); 9175c51f124SMoriah Waterland 9185c51f124SMoriah Waterland if (n != 0) { 9195c51f124SMoriah Waterland quit(n); 9205c51f124SMoriah Waterland /* NOTREACHED */ 9215c51f124SMoriah Waterland } 9225c51f124SMoriah Waterland 9235c51f124SMoriah Waterland /* 9245c51f124SMoriah Waterland * ********************************************************************* 9255c51f124SMoriah Waterland * the actual removal of the package begins here 9265c51f124SMoriah Waterland * ********************************************************************* 9275c51f124SMoriah Waterland */ 9285c51f124SMoriah Waterland 9295c51f124SMoriah Waterland /* 9305c51f124SMoriah Waterland * create lockfile to indicate start of removal 9315c51f124SMoriah Waterland */ 9325c51f124SMoriah Waterland started++; 9335c51f124SMoriah Waterland if ((fd = open(rlockfile, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) { 9345c51f124SMoriah Waterland progerr(ERR_LOCKFILE, rlockfile); 9355c51f124SMoriah Waterland quit(99); 9365c51f124SMoriah Waterland } else { 9375c51f124SMoriah Waterland (void) close(fd); 9385c51f124SMoriah Waterland } 9395c51f124SMoriah Waterland 9405c51f124SMoriah Waterland if (zoneName == (char *)NULL) { 9415c51f124SMoriah Waterland echo(MSG_PKGREMOVE_PROCPKG_GZ); 9425c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PROCPKG_GZ, pkginst, rlockfile); 9435c51f124SMoriah Waterland } else { 9445c51f124SMoriah Waterland echo(MSG_PKGREMOVE_PROCPKG_LZ, zoneName); 9455c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PROCPKG_LZ, pkginst, rlockfile, 9465c51f124SMoriah Waterland zoneName); 9475c51f124SMoriah Waterland } 94862224350SCasper H.S. Dik if (delmap(0, pkginst, &pkgserver, &tmpfp) != 0) { 9495c51f124SMoriah Waterland progerr(ERR_DB_QUERY, pkginst); 9505c51f124SMoriah Waterland quit(99); 9515c51f124SMoriah Waterland } 9525c51f124SMoriah Waterland 9535c51f124SMoriah Waterland /* 9545c51f124SMoriah Waterland * Run a preremove script if one is provided by the package. 9555c51f124SMoriah Waterland * Don't execute preremove script if only updating the DB. 9565c51f124SMoriah Waterland * Don't execute preremove script if files are not being deleted. 9575c51f124SMoriah Waterland */ 9585c51f124SMoriah Waterland 9595c51f124SMoriah Waterland /* update the lock - at the preremove script */ 9605c51f124SMoriah Waterland lockupd("preremove"); 9615c51f124SMoriah Waterland 9625c51f124SMoriah Waterland /* execute preremove script if one is provided */ 9635c51f124SMoriah Waterland (void) snprintf(script, sizeof (script), "%s/preremove", pkgbin); 9645c51f124SMoriah Waterland if (access(script, F_OK) != 0) { 9655c51f124SMoriah Waterland /* no script present */ 9665c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_POC_NONE, pkginst, 9675c51f124SMoriah Waterland zoneName ? zoneName : "global"); 9685c51f124SMoriah Waterland } else if (nodelete) { 9695c51f124SMoriah Waterland /* not deleting files: skip preremove script */ 9705c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_POC_NODEL, pkginst, script, 9715c51f124SMoriah Waterland zoneName ? zoneName : "global"); 9725c51f124SMoriah Waterland } else if (is_depend_pkginfo_DB()) { 9735c51f124SMoriah Waterland /* updating db only: skip preremove script */ 9745c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_POC_DBUPD, pkginst, script, 9755c51f124SMoriah Waterland zoneName ? zoneName : "global"); 9765c51f124SMoriah Waterland } else { 9775c51f124SMoriah Waterland /* script present and ok to run: run the script */ 9785c51f124SMoriah Waterland set_ulimit("preremove", ERR_PREREMOVE); 9795c51f124SMoriah Waterland if (zoneName == (char *)NULL) { 9805c51f124SMoriah Waterland echo(MSG_PKGREMOVE_EXEPOC_GZ); 9815c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_EXEPOC_GZ, pkginst, script); 9825c51f124SMoriah Waterland } else { 9835c51f124SMoriah Waterland echo(MSG_PKGREMOVE_EXEPOC_LZ, zoneName); 9845c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_EXEPOC_LZ, pkginst, script, 9855c51f124SMoriah Waterland zoneName); 9865c51f124SMoriah Waterland } 9875c51f124SMoriah Waterland putparam("PKG_PROC_SCRIPT", "preremove"); 9885c51f124SMoriah Waterland if (pkgverbose) { 9895c51f124SMoriah Waterland ckreturn(pkgexecl(script_in, PROC_STDOUT, 9905c51f124SMoriah Waterland PROC_USER, PROC_GRP, SHELL, "-x", 9915c51f124SMoriah Waterland script, NULL), ERR_PREREMOVE); 9925c51f124SMoriah Waterland } else { 9935c51f124SMoriah Waterland ckreturn(pkgexecl(script_in, PROC_STDOUT, 9945c51f124SMoriah Waterland PROC_USER, PROC_GRP, SHELL, script, 9955c51f124SMoriah Waterland NULL), ERR_PREREMOVE); 9965c51f124SMoriah Waterland } 9975c51f124SMoriah Waterland clr_ulimit(); 9985c51f124SMoriah Waterland } 9995c51f124SMoriah Waterland 10005c51f124SMoriah Waterland /* update the lock - doing removal */ 10015c51f124SMoriah Waterland 10025c51f124SMoriah Waterland lockupd("remove"); 10035c51f124SMoriah Waterland 10045c51f124SMoriah Waterland /* 10055c51f124SMoriah Waterland * Ensure that the contents file is updated even if the db has 10065c51f124SMoriah Waterland * been upgraded, in the case that there are relevant entries 10075c51f124SMoriah Waterland * in a special_contents file. The return value is ignored 10085c51f124SMoriah Waterland * since we do not want special_contents operation to prevent 10095c51f124SMoriah Waterland * pkgremove from succeeding. We do report errors to stderr. 10105c51f124SMoriah Waterland */ 10115c51f124SMoriah Waterland 10125c51f124SMoriah Waterland /* 10135c51f124SMoriah Waterland * Remove all components belonging to this package. 10145c51f124SMoriah Waterland * Don't remove components if only updating the DB. 10155c51f124SMoriah Waterland * Don't remove components if files are not being deleted. 10165c51f124SMoriah Waterland */ 10175c51f124SMoriah Waterland 10185c51f124SMoriah Waterland if (nodelete) { 10195c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_REM_NODEL, pkginst, 10205c51f124SMoriah Waterland zoneName ? zoneName : "global"); 10215c51f124SMoriah Waterland } else if (is_depend_pkginfo_DB()) { 10225c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_REM_DBUPD, pkginst, 10235c51f124SMoriah Waterland zoneName ? zoneName : "global"); 10245c51f124SMoriah Waterland } else { 10255c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_REM, pkginst, 10265c51f124SMoriah Waterland zoneName ? zoneName : "global"); 10275c51f124SMoriah Waterland /* 10285c51f124SMoriah Waterland * remove package one class at a time 10295c51f124SMoriah Waterland */ 10305c51f124SMoriah Waterland 10315c51f124SMoriah Waterland /* reverse order of classes */ 10325c51f124SMoriah Waterland for (i = cl_getn() - 1; i >= 0; i--) { 10335c51f124SMoriah Waterland rmclass(cl_nam(i), pkgrmremote, zoneName); 10345c51f124SMoriah Waterland } 10355c51f124SMoriah Waterland 10365c51f124SMoriah Waterland rmclass(NULL, pkgrmremote, zoneName); 10375c51f124SMoriah Waterland } 10385c51f124SMoriah Waterland 10395c51f124SMoriah Waterland z_destroyMountTable(); 10405c51f124SMoriah Waterland 10415c51f124SMoriah Waterland /* 10425c51f124SMoriah Waterland * Execute postremove script, if any 10435c51f124SMoriah Waterland * Don't execute postremove script if only updating the DB. 10445c51f124SMoriah Waterland * Don't execute postremove script if files are not being deleted. 10455c51f124SMoriah Waterland */ 10465c51f124SMoriah Waterland 10475c51f124SMoriah Waterland /* update the lock - at the postremove script */ 10485c51f124SMoriah Waterland lockupd("postremove"); 10495c51f124SMoriah Waterland 10505c51f124SMoriah Waterland /* execute postremove script if one is provided */ 10515c51f124SMoriah Waterland (void) snprintf(script, sizeof (script), "%s/postremove", pkgbin); 10525c51f124SMoriah Waterland if (access(script, F_OK) != 0) { 10535c51f124SMoriah Waterland /* no script present */ 10545c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PIC_NONE, pkginst, 10555c51f124SMoriah Waterland zoneName ? zoneName : "global"); 10565c51f124SMoriah Waterland } else if (nodelete) { 10575c51f124SMoriah Waterland /* not deleting files: skip postremove script */ 10585c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PIC_NODEL, pkginst, script, 10595c51f124SMoriah Waterland zoneName ? zoneName : "global"); 10605c51f124SMoriah Waterland } else if (is_depend_pkginfo_DB()) { 10615c51f124SMoriah Waterland /* updating db only: skip postremove script */ 10625c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_PIC_DBUPD, pkginst, script, 10635c51f124SMoriah Waterland zoneName ? zoneName : "global"); 10645c51f124SMoriah Waterland } else { 10655c51f124SMoriah Waterland /* script present and ok to run: run the script */ 10665c51f124SMoriah Waterland set_ulimit("postremove", ERR_POSTREMOVE); 10675c51f124SMoriah Waterland if (zoneName == (char *)NULL) { 10685c51f124SMoriah Waterland echo(MSG_PKGREMOVE_EXEPIC_GZ); 10695c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_EXEPIC_GZ, pkginst, script); 10705c51f124SMoriah Waterland } else { 10715c51f124SMoriah Waterland echo(MSG_PKGREMOVE_EXEPIC_LZ, zoneName); 10725c51f124SMoriah Waterland echoDebug(DBG_PKGREMOVE_EXEPIC_LZ, pkginst, script, 10735c51f124SMoriah Waterland zoneName); 10745c51f124SMoriah Waterland } 10755c51f124SMoriah Waterland putparam("PKG_PROC_SCRIPT", "postremove"); 10765c51f124SMoriah Waterland putparam("TMPDIR", tmpdir); 10775c51f124SMoriah Waterland if (pkgverbose) { 10785c51f124SMoriah Waterland ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER, 10795c51f124SMoriah Waterland PROC_GRP, SHELL, "-x", script, NULL), 10805c51f124SMoriah Waterland ERR_POSTREMOVE); 10815c51f124SMoriah Waterland } else { 10825c51f124SMoriah Waterland ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER, 10835c51f124SMoriah Waterland PROC_GRP, SHELL, script, NULL), 10845c51f124SMoriah Waterland ERR_POSTREMOVE); 10855c51f124SMoriah Waterland } 10865c51f124SMoriah Waterland clr_ulimit(); 10875c51f124SMoriah Waterland } 10885c51f124SMoriah Waterland 10895c51f124SMoriah Waterland if (zoneName == (char *)NULL) { 10905c51f124SMoriah Waterland echo(MSG_PKGREMOVE_UPDINF_GZ); 10915c51f124SMoriah Waterland } else { 10925c51f124SMoriah Waterland echo(MSG_PKGREMOVE_UPDINF_LZ, zoneName); 10935c51f124SMoriah Waterland } 10945c51f124SMoriah Waterland 109562224350SCasper H.S. Dik if (delmap(1, pkginst, &pkgserver, &tmpfp) != 0) { 10965c51f124SMoriah Waterland progerr(ERR_DB_QUERY, pkginst); 10975c51f124SMoriah Waterland quit(99); 10985c51f124SMoriah Waterland } 10995c51f124SMoriah Waterland 11005c51f124SMoriah Waterland if (!warnflag && !failflag) { 11015c51f124SMoriah Waterland if (pt = getenv("PREDEPEND")) 11025c51f124SMoriah Waterland predepend(pt); 11035c51f124SMoriah Waterland (void) chdir("/"); 11045c51f124SMoriah Waterland if (rrmdir(pkgloc)) 11055c51f124SMoriah Waterland warnflag++; 11065c51f124SMoriah Waterland } 11075c51f124SMoriah Waterland 11085c51f124SMoriah Waterland if ((z_running_in_global_zone() == B_TRUE) && 11095c51f124SMoriah Waterland (pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE)) { 11105c51f124SMoriah Waterland boolean_t b; 11115c51f124SMoriah Waterland 11125c51f124SMoriah Waterland b = pkgRemovePackageFromGzonlyList(get_inst_root(), pkginst); 11135c51f124SMoriah Waterland if (b == B_FALSE) { 11145c51f124SMoriah Waterland progerr(ERR_PKGREMOVE_GZONLY_REMOVE, pkginst); 11155c51f124SMoriah Waterland ckreturn(1, NULL); 11165c51f124SMoriah Waterland } 11175c51f124SMoriah Waterland } 11185c51f124SMoriah Waterland 11195c51f124SMoriah Waterland /* release the generic package lock */ 11205c51f124SMoriah Waterland 11215c51f124SMoriah Waterland (void) unlockinst(); 11225c51f124SMoriah Waterland 112362224350SCasper H.S. Dik pkgcloseserver(pkgserver); 112462224350SCasper H.S. Dik 11255c51f124SMoriah Waterland quit(0); 11265c51f124SMoriah Waterland /* LINTED: no return */ 11275c51f124SMoriah Waterland } 11285c51f124SMoriah Waterland 11295c51f124SMoriah Waterland int 11305c51f124SMoriah Waterland issymlink(char *path) 11315c51f124SMoriah Waterland { 11325c51f124SMoriah Waterland struct stat statbuf; 11335c51f124SMoriah Waterland 11345c51f124SMoriah Waterland /* 11355c51f124SMoriah Waterland * Obtain status of path; if symbolic link get link's status 11365c51f124SMoriah Waterland */ 11375c51f124SMoriah Waterland 11385c51f124SMoriah Waterland if (lstat(path, &statbuf) != 0) { 11395c51f124SMoriah Waterland return (1); /* not symlink */ 11405c51f124SMoriah Waterland } 11415c51f124SMoriah Waterland 11425c51f124SMoriah Waterland /* 11435c51f124SMoriah Waterland * Status obtained - if symbolic link, return 0 11445c51f124SMoriah Waterland */ 11455c51f124SMoriah Waterland 11465c51f124SMoriah Waterland if ((statbuf.st_mode & S_IFMT) == S_IFLNK) { 11475c51f124SMoriah Waterland return (0); /* is a symlink */ 11485c51f124SMoriah Waterland } 11495c51f124SMoriah Waterland 11505c51f124SMoriah Waterland /* 11515c51f124SMoriah Waterland * Not a symbolic link - return 1 11525c51f124SMoriah Waterland */ 11535c51f124SMoriah Waterland 11545c51f124SMoriah Waterland return (1); /* not symlink */ 11555c51f124SMoriah Waterland } 11565c51f124SMoriah Waterland 11575c51f124SMoriah Waterland static void 11585c51f124SMoriah Waterland rmclass(char *aclass, int rm_remote, char *a_zoneName) 11595c51f124SMoriah Waterland { 11605c51f124SMoriah Waterland struct cfent *ept; 11615c51f124SMoriah Waterland FILE *fp; 11625c51f124SMoriah Waterland char tmpfile[PATH_MAX]; 11635c51f124SMoriah Waterland char script[PATH_MAX]; 11645c51f124SMoriah Waterland int i; 11655c51f124SMoriah Waterland char *tmp_path; 11665c51f124SMoriah Waterland char *save_path = NULL; 11675c51f124SMoriah Waterland struct stat st; 11685c51f124SMoriah Waterland 11695c51f124SMoriah Waterland if (aclass == NULL) { 11705c51f124SMoriah Waterland for (i = 0; i < eptnum; i++) { 11715c51f124SMoriah Waterland if (eptlist[i] != NULL) { 11725c51f124SMoriah Waterland rmclass(eptlist[i]->pkg_class, 11735c51f124SMoriah Waterland rm_remote, a_zoneName); 11745c51f124SMoriah Waterland } 11755c51f124SMoriah Waterland } 11765c51f124SMoriah Waterland return; 11775c51f124SMoriah Waterland } 11785c51f124SMoriah Waterland 11795c51f124SMoriah Waterland /* locate class action script to execute */ 11805c51f124SMoriah Waterland (void) snprintf(script, sizeof (script), "%s/r.%s", pkgbin, aclass); 11815c51f124SMoriah Waterland if (access(script, F_OK) != 0) { 11825c51f124SMoriah Waterland (void) snprintf(script, sizeof (script), "%s/r.%s", 11835c51f124SMoriah Waterland PKGSCR, aclass); 11845c51f124SMoriah Waterland if (access(script, F_OK) != 0) 11855c51f124SMoriah Waterland script[0] = '\0'; 11865c51f124SMoriah Waterland } 11875c51f124SMoriah Waterland if (script[0] != '\0') { 11885c51f124SMoriah Waterland int td; 11895c51f124SMoriah Waterland 11905c51f124SMoriah Waterland (void) snprintf(tmpfile, sizeof (tmpfile), "%s/RMLISTXXXXXX", 11915c51f124SMoriah Waterland tmpdir); 11925c51f124SMoriah Waterland td = mkstemp(tmpfile); 11935c51f124SMoriah Waterland if (td == -1) { 11945c51f124SMoriah Waterland progerr(ERR_TMPFILE); 11955c51f124SMoriah Waterland quit(99); 11965c51f124SMoriah Waterland } 11975c51f124SMoriah Waterland if ((fp = fdopen(td, "w")) == NULL) { 11985c51f124SMoriah Waterland progerr(ERR_WTMPFILE, tmpfile); 11995c51f124SMoriah Waterland quit(99); 12005c51f124SMoriah Waterland } 12015c51f124SMoriah Waterland } 12025c51f124SMoriah Waterland 12035c51f124SMoriah Waterland if (a_zoneName == (char *)NULL) { 12045c51f124SMoriah Waterland echo(MSG_PKGREMOVE_REMPATHCLASS_GZ, aclass); 12055c51f124SMoriah Waterland } else { 12065c51f124SMoriah Waterland echo(MSG_PKGREMOVE_REMPATHCLASS_LZ, aclass, a_zoneName); 12075c51f124SMoriah Waterland } 12085c51f124SMoriah Waterland 12095c51f124SMoriah Waterland /* process paths in reverse order */ 12105c51f124SMoriah Waterland i = eptnum; 12115c51f124SMoriah Waterland while (--i >= 0) { 12125c51f124SMoriah Waterland ept = eptlist[i]; 12135c51f124SMoriah Waterland 12145c51f124SMoriah Waterland if ((ept == NULL) || strcmp(aclass, ept->pkg_class)) { 12155c51f124SMoriah Waterland continue; 12165c51f124SMoriah Waterland } 12175c51f124SMoriah Waterland 12185c51f124SMoriah Waterland /* save the path, and prepend the ir */ 12195c51f124SMoriah Waterland if (is_an_inst_root()) { 12205c51f124SMoriah Waterland save_path = ept->path; 12215c51f124SMoriah Waterland tmp_path = fixpath(ept->path); 12225c51f124SMoriah Waterland ept->path = tmp_path; 12235c51f124SMoriah Waterland } 12245c51f124SMoriah Waterland 12255c51f124SMoriah Waterland if (!ept->ftype || (ept->ftype == '^' && !script[0])) { 12265c51f124SMoriah Waterland /* 12275c51f124SMoriah Waterland * A path owned by more than one package is marked with 12285c51f124SMoriah Waterland * a NULL ftype (seems odd, but that's how it's 12295c51f124SMoriah Waterland * done). Such files are sacro sanct. Shared editable 12305c51f124SMoriah Waterland * files are a special case, and are marked with an 12315c51f124SMoriah Waterland * ftype of '^'. These files should only be ignored if 12325c51f124SMoriah Waterland * no class action script is present. It is the CAS's 12335c51f124SMoriah Waterland * responsibility to not remove the editable object. 12345c51f124SMoriah Waterland */ 12355c51f124SMoriah Waterland echo(MSG_SHARED, ept->path); 12365c51f124SMoriah Waterland } else if (ept->pinfo->status == SERVED_FILE && !rm_remote) { 12375c51f124SMoriah Waterland /* 12385c51f124SMoriah Waterland * If the path is provided to the client from a 12395c51f124SMoriah Waterland * server, don't remove anything unless explicitly 12405c51f124SMoriah Waterland * requested through the "-f" option. 12415c51f124SMoriah Waterland */ 12425c51f124SMoriah Waterland echo(MSG_SERVER, ept->path); 12435c51f124SMoriah Waterland } else if (script[0]) { 12445c51f124SMoriah Waterland /* 12455c51f124SMoriah Waterland * If there's a class action script, just put the 12465c51f124SMoriah Waterland * path name into the list. 12475c51f124SMoriah Waterland */ 12485c51f124SMoriah Waterland (void) fprintf(fp, "%s\n", ept->path); 12495c51f124SMoriah Waterland } else if (strchr("dx", ept->ftype) != NULL || 12505c51f124SMoriah Waterland (lstat(ept->path, &st) == 0 && S_ISDIR(st.st_mode))) { 12515c51f124SMoriah Waterland /* Directories are rmdir()'d. */ 12525c51f124SMoriah Waterland 12535c51f124SMoriah Waterland if (rmdir(ept->path)) { 12545c51f124SMoriah Waterland if (errno == EBUSY) { 12555c51f124SMoriah Waterland echo(MSG_DIRBUSY, ept->path); 12565c51f124SMoriah Waterland } else if (errno == EEXIST) { 12575c51f124SMoriah Waterland echo(MSG_NOTEMPTY, ept->path); 12585c51f124SMoriah Waterland } else if (errno != ENOENT) { 12595c51f124SMoriah Waterland progerr(ERR_RMDIR, ept->path); 12605c51f124SMoriah Waterland warnflag++; 12615c51f124SMoriah Waterland } 12625c51f124SMoriah Waterland } else { 12635c51f124SMoriah Waterland if (ept->pinfo->status == SERVED_FILE) { 12645c51f124SMoriah Waterland echo(MSG_RMSRVR, ept->path); 12655c51f124SMoriah Waterland } else { 12665c51f124SMoriah Waterland echo("%s", ept->path); 12675c51f124SMoriah Waterland } 12685c51f124SMoriah Waterland } 12695c51f124SMoriah Waterland 12705c51f124SMoriah Waterland } else { 12715c51f124SMoriah Waterland /* 12725c51f124SMoriah Waterland * Before removing this object one more 12735c51f124SMoriah Waterland * check should be done to assure that a 12745c51f124SMoriah Waterland * shared object is not removed. 12755c51f124SMoriah Waterland * This can happen if the original object 12765c51f124SMoriah Waterland * was incorrectly updated with the 12775c51f124SMoriah Waterland * incorrect class identifier. 12785c51f124SMoriah Waterland * This handles pathologcal cases that 12795c51f124SMoriah Waterland * weren't handled above. 12805c51f124SMoriah Waterland */ 12815c51f124SMoriah Waterland if (ept->npkgs > 1) { 12825c51f124SMoriah Waterland echo(MSG_SHARED, ept->path); 12835c51f124SMoriah Waterland continue; 12845c51f124SMoriah Waterland } 12855c51f124SMoriah Waterland 12865c51f124SMoriah Waterland /* Regular files are unlink()'d. */ 12875c51f124SMoriah Waterland 12885c51f124SMoriah Waterland if (unlink(ept->path)) { 12895c51f124SMoriah Waterland if (errno != ENOENT) { 12905c51f124SMoriah Waterland progerr(ERR_RMPATH, ept->path); 12915c51f124SMoriah Waterland warnflag++; 12925c51f124SMoriah Waterland } 12935c51f124SMoriah Waterland } else { 12945c51f124SMoriah Waterland if (ept->pinfo->status == SERVED_FILE) { 12955c51f124SMoriah Waterland echo(MSG_RMSRVR, ept->path); 12965c51f124SMoriah Waterland } else { 12975c51f124SMoriah Waterland echo("%s", ept->path); 12985c51f124SMoriah Waterland } 12995c51f124SMoriah Waterland } 13005c51f124SMoriah Waterland } 13015c51f124SMoriah Waterland 13025c51f124SMoriah Waterland /* restore the original path */ 13035c51f124SMoriah Waterland 13045c51f124SMoriah Waterland if (is_an_inst_root()) { 13055c51f124SMoriah Waterland ept->path = save_path; 13065c51f124SMoriah Waterland } 13075c51f124SMoriah Waterland 13085c51f124SMoriah Waterland /* 13095c51f124SMoriah Waterland * free memory allocated for this entry memory used for 13105c51f124SMoriah Waterland * pathnames will be freed later by a call to pathdup() 13115c51f124SMoriah Waterland */ 13125c51f124SMoriah Waterland 13135c51f124SMoriah Waterland if (eptlist[i]) { 13145c51f124SMoriah Waterland free(eptlist[i]); 13155c51f124SMoriah Waterland } 13165c51f124SMoriah Waterland eptlist[i] = NULL; 13175c51f124SMoriah Waterland } 13185c51f124SMoriah Waterland if (script[0]) { 13195c51f124SMoriah Waterland (void) fclose(fp); 13205c51f124SMoriah Waterland set_ulimit(script, ERR_CASFAIL); 13215c51f124SMoriah Waterland if (pkgverbose) 13225c51f124SMoriah Waterland ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER, 13235c51f124SMoriah Waterland CAS_GRP, SHELL, "-x", script, NULL), 13245c51f124SMoriah Waterland ERR_CASFAIL); 13255c51f124SMoriah Waterland else 13265c51f124SMoriah Waterland ckreturn(pkgexecl(tmpfile, CAS_STDOUT, CAS_USER, 13275c51f124SMoriah Waterland CAS_GRP, SHELL, script, NULL), 13285c51f124SMoriah Waterland ERR_CASFAIL); 13295c51f124SMoriah Waterland clr_ulimit(); 13305c51f124SMoriah Waterland if (isfile(NULL, tmpfile) == 0) { 13315c51f124SMoriah Waterland if (unlink(tmpfile) == -1) 13325c51f124SMoriah Waterland progerr(ERR_RMPATH, tmpfile); 13335c51f124SMoriah Waterland } 13345c51f124SMoriah Waterland } 13355c51f124SMoriah Waterland } 13365c51f124SMoriah Waterland 13375c51f124SMoriah Waterland static void 13385c51f124SMoriah Waterland ckreturn(int retcode, char *msg) 13395c51f124SMoriah Waterland { 13405c51f124SMoriah Waterland switch (retcode) { 13415c51f124SMoriah Waterland case 2: 13425c51f124SMoriah Waterland case 12: 13435c51f124SMoriah Waterland case 22: 13445c51f124SMoriah Waterland warnflag++; 13455c51f124SMoriah Waterland /*FALLTHRU*/ 13465c51f124SMoriah Waterland if (msg) 13475c51f124SMoriah Waterland progerr(msg); 13485c51f124SMoriah Waterland case 10: 13495c51f124SMoriah Waterland case 20: 13505c51f124SMoriah Waterland if (retcode >= 10) 13515c51f124SMoriah Waterland dreboot++; 13525c51f124SMoriah Waterland if (retcode >= 20) 13535c51f124SMoriah Waterland ireboot++; 13545c51f124SMoriah Waterland /*FALLTHRU*/ 13555c51f124SMoriah Waterland case 0: 13565c51f124SMoriah Waterland break; /* okay */ 13575c51f124SMoriah Waterland 13585c51f124SMoriah Waterland case -1: 13595c51f124SMoriah Waterland retcode = 99; 13605c51f124SMoriah Waterland /*FALLTHRU*/ 13615c51f124SMoriah Waterland case 99: 13625c51f124SMoriah Waterland case 1: 13635c51f124SMoriah Waterland case 11: 13645c51f124SMoriah Waterland case 21: 13655c51f124SMoriah Waterland case 4: 13665c51f124SMoriah Waterland case 14: 13675c51f124SMoriah Waterland case 24: 13685c51f124SMoriah Waterland case 5: 13695c51f124SMoriah Waterland case 15: 13705c51f124SMoriah Waterland case 25: 13715c51f124SMoriah Waterland if (msg) 13725c51f124SMoriah Waterland progerr(msg); 13735c51f124SMoriah Waterland /*FALLTHRU*/ 13745c51f124SMoriah Waterland case 3: 13755c51f124SMoriah Waterland case 13: 13765c51f124SMoriah Waterland case 23: 13775c51f124SMoriah Waterland quit(retcode); 13785c51f124SMoriah Waterland /* NOT REACHED */ 13795c51f124SMoriah Waterland default: 13805c51f124SMoriah Waterland if (msg) 13815c51f124SMoriah Waterland progerr(msg); 13825c51f124SMoriah Waterland quit(1); 13835c51f124SMoriah Waterland } 13845c51f124SMoriah Waterland } 13855c51f124SMoriah Waterland 13865c51f124SMoriah Waterland static void 13875c51f124SMoriah Waterland usage(void) 13885c51f124SMoriah Waterland { 13895c51f124SMoriah Waterland (void) fprintf(stderr, ERR_USAGE_PKGREMOVE); 13905c51f124SMoriah Waterland 13915c51f124SMoriah Waterland exit(1); 13925c51f124SMoriah Waterland } 13935c51f124SMoriah Waterland 13945c51f124SMoriah Waterland /* 13955c51f124SMoriah Waterland * Name: path_valid 13965c51f124SMoriah Waterland * Description: Checks a string for being a valid path 13975c51f124SMoriah Waterland * 13985c51f124SMoriah Waterland * Arguments: path - path to validate 13995c51f124SMoriah Waterland * 14005c51f124SMoriah Waterland * Returns : B_TRUE - success, B_FALSE otherwise. 14015c51f124SMoriah Waterland * B_FALSE means path was null, too long (>PATH_MAX), 14025c51f124SMoriah Waterland * or too short (<1) 14035c51f124SMoriah Waterland */ 14045c51f124SMoriah Waterland static boolean_t 14055c51f124SMoriah Waterland path_valid(char *path) 14065c51f124SMoriah Waterland { 14075c51f124SMoriah Waterland if (path == NULL) { 14085c51f124SMoriah Waterland return (B_FALSE); 14095c51f124SMoriah Waterland } else if (strlen(path) > PATH_MAX) { 14105c51f124SMoriah Waterland return (B_FALSE); 14115c51f124SMoriah Waterland } else if (strlen(path) >= 1) { 14125c51f124SMoriah Waterland return (B_TRUE); 14135c51f124SMoriah Waterland } else { 14145c51f124SMoriah Waterland /* path < 1 */ 14155c51f124SMoriah Waterland return (B_FALSE); 14165c51f124SMoriah Waterland } 14175c51f124SMoriah Waterland } 1418