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 2005 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 <string.h> 33*5c51f124SMoriah Waterland #include <signal.h> 34*5c51f124SMoriah Waterland #include <sys/utsname.h> 35*5c51f124SMoriah Waterland #include <limits.h> 36*5c51f124SMoriah Waterland #include <stdlib.h> 37*5c51f124SMoriah Waterland #include <unistd.h> 38*5c51f124SMoriah Waterland #include <pkgdev.h> 39*5c51f124SMoriah Waterland #include <pkglocs.h> 40*5c51f124SMoriah Waterland #include <locale.h> 41*5c51f124SMoriah Waterland #include <libintl.h> 42*5c51f124SMoriah Waterland #include <errno.h> 43*5c51f124SMoriah Waterland #include <pkglib.h> 44*5c51f124SMoriah Waterland #include "install.h" 45*5c51f124SMoriah Waterland #include "dryrun.h" 46*5c51f124SMoriah Waterland #include "libadm.h" 47*5c51f124SMoriah Waterland #include "libinst.h" 48*5c51f124SMoriah Waterland #include "pkginstall.h" 49*5c51f124SMoriah Waterland #include "messages.h" 50*5c51f124SMoriah Waterland 51*5c51f124SMoriah Waterland /* main.c */ 52*5c51f124SMoriah Waterland extern char *pkgdrtarg; 53*5c51f124SMoriah Waterland extern struct cfextra **extlist; 54*5c51f124SMoriah Waterland 55*5c51f124SMoriah Waterland extern struct admin adm; 56*5c51f124SMoriah Waterland extern struct pkgdev pkgdev; /* holds info about the installation device */ 57*5c51f124SMoriah Waterland 58*5c51f124SMoriah Waterland extern int dparts; 59*5c51f124SMoriah Waterland extern int dreboot; /* != 0 if reboot required after installation */ 60*5c51f124SMoriah Waterland extern int failflag; /* != 0 if fatal error has occurred (1) */ 61*5c51f124SMoriah Waterland extern int ireboot; /* != 0 if immediate reboot required */ 62*5c51f124SMoriah Waterland extern int warnflag; /* != 0 if non-fatal error has occurred (2) */ 63*5c51f124SMoriah Waterland 64*5c51f124SMoriah Waterland extern char tmpdir[]; 65*5c51f124SMoriah Waterland extern char pkgloc[]; 66*5c51f124SMoriah Waterland extern char pkgloc_sav[]; 67*5c51f124SMoriah Waterland extern char *msgtext; 68*5c51f124SMoriah Waterland extern char *pkginst; 69*5c51f124SMoriah Waterland extern char *pkgname; 70*5c51f124SMoriah Waterland 71*5c51f124SMoriah Waterland /* 72*5c51f124SMoriah Waterland * exported functions 73*5c51f124SMoriah Waterland */ 74*5c51f124SMoriah Waterland 75*5c51f124SMoriah Waterland void quit(int retcode); 76*5c51f124SMoriah Waterland void quitSetZoneName(char *a_zoneName); 77*5c51f124SMoriah Waterland sighdlrFunc_t *quitGetTrapHandler(void); 78*5c51f124SMoriah Waterland 79*5c51f124SMoriah Waterland /* 80*5c51f124SMoriah Waterland * forward declarations 81*5c51f124SMoriah Waterland */ 82*5c51f124SMoriah Waterland 83*5c51f124SMoriah Waterland static void trap(int signo); 84*5c51f124SMoriah Waterland static void mailmsg(int retcode); 85*5c51f124SMoriah Waterland static void quitmsg(int retcode); 86*5c51f124SMoriah Waterland 87*5c51f124SMoriah Waterland static boolean_t silentExit = B_FALSE; 88*5c51f124SMoriah Waterland static boolean_t pkgaskFlag = B_FALSE; 89*5c51f124SMoriah Waterland static boolean_t installStarted = B_FALSE; 90*5c51f124SMoriah Waterland static boolean_t updatingExistingPackage = B_FALSE; 91*5c51f124SMoriah Waterland 92*5c51f124SMoriah Waterland static char *dstreamTempDir = (char *)NULL; 93*5c51f124SMoriah Waterland static char *zoneName = (char *)NULL; 94*5c51f124SMoriah Waterland static int includeZonename = 0; 95*5c51f124SMoriah Waterland static int trapEntered = 0; 96*5c51f124SMoriah Waterland 97*5c51f124SMoriah Waterland /* 98*5c51f124SMoriah Waterland * ***************************************************************************** 99*5c51f124SMoriah Waterland * global external (public) functions 100*5c51f124SMoriah Waterland * ***************************************************************************** 101*5c51f124SMoriah Waterland */ 102*5c51f124SMoriah Waterland 103*5c51f124SMoriah Waterland /* 104*5c51f124SMoriah Waterland * Name: quitGetTrapHandler 105*5c51f124SMoriah Waterland * Description: return address of this modules "signal trap" handler 106*5c51f124SMoriah Waterland * Arguments: void 107*5c51f124SMoriah Waterland * Returns: sighdlrFunc_t 108*5c51f124SMoriah Waterland * The address of the trap handler that can be passed to 109*5c51f124SMoriah Waterland * the signal() type system calls 110*5c51f124SMoriah Waterland */ 111*5c51f124SMoriah Waterland 112*5c51f124SMoriah Waterland sighdlrFunc_t * 113*5c51f124SMoriah Waterland quitGetTrapHandler(void) 114*5c51f124SMoriah Waterland { 115*5c51f124SMoriah Waterland return (&trap); 116*5c51f124SMoriah Waterland } 117*5c51f124SMoriah Waterland 118*5c51f124SMoriah Waterland /* 119*5c51f124SMoriah Waterland * Name: quitSetZoneName 120*5c51f124SMoriah Waterland * Description: set the zone name the program is running in 121*5c51f124SMoriah Waterland * Arguments: a_zoneName - pointer to string representing the name of the zone 122*5c51f124SMoriah Waterland * that the program is running in 123*5c51f124SMoriah Waterland * Returns: void 124*5c51f124SMoriah Waterland */ 125*5c51f124SMoriah Waterland 126*5c51f124SMoriah Waterland void 127*5c51f124SMoriah Waterland quitSetZoneName(char *a_zoneName) 128*5c51f124SMoriah Waterland { 129*5c51f124SMoriah Waterland zoneName = a_zoneName; 130*5c51f124SMoriah Waterland if ((zoneName == (char *)NULL || *zoneName == '\0')) { 131*5c51f124SMoriah Waterland includeZonename = 0; 132*5c51f124SMoriah Waterland } else { 133*5c51f124SMoriah Waterland includeZonename = 1; 134*5c51f124SMoriah Waterland } 135*5c51f124SMoriah Waterland } 136*5c51f124SMoriah Waterland 137*5c51f124SMoriah Waterland /* 138*5c51f124SMoriah Waterland * Name: quitSetDstreamTmpdir 139*5c51f124SMoriah Waterland * Description: set the name of a temporary directory that contains package 140*5c51f124SMoriah Waterland * streams to be removed when quit() is called 141*5c51f124SMoriah Waterland * Arguments: a_dstreamTempDir - pointer to string representing the path 142*5c51f124SMoriah Waterland * to the temporary directory to remove when quit() 143*5c51f124SMoriah Waterland * is called 144*5c51f124SMoriah Waterland * Returns: void 145*5c51f124SMoriah Waterland */ 146*5c51f124SMoriah Waterland 147*5c51f124SMoriah Waterland void 148*5c51f124SMoriah Waterland quitSetDstreamTmpdir(char *a_dstreamTempDir) 149*5c51f124SMoriah Waterland { 150*5c51f124SMoriah Waterland dstreamTempDir = a_dstreamTempDir; 151*5c51f124SMoriah Waterland } 152*5c51f124SMoriah Waterland 153*5c51f124SMoriah Waterland /* 154*5c51f124SMoriah Waterland * Name: quitSetUpdatingExisting 155*5c51f124SMoriah Waterland * Description: set the "updating existing" flag - used in conjunction 156*5c51f124SMoriah Waterland * with the "install started" flag to determine the type 157*5c51f124SMoriah Waterland * of cleanup to be done when quit() is called 158*5c51f124SMoriah Waterland * Arguments: a_updatingExistingPackage - indicates whether or not existing 159*5c51f124SMoriah Waterland * packages are being updated (B_TRUE) or new packages 160*5c51f124SMoriah Waterland * are being installed (B_FALSE) 161*5c51f124SMoriah Waterland * Returns: void 162*5c51f124SMoriah Waterland */ 163*5c51f124SMoriah Waterland 164*5c51f124SMoriah Waterland void 165*5c51f124SMoriah Waterland quitSetUpdatingExisting(boolean_t a_updatingExistingPackage) 166*5c51f124SMoriah Waterland { 167*5c51f124SMoriah Waterland updatingExistingPackage = a_updatingExistingPackage; 168*5c51f124SMoriah Waterland } 169*5c51f124SMoriah Waterland 170*5c51f124SMoriah Waterland /* 171*5c51f124SMoriah Waterland * Name: quitSetInstallStarted 172*5c51f124SMoriah Waterland * Description: set the "install started" flag - used in conjunction 173*5c51f124SMoriah Waterland * with the "updating existing" flag to determine the type 174*5c51f124SMoriah Waterland * of cleanup to be done when quit() is called, and the 175*5c51f124SMoriah Waterland * type of message to be output for the "reason" why quit() 176*5c51f124SMoriah Waterland * was called 177*5c51f124SMoriah Waterland * Arguments: a_installStarted - indicates whether or not installation 178*5c51f124SMoriah Waterland * has started 179*5c51f124SMoriah Waterland * Returns: void 180*5c51f124SMoriah Waterland */ 181*5c51f124SMoriah Waterland 182*5c51f124SMoriah Waterland void 183*5c51f124SMoriah Waterland quitSetInstallStarted(boolean_t a_installStarted) 184*5c51f124SMoriah Waterland { 185*5c51f124SMoriah Waterland installStarted = a_installStarted; 186*5c51f124SMoriah Waterland } 187*5c51f124SMoriah Waterland 188*5c51f124SMoriah Waterland /* 189*5c51f124SMoriah Waterland * Name: quitSetPkgask 190*5c51f124SMoriah Waterland * Description: set the "pkgask is being run" flag - used to determine 191*5c51f124SMoriah Waterland * the type of message to be output for the "reason" why 192*5c51f124SMoriah Waterland * quit() was called 193*5c51f124SMoriah Waterland * Arguments: a_pkgaskflag - indicates whether or not pkgask is being run 194*5c51f124SMoriah Waterland * Returns: void 195*5c51f124SMoriah Waterland */ 196*5c51f124SMoriah Waterland 197*5c51f124SMoriah Waterland void 198*5c51f124SMoriah Waterland quitSetPkgask(boolean_t a_pkgaskFlag) 199*5c51f124SMoriah Waterland { 200*5c51f124SMoriah Waterland pkgaskFlag = a_pkgaskFlag; 201*5c51f124SMoriah Waterland } 202*5c51f124SMoriah Waterland 203*5c51f124SMoriah Waterland /* 204*5c51f124SMoriah Waterland * Name: quitSetSilentExit 205*5c51f124SMoriah Waterland * Description: set the "silent exit" flag - if silent exit is TRUE, then 206*5c51f124SMoriah Waterland * no messages are output by quit() when it is called 207*5c51f124SMoriah Waterland * Arguments: a_silentExit - indicates whether or not silent exit is set 208*5c51f124SMoriah Waterland * Returns: void 209*5c51f124SMoriah Waterland */ 210*5c51f124SMoriah Waterland 211*5c51f124SMoriah Waterland void 212*5c51f124SMoriah Waterland quitSetSilentExit(boolean_t a_silentExit) 213*5c51f124SMoriah Waterland { 214*5c51f124SMoriah Waterland silentExit = a_silentExit; 215*5c51f124SMoriah Waterland } 216*5c51f124SMoriah Waterland 217*5c51f124SMoriah Waterland /* 218*5c51f124SMoriah Waterland * Name: quit 219*5c51f124SMoriah Waterland * Description: cleanup and exit 220*5c51f124SMoriah Waterland * Arguments: a_retcode - the code to use to determine final exit status; 221*5c51f124SMoriah Waterland * if this is NOT "99" and if a "ckreturnFunc" is 222*5c51f124SMoriah Waterland * set, then that function is called with a_retcode 223*5c51f124SMoriah Waterland * to set the final exit status. 224*5c51f124SMoriah Waterland * Valid values are: 225*5c51f124SMoriah Waterland * 0 - success 226*5c51f124SMoriah Waterland * 1 - package operation failed (fatal error) 227*5c51f124SMoriah Waterland * 2 - non-fatal error (warning) 228*5c51f124SMoriah Waterland * 3 - user selected quit (operation interrupted) 229*5c51f124SMoriah Waterland * 4 - admin settings prevented operation 230*5c51f124SMoriah Waterland * 5 - interaction required and -n (non-interactive) specified 231*5c51f124SMoriah Waterland * "10" is added to indicate "immediate reboot required" 232*5c51f124SMoriah Waterland * "20" is be added to indicate "reboot after install required" 233*5c51f124SMoriah Waterland * 99 - do not interpret the code - just exit "99" 234*5c51f124SMoriah Waterland * Returns: <<this function does not return - calls exit()>> 235*5c51f124SMoriah Waterland */ 236*5c51f124SMoriah Waterland 237*5c51f124SMoriah Waterland void 238*5c51f124SMoriah Waterland quit(int retcode) 239*5c51f124SMoriah Waterland { 240*5c51f124SMoriah Waterland /* disable interrupts */ 241*5c51f124SMoriah Waterland 242*5c51f124SMoriah Waterland (void) signal(SIGINT, SIG_IGN); 243*5c51f124SMoriah Waterland (void) signal(SIGHUP, SIG_IGN); 244*5c51f124SMoriah Waterland 245*5c51f124SMoriah Waterland /* process return code if not quit(99) */ 246*5c51f124SMoriah Waterland 247*5c51f124SMoriah Waterland if (retcode != 99) { 248*5c51f124SMoriah Waterland if ((retcode % 10) == 0) { 249*5c51f124SMoriah Waterland if (failflag) { 250*5c51f124SMoriah Waterland retcode += 1; 251*5c51f124SMoriah Waterland } else if (warnflag) { 252*5c51f124SMoriah Waterland retcode += 2; 253*5c51f124SMoriah Waterland } 254*5c51f124SMoriah Waterland } 255*5c51f124SMoriah Waterland 256*5c51f124SMoriah Waterland if (ireboot) { 257*5c51f124SMoriah Waterland retcode = (retcode % 10) + 20; 258*5c51f124SMoriah Waterland } 259*5c51f124SMoriah Waterland if (dreboot) { 260*5c51f124SMoriah Waterland retcode = (retcode % 10) + 10; 261*5c51f124SMoriah Waterland } 262*5c51f124SMoriah Waterland } 263*5c51f124SMoriah Waterland 264*5c51f124SMoriah Waterland /* if set remove dstream temporary directory */ 265*5c51f124SMoriah Waterland 266*5c51f124SMoriah Waterland if (dstreamTempDir != (char *)NULL) { 267*5c51f124SMoriah Waterland echoDebug(DBG_REMOVING_DSTREAM_TMPDIR, dstreamTempDir); 268*5c51f124SMoriah Waterland (void) rrmdir(dstreamTempDir); 269*5c51f124SMoriah Waterland dstreamTempDir = (char *)NULL; 270*5c51f124SMoriah Waterland } 271*5c51f124SMoriah Waterland 272*5c51f124SMoriah Waterland /* If we're in dryrun mode, write out the dryrun file(s). */ 273*5c51f124SMoriah Waterland if (in_dryrun_mode()) { 274*5c51f124SMoriah Waterland char exit_msg[200]; 275*5c51f124SMoriah Waterland set_dr_info(EXITCODE, retcode); 276*5c51f124SMoriah Waterland if (failflag || warnflag) { 277*5c51f124SMoriah Waterland set_dr_exitmsg(msgtext); 278*5c51f124SMoriah Waterland } else { 279*5c51f124SMoriah Waterland /* LINTED variable format specified */ 280*5c51f124SMoriah Waterland (void) snprintf(exit_msg, sizeof (exit_msg), 281*5c51f124SMoriah Waterland qreason(1, retcode, installStarted, 282*5c51f124SMoriah Waterland includeZonename), 283*5c51f124SMoriah Waterland (pkginst ? pkginst : "unknown"), 284*5c51f124SMoriah Waterland zoneName); 285*5c51f124SMoriah Waterland set_dr_exitmsg(exit_msg); 286*5c51f124SMoriah Waterland } 287*5c51f124SMoriah Waterland 288*5c51f124SMoriah Waterland write_dryrun_file(extlist); 289*5c51f124SMoriah Waterland ptext(stderr, MSG_DRYRUN_DONE); 290*5c51f124SMoriah Waterland ptext(stderr, MSG_NOCHANGE); 291*5c51f124SMoriah Waterland 292*5c51f124SMoriah Waterland if (tmpdir[0] != NULL) 293*5c51f124SMoriah Waterland (void) rrmdir(tmpdir); 294*5c51f124SMoriah Waterland 295*5c51f124SMoriah Waterland } else { 296*5c51f124SMoriah Waterland /* fix bug #1082589 that deletes root file */ 297*5c51f124SMoriah Waterland if (tmpdir[0] != NULL) { 298*5c51f124SMoriah Waterland (void) rrmdir(tmpdir); 299*5c51f124SMoriah Waterland } 300*5c51f124SMoriah Waterland 301*5c51f124SMoriah Waterland /* send mail to appropriate user list */ 302*5c51f124SMoriah Waterland mailmsg(retcode); 303*5c51f124SMoriah Waterland 304*5c51f124SMoriah Waterland /* display message about this installation */ 305*5c51f124SMoriah Waterland quitmsg(retcode); 306*5c51f124SMoriah Waterland } 307*5c51f124SMoriah Waterland 308*5c51f124SMoriah Waterland /* 309*5c51f124SMoriah Waterland * In the event that this quit() was called prior to completion of 310*5c51f124SMoriah Waterland * the task, do an unlockinst() just in case. 311*5c51f124SMoriah Waterland */ 312*5c51f124SMoriah Waterland unlockinst(); 313*5c51f124SMoriah Waterland 314*5c51f124SMoriah Waterland /* Unmount anything that's our responsibility. */ 315*5c51f124SMoriah Waterland (void) unmount_client(); 316*5c51f124SMoriah Waterland 317*5c51f124SMoriah Waterland /* 318*5c51f124SMoriah Waterland * No need to umount device since calling process 319*5c51f124SMoriah Waterland * was responsible for original mount 320*5c51f124SMoriah Waterland */ 321*5c51f124SMoriah Waterland 322*5c51f124SMoriah Waterland if (!updatingExistingPackage) { 323*5c51f124SMoriah Waterland if (!installStarted && pkgloc[0]) { 324*5c51f124SMoriah Waterland /* 325*5c51f124SMoriah Waterland * install not yet started; if package install 326*5c51f124SMoriah Waterland * location is defined, remove the package. 327*5c51f124SMoriah Waterland */ 328*5c51f124SMoriah Waterland echoDebug(DBG_QUIT_REMOVING_PKGDIR, pkgloc); 329*5c51f124SMoriah Waterland 330*5c51f124SMoriah Waterland (void) chdir("/"); 331*5c51f124SMoriah Waterland if (pkgloc[0]) { 332*5c51f124SMoriah Waterland (void) rrmdir(pkgloc); 333*5c51f124SMoriah Waterland } 334*5c51f124SMoriah Waterland } 335*5c51f124SMoriah Waterland } else { 336*5c51f124SMoriah Waterland if (!installStarted) { 337*5c51f124SMoriah Waterland /* 338*5c51f124SMoriah Waterland * If we haven't started, but have already done 339*5c51f124SMoriah Waterland * the <PKGINST>/install directory rename, then 340*5c51f124SMoriah Waterland * remove the new <PKGINST>/install directory 341*5c51f124SMoriah Waterland * and rename <PKGINST>/install.save back to 342*5c51f124SMoriah Waterland * <PKGINST>/install. 343*5c51f124SMoriah Waterland */ 344*5c51f124SMoriah Waterland if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) { 345*5c51f124SMoriah Waterland if (pkgloc[0] && !access(pkgloc, F_OK)) 346*5c51f124SMoriah Waterland (void) rrmdir(pkgloc); 347*5c51f124SMoriah Waterland if (rename(pkgloc_sav, pkgloc) == -1) { 348*5c51f124SMoriah Waterland progerr(ERR_PACKAGEBINREN, 349*5c51f124SMoriah Waterland pkgloc_sav, pkgloc); 350*5c51f124SMoriah Waterland } 351*5c51f124SMoriah Waterland } 352*5c51f124SMoriah Waterland } else { 353*5c51f124SMoriah Waterland if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) { 354*5c51f124SMoriah Waterland echoDebug(DBG_QUIT_REMOVING_PKGSAV, pkgloc_sav); 355*5c51f124SMoriah Waterland (void) rrmdir(pkgloc_sav); 356*5c51f124SMoriah Waterland } 357*5c51f124SMoriah Waterland } 358*5c51f124SMoriah Waterland } 359*5c51f124SMoriah Waterland 360*5c51f124SMoriah Waterland /* 361*5c51f124SMoriah Waterland * pkginst can be null if an administration setting doesn't all 362*5c51f124SMoriah Waterland * the package to be installed. Make sure pkginst exeists before 363*5c51f124SMoriah Waterland * updating the DB 364*5c51f124SMoriah Waterland */ 365*5c51f124SMoriah Waterland 366*5c51f124SMoriah Waterland if (dparts > 0) 367*5c51f124SMoriah Waterland ds_skiptoend(pkgdev.cdevice); 368*5c51f124SMoriah Waterland (void) ds_close(1); 369*5c51f124SMoriah Waterland 370*5c51f124SMoriah Waterland /* Free the filesystem table. */ 371*5c51f124SMoriah Waterland fs_tab_free(); 372*5c51f124SMoriah Waterland 373*5c51f124SMoriah Waterland /* Free the package information lists. */ 374*5c51f124SMoriah Waterland pinfo_free(); 375*5c51f124SMoriah Waterland 376*5c51f124SMoriah Waterland /* Free all stragglers. */ 377*5c51f124SMoriah Waterland bl_free(BL_ALL); 378*5c51f124SMoriah Waterland (void) pathdup(NULL); 379*5c51f124SMoriah Waterland 380*5c51f124SMoriah Waterland /* Free regfiles. */ 381*5c51f124SMoriah Waterland regfiles_free(); 382*5c51f124SMoriah Waterland 383*5c51f124SMoriah Waterland /* final exit debugging message */ 384*5c51f124SMoriah Waterland 385*5c51f124SMoriah Waterland echoDebug(DBG_EXIT_WITH_CODE, retcode); 386*5c51f124SMoriah Waterland 387*5c51f124SMoriah Waterland exit(retcode); 388*5c51f124SMoriah Waterland /*NOTREACHED*/ 389*5c51f124SMoriah Waterland } 390*5c51f124SMoriah Waterland 391*5c51f124SMoriah Waterland /* 392*5c51f124SMoriah Waterland * ***************************************************************************** 393*5c51f124SMoriah Waterland * static internal (private) functions 394*5c51f124SMoriah Waterland * ***************************************************************************** 395*5c51f124SMoriah Waterland */ 396*5c51f124SMoriah Waterland 397*5c51f124SMoriah Waterland static void 398*5c51f124SMoriah Waterland quitmsg(int retcode) 399*5c51f124SMoriah Waterland { 400*5c51f124SMoriah Waterland if (silentExit == B_TRUE) { 401*5c51f124SMoriah Waterland return; 402*5c51f124SMoriah Waterland } 403*5c51f124SMoriah Waterland 404*5c51f124SMoriah Waterland (void) putc('\n', stderr); 405*5c51f124SMoriah Waterland if (pkgaskFlag) { 406*5c51f124SMoriah Waterland ptext(stderr, qreason(0, retcode, installStarted, 407*5c51f124SMoriah Waterland includeZonename), zoneName); 408*5c51f124SMoriah Waterland } else if (pkginst) { 409*5c51f124SMoriah Waterland ptext(stderr, qreason(1, retcode, installStarted, 410*5c51f124SMoriah Waterland includeZonename), pkginst, zoneName); 411*5c51f124SMoriah Waterland } 412*5c51f124SMoriah Waterland 413*5c51f124SMoriah Waterland if (retcode && !installStarted) { 414*5c51f124SMoriah Waterland ptext(stderr, MSG_NOCHANGE); 415*5c51f124SMoriah Waterland } 416*5c51f124SMoriah Waterland } 417*5c51f124SMoriah Waterland 418*5c51f124SMoriah Waterland static void 419*5c51f124SMoriah Waterland mailmsg(int retcode) 420*5c51f124SMoriah Waterland { 421*5c51f124SMoriah Waterland struct utsname utsbuf; 422*5c51f124SMoriah Waterland FILE *pp; 423*5c51f124SMoriah Waterland char *cmd; 424*5c51f124SMoriah Waterland size_t len; 425*5c51f124SMoriah Waterland 426*5c51f124SMoriah Waterland if (silentExit == B_TRUE) { 427*5c51f124SMoriah Waterland return; 428*5c51f124SMoriah Waterland } 429*5c51f124SMoriah Waterland 430*5c51f124SMoriah Waterland if (!installStarted || pkgaskFlag || (adm.mail == NULL)) { 431*5c51f124SMoriah Waterland return; 432*5c51f124SMoriah Waterland } 433*5c51f124SMoriah Waterland 434*5c51f124SMoriah Waterland len = strlen(adm.mail) + sizeof (MAILCMD) + 2; 435*5c51f124SMoriah Waterland cmd = calloc(len, sizeof (char)); 436*5c51f124SMoriah Waterland if (cmd == NULL) { 437*5c51f124SMoriah Waterland logerr(WRN_NOMAIL); 438*5c51f124SMoriah Waterland return; 439*5c51f124SMoriah Waterland } 440*5c51f124SMoriah Waterland 441*5c51f124SMoriah Waterland (void) snprintf(cmd, len, "%s %s", MAILCMD, adm.mail); 442*5c51f124SMoriah Waterland if ((pp = popen(cmd, "w")) == NULL) { 443*5c51f124SMoriah Waterland logerr(WRN_NOMAIL); 444*5c51f124SMoriah Waterland return; 445*5c51f124SMoriah Waterland } 446*5c51f124SMoriah Waterland 447*5c51f124SMoriah Waterland if (msgtext) 448*5c51f124SMoriah Waterland ptext(pp, msgtext); 449*5c51f124SMoriah Waterland 450*5c51f124SMoriah Waterland (void) strcpy(utsbuf.nodename, MSG_NODENAME); 451*5c51f124SMoriah Waterland (void) uname(&utsbuf); 452*5c51f124SMoriah Waterland 453*5c51f124SMoriah Waterland ptext(pp, qreason(2, retcode, installStarted, includeZonename), 454*5c51f124SMoriah Waterland pkgname, utsbuf.nodename, pkginst, zoneName); 455*5c51f124SMoriah Waterland 456*5c51f124SMoriah Waterland if (pclose(pp)) { 457*5c51f124SMoriah Waterland logerr(WRN_FLMAIL); 458*5c51f124SMoriah Waterland } 459*5c51f124SMoriah Waterland } 460*5c51f124SMoriah Waterland 461*5c51f124SMoriah Waterland /* 462*5c51f124SMoriah Waterland * Name: trap 463*5c51f124SMoriah Waterland * Description: signal handler connected via quitGetTrapHandler() 464*5c51f124SMoriah Waterland * Arguments: signo - [RO, *RO] - (int) 465*5c51f124SMoriah Waterland * Integer representing the signal that caused the trap 466*5c51f124SMoriah Waterland * to this function to occur 467*5c51f124SMoriah Waterland * Returns: << NONE >> 468*5c51f124SMoriah Waterland * NOTE: This function exits the program after doing mandatory cleanup. 469*5c51f124SMoriah Waterland * NOTE: Even though quit() should NOT return, there is a call to _exit() 470*5c51f124SMoriah Waterland * put after each call to quit() just in case quit() ever returned 471*5c51f124SMoriah Waterland * by mistake. 472*5c51f124SMoriah Waterland */ 473*5c51f124SMoriah Waterland 474*5c51f124SMoriah Waterland static void 475*5c51f124SMoriah Waterland trap(int signo) 476*5c51f124SMoriah Waterland { 477*5c51f124SMoriah Waterland /* prevent reentrance */ 478*5c51f124SMoriah Waterland 479*5c51f124SMoriah Waterland if (trapEntered++ != 0) { 480*5c51f124SMoriah Waterland return; 481*5c51f124SMoriah Waterland } 482*5c51f124SMoriah Waterland 483*5c51f124SMoriah Waterland if ((signo == SIGINT) || (signo == SIGHUP)) { 484*5c51f124SMoriah Waterland quit(3); 485*5c51f124SMoriah Waterland _exit(3); 486*5c51f124SMoriah Waterland } 487*5c51f124SMoriah Waterland quit(1); 488*5c51f124SMoriah Waterland _exit(1); 489*5c51f124SMoriah Waterland } 490