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 /*
235c51f124SMoriah Waterland  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
245c51f124SMoriah Waterland  * Use is subject to license terms.
255c51f124SMoriah Waterland  */
265c51f124SMoriah Waterland 
275c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
285c51f124SMoriah Waterland /* All Rights Reserved */
295c51f124SMoriah Waterland 
305c51f124SMoriah Waterland 
315c51f124SMoriah Waterland #include <stdio.h>
325c51f124SMoriah Waterland #include <string.h>
335c51f124SMoriah Waterland #include <signal.h>
345c51f124SMoriah Waterland #include <sys/utsname.h>
355c51f124SMoriah Waterland #include <limits.h>
365c51f124SMoriah Waterland #include <stdlib.h>
375c51f124SMoriah Waterland #include <unistd.h>
385c51f124SMoriah Waterland #include <pkgdev.h>
395c51f124SMoriah Waterland #include <pkglocs.h>
405c51f124SMoriah Waterland #include <locale.h>
415c51f124SMoriah Waterland #include <libintl.h>
425c51f124SMoriah Waterland #include <errno.h>
435c51f124SMoriah Waterland #include <pkglib.h>
445c51f124SMoriah Waterland #include "install.h"
455c51f124SMoriah Waterland #include "dryrun.h"
465c51f124SMoriah Waterland #include "libadm.h"
475c51f124SMoriah Waterland #include "libinst.h"
485c51f124SMoriah Waterland #include "pkginstall.h"
495c51f124SMoriah Waterland #include "messages.h"
505c51f124SMoriah Waterland 
515c51f124SMoriah Waterland /* main.c */
525c51f124SMoriah Waterland extern char		*pkgdrtarg;
535c51f124SMoriah Waterland extern struct cfextra	**extlist;
545c51f124SMoriah Waterland 
555c51f124SMoriah Waterland extern struct	admin adm;
565c51f124SMoriah Waterland extern struct	pkgdev pkgdev;	/* holds info about the installation device */
575c51f124SMoriah Waterland 
585c51f124SMoriah Waterland extern int	dparts;
595c51f124SMoriah Waterland extern int	dreboot;	/* != 0 if reboot required after installation */
605c51f124SMoriah Waterland extern int	failflag;	/* != 0 if fatal error has occurred (1) */
615c51f124SMoriah Waterland extern int	ireboot;	/* != 0 if immediate reboot required */
625c51f124SMoriah Waterland extern int	warnflag;	/* != 0 if non-fatal error has occurred (2) */
635c51f124SMoriah Waterland 
645c51f124SMoriah Waterland extern char	tmpdir[];
655c51f124SMoriah Waterland extern char	pkgloc[];
665c51f124SMoriah Waterland extern char	pkgloc_sav[];
675c51f124SMoriah Waterland extern char	*msgtext;
685c51f124SMoriah Waterland extern char	*pkginst;
695c51f124SMoriah Waterland extern char	*pkgname;
705c51f124SMoriah Waterland 
715c51f124SMoriah Waterland /*
725c51f124SMoriah Waterland  * exported functions
735c51f124SMoriah Waterland  */
745c51f124SMoriah Waterland 
755c51f124SMoriah Waterland void		quit(int retcode);
765c51f124SMoriah Waterland void		quitSetZoneName(char *a_zoneName);
775c51f124SMoriah Waterland sighdlrFunc_t	*quitGetTrapHandler(void);
785c51f124SMoriah Waterland 
795c51f124SMoriah Waterland /*
805c51f124SMoriah Waterland  * forward declarations
815c51f124SMoriah Waterland  */
825c51f124SMoriah Waterland 
835c51f124SMoriah Waterland static void		trap(int signo);
845c51f124SMoriah Waterland static void		mailmsg(int retcode);
855c51f124SMoriah Waterland static void		quitmsg(int retcode);
865c51f124SMoriah Waterland 
875c51f124SMoriah Waterland static boolean_t	silentExit = B_FALSE;
885c51f124SMoriah Waterland static boolean_t	pkgaskFlag = B_FALSE;
895c51f124SMoriah Waterland static boolean_t	installStarted = B_FALSE;
905c51f124SMoriah Waterland static boolean_t	updatingExistingPackage = B_FALSE;
915c51f124SMoriah Waterland 
925c51f124SMoriah Waterland static char		*dstreamTempDir = (char *)NULL;
935c51f124SMoriah Waterland static char		*zoneName = (char *)NULL;
945c51f124SMoriah Waterland static int		includeZonename = 0;
955c51f124SMoriah Waterland static int		trapEntered = 0;
965c51f124SMoriah Waterland 
975c51f124SMoriah Waterland /*
985c51f124SMoriah Waterland  * *****************************************************************************
995c51f124SMoriah Waterland  * global external (public) functions
1005c51f124SMoriah Waterland  * *****************************************************************************
1015c51f124SMoriah Waterland  */
1025c51f124SMoriah Waterland 
1035c51f124SMoriah Waterland /*
1045c51f124SMoriah Waterland  * Name:	quitGetTrapHandler
1055c51f124SMoriah Waterland  * Description:	return address of this modules "signal trap" handler
1065c51f124SMoriah Waterland  * Arguments:	void
1075c51f124SMoriah Waterland  * Returns:	sighdlrFunc_t
1085c51f124SMoriah Waterland  *			The address of the trap handler that can be passed to
1095c51f124SMoriah Waterland  *			the signal() type system calls
1105c51f124SMoriah Waterland  */
1115c51f124SMoriah Waterland 
1125c51f124SMoriah Waterland sighdlrFunc_t *
quitGetTrapHandler(void)1135c51f124SMoriah Waterland quitGetTrapHandler(void)
1145c51f124SMoriah Waterland {
1155c51f124SMoriah Waterland 	return (&trap);
1165c51f124SMoriah Waterland }
1175c51f124SMoriah Waterland 
1185c51f124SMoriah Waterland /*
1195c51f124SMoriah Waterland  * Name:	quitSetZoneName
1205c51f124SMoriah Waterland  * Description:	set the zone name the program is running in
1215c51f124SMoriah Waterland  * Arguments:	a_zoneName - pointer to string representing the name of the zone
1225c51f124SMoriah Waterland  *			that the program is running in
1235c51f124SMoriah Waterland  * Returns:	void
1245c51f124SMoriah Waterland  */
1255c51f124SMoriah Waterland 
1265c51f124SMoriah Waterland void
quitSetZoneName(char * a_zoneName)1275c51f124SMoriah Waterland quitSetZoneName(char *a_zoneName)
1285c51f124SMoriah Waterland {
1295c51f124SMoriah Waterland 	zoneName = a_zoneName;
1305c51f124SMoriah Waterland 	if ((zoneName == (char *)NULL || *zoneName == '\0')) {
1315c51f124SMoriah Waterland 		includeZonename = 0;
1325c51f124SMoriah Waterland 	} else {
1335c51f124SMoriah Waterland 		includeZonename = 1;
1345c51f124SMoriah Waterland 	}
1355c51f124SMoriah Waterland }
1365c51f124SMoriah Waterland 
1375c51f124SMoriah Waterland /*
1385c51f124SMoriah Waterland  * Name:	quitSetDstreamTmpdir
1395c51f124SMoriah Waterland  * Description:	set the name of a temporary directory that contains package
1405c51f124SMoriah Waterland  *		streams to be removed when quit() is called
1415c51f124SMoriah Waterland  * Arguments:	a_dstreamTempDir - pointer to string representing the path
1425c51f124SMoriah Waterland  *			to the temporary directory to remove when quit()
1435c51f124SMoriah Waterland  *			is called
1445c51f124SMoriah Waterland  * Returns:	void
1455c51f124SMoriah Waterland  */
1465c51f124SMoriah Waterland 
1475c51f124SMoriah Waterland void
quitSetDstreamTmpdir(char * a_dstreamTempDir)1485c51f124SMoriah Waterland quitSetDstreamTmpdir(char *a_dstreamTempDir)
1495c51f124SMoriah Waterland {
1505c51f124SMoriah Waterland 	dstreamTempDir = a_dstreamTempDir;
1515c51f124SMoriah Waterland }
1525c51f124SMoriah Waterland 
1535c51f124SMoriah Waterland /*
1545c51f124SMoriah Waterland  * Name:	quitSetUpdatingExisting
1555c51f124SMoriah Waterland  * Description:	set the "updating existing" flag - used in conjunction
1565c51f124SMoriah Waterland  *		with the "install started" flag to determine the type
1575c51f124SMoriah Waterland  *		of cleanup to be done when quit() is called
1585c51f124SMoriah Waterland  * Arguments:	a_updatingExistingPackage - indicates whether or not existing
1595c51f124SMoriah Waterland  *			packages are being updated (B_TRUE) or new packages
1605c51f124SMoriah Waterland  *			are being installed (B_FALSE)
1615c51f124SMoriah Waterland  * Returns:	void
1625c51f124SMoriah Waterland  */
1635c51f124SMoriah Waterland 
1645c51f124SMoriah Waterland void
quitSetUpdatingExisting(boolean_t a_updatingExistingPackage)1655c51f124SMoriah Waterland quitSetUpdatingExisting(boolean_t a_updatingExistingPackage)
1665c51f124SMoriah Waterland {
1675c51f124SMoriah Waterland 	updatingExistingPackage = a_updatingExistingPackage;
1685c51f124SMoriah Waterland }
1695c51f124SMoriah Waterland 
1705c51f124SMoriah Waterland /*
1715c51f124SMoriah Waterland  * Name:	quitSetInstallStarted
1725c51f124SMoriah Waterland  * Description:	set the "install started" flag - used in conjunction
1735c51f124SMoriah Waterland  *		with the "updating existing" flag to determine the type
1745c51f124SMoriah Waterland  *		of cleanup to be done when quit() is called, and the
1755c51f124SMoriah Waterland  *		type of message to be output for the "reason" why quit()
1765c51f124SMoriah Waterland  *		was called
1775c51f124SMoriah Waterland  * Arguments:	a_installStarted - indicates whether or not installation
1785c51f124SMoriah Waterland  *			has started
1795c51f124SMoriah Waterland  * Returns:	void
1805c51f124SMoriah Waterland  */
1815c51f124SMoriah Waterland 
1825c51f124SMoriah Waterland void
quitSetInstallStarted(boolean_t a_installStarted)1835c51f124SMoriah Waterland quitSetInstallStarted(boolean_t a_installStarted)
1845c51f124SMoriah Waterland {
1855c51f124SMoriah Waterland 	installStarted = a_installStarted;
1865c51f124SMoriah Waterland }
1875c51f124SMoriah Waterland 
1885c51f124SMoriah Waterland /*
1895c51f124SMoriah Waterland  * Name:	quitSetPkgask
1905c51f124SMoriah Waterland  * Description:	set the "pkgask is being run" flag - used to determine
1915c51f124SMoriah Waterland  *		the type of message to be output for the "reason" why
1925c51f124SMoriah Waterland  *		quit() was called
1935c51f124SMoriah Waterland  * Arguments:	a_pkgaskflag - indicates whether or not pkgask is being run
1945c51f124SMoriah Waterland  * Returns:	void
1955c51f124SMoriah Waterland  */
1965c51f124SMoriah Waterland 
1975c51f124SMoriah Waterland void
quitSetPkgask(boolean_t a_pkgaskFlag)1985c51f124SMoriah Waterland quitSetPkgask(boolean_t a_pkgaskFlag)
1995c51f124SMoriah Waterland {
2005c51f124SMoriah Waterland 	pkgaskFlag = a_pkgaskFlag;
2015c51f124SMoriah Waterland }
2025c51f124SMoriah Waterland 
2035c51f124SMoriah Waterland /*
2045c51f124SMoriah Waterland  * Name:	quitSetSilentExit
2055c51f124SMoriah Waterland  * Description:	set the "silent exit" flag - if silent exit is TRUE, then
2065c51f124SMoriah Waterland  *		no messages are output by quit() when it is called
2075c51f124SMoriah Waterland  * Arguments:	a_silentExit - indicates whether or not silent exit is set
2085c51f124SMoriah Waterland  * Returns:	void
2095c51f124SMoriah Waterland  */
2105c51f124SMoriah Waterland 
2115c51f124SMoriah Waterland void
quitSetSilentExit(boolean_t a_silentExit)2125c51f124SMoriah Waterland quitSetSilentExit(boolean_t a_silentExit)
2135c51f124SMoriah Waterland {
2145c51f124SMoriah Waterland 	silentExit = a_silentExit;
2155c51f124SMoriah Waterland }
2165c51f124SMoriah Waterland 
2175c51f124SMoriah Waterland /*
2185c51f124SMoriah Waterland  * Name:	quit
2195c51f124SMoriah Waterland  * Description:	cleanup and exit
2205c51f124SMoriah Waterland  * Arguments:	a_retcode - the code to use to determine final exit status;
2215c51f124SMoriah Waterland  *			if this is NOT "99" and if a "ckreturnFunc" is
2225c51f124SMoriah Waterland  *			set, then that function is called with a_retcode
2235c51f124SMoriah Waterland  *			to set the final exit status.
2245c51f124SMoriah Waterland  *		Valid values are:
2255c51f124SMoriah Waterland  *		0 - success
2265c51f124SMoriah Waterland  *		1 - package operation failed (fatal error)
2275c51f124SMoriah Waterland  *		2 - non-fatal error (warning)
2285c51f124SMoriah Waterland  *		3 - user selected quit (operation interrupted)
2295c51f124SMoriah Waterland  *		4 - admin settings prevented operation
2305c51f124SMoriah Waterland  *		5 - interaction required and -n (non-interactive) specified
2315c51f124SMoriah Waterland  *		"10" is added to indicate "immediate reboot required"
2325c51f124SMoriah Waterland  *		"20" is be added to indicate "reboot after install required"
2335c51f124SMoriah Waterland  *		99 - do not interpret the code - just exit "99"
2345c51f124SMoriah Waterland  * Returns:	<<this function does not return - calls exit()>>
2355c51f124SMoriah Waterland  */
2365c51f124SMoriah Waterland 
2375c51f124SMoriah Waterland void
quit(int retcode)2385c51f124SMoriah Waterland quit(int retcode)
2395c51f124SMoriah Waterland {
2405c51f124SMoriah Waterland 	/* disable interrupts */
2415c51f124SMoriah Waterland 
2425c51f124SMoriah Waterland 	(void) signal(SIGINT, SIG_IGN);
2435c51f124SMoriah Waterland 	(void) signal(SIGHUP, SIG_IGN);
2445c51f124SMoriah Waterland 
2455c51f124SMoriah Waterland 	/* process return code if not quit(99) */
2465c51f124SMoriah Waterland 
2475c51f124SMoriah Waterland 	if (retcode != 99) {
2485c51f124SMoriah Waterland 		if ((retcode % 10) == 0) {
2495c51f124SMoriah Waterland 			if (failflag) {
2505c51f124SMoriah Waterland 				retcode += 1;
2515c51f124SMoriah Waterland 			} else if (warnflag) {
2525c51f124SMoriah Waterland 				retcode += 2;
2535c51f124SMoriah Waterland 			}
2545c51f124SMoriah Waterland 		}
2555c51f124SMoriah Waterland 
2565c51f124SMoriah Waterland 		if (ireboot) {
2575c51f124SMoriah Waterland 			retcode = (retcode % 10) + 20;
2585c51f124SMoriah Waterland 		}
2595c51f124SMoriah Waterland 		if (dreboot) {
2605c51f124SMoriah Waterland 			retcode = (retcode % 10) + 10;
2615c51f124SMoriah Waterland 		}
2625c51f124SMoriah Waterland 	}
2635c51f124SMoriah Waterland 
2645c51f124SMoriah Waterland 	/* if set remove dstream temporary directory */
2655c51f124SMoriah Waterland 
2665c51f124SMoriah Waterland 	if (dstreamTempDir != (char *)NULL) {
2675c51f124SMoriah Waterland 		echoDebug(DBG_REMOVING_DSTREAM_TMPDIR, dstreamTempDir);
2685c51f124SMoriah Waterland 		(void) rrmdir(dstreamTempDir);
2695c51f124SMoriah Waterland 		dstreamTempDir = (char *)NULL;
2705c51f124SMoriah Waterland 	}
2715c51f124SMoriah Waterland 
2725c51f124SMoriah Waterland 	/* If we're in dryrun mode, write out the dryrun file(s). */
2735c51f124SMoriah Waterland 	if (in_dryrun_mode()) {
2745c51f124SMoriah Waterland 		char exit_msg[200];
2755c51f124SMoriah Waterland 		set_dr_info(EXITCODE, retcode);
2765c51f124SMoriah Waterland 		if (failflag || warnflag) {
2775c51f124SMoriah Waterland 			set_dr_exitmsg(msgtext);
2785c51f124SMoriah Waterland 		} else {
2795c51f124SMoriah Waterland 			/* LINTED variable format specified */
2805c51f124SMoriah Waterland 			(void) snprintf(exit_msg, sizeof (exit_msg),
2815c51f124SMoriah Waterland 				qreason(1, retcode, installStarted,
2825c51f124SMoriah Waterland 					includeZonename),
2835c51f124SMoriah Waterland 					(pkginst ? pkginst : "unknown"),
2845c51f124SMoriah Waterland 					zoneName);
2855c51f124SMoriah Waterland 			set_dr_exitmsg(exit_msg);
2865c51f124SMoriah Waterland 		}
2875c51f124SMoriah Waterland 
2885c51f124SMoriah Waterland 		write_dryrun_file(extlist);
2895c51f124SMoriah Waterland 		ptext(stderr, MSG_DRYRUN_DONE);
2905c51f124SMoriah Waterland 		ptext(stderr, MSG_NOCHANGE);
2915c51f124SMoriah Waterland 
292*c57b7750SToomas Soome 		if (tmpdir[0] != '\0')
2935c51f124SMoriah Waterland 			(void) rrmdir(tmpdir);
2945c51f124SMoriah Waterland 
2955c51f124SMoriah Waterland 	} else {
2965c51f124SMoriah Waterland 		/* fix bug #1082589 that deletes root file */
297*c57b7750SToomas Soome 		if (tmpdir[0] != '\0') {
2985c51f124SMoriah Waterland 			(void) rrmdir(tmpdir);
2995c51f124SMoriah Waterland 		}
3005c51f124SMoriah Waterland 
3015c51f124SMoriah Waterland 		/* send mail to appropriate user list */
3025c51f124SMoriah Waterland 		mailmsg(retcode);
3035c51f124SMoriah Waterland 
3045c51f124SMoriah Waterland 		/* display message about this installation */
3055c51f124SMoriah Waterland 		quitmsg(retcode);
3065c51f124SMoriah Waterland 	}
3075c51f124SMoriah Waterland 
3085c51f124SMoriah Waterland 	/*
3095c51f124SMoriah Waterland 	 * In the event that this quit() was called prior to completion of
3105c51f124SMoriah Waterland 	 * the task, do an unlockinst() just in case.
3115c51f124SMoriah Waterland 	 */
3125c51f124SMoriah Waterland 	unlockinst();
3135c51f124SMoriah Waterland 
3145c51f124SMoriah Waterland 	/* Unmount anything that's our responsibility. */
3155c51f124SMoriah Waterland 	(void) unmount_client();
3165c51f124SMoriah Waterland 
3175c51f124SMoriah Waterland 	/*
3185c51f124SMoriah Waterland 	 * No need to umount device since calling process
3195c51f124SMoriah Waterland 	 * was responsible for original mount
3205c51f124SMoriah Waterland 	 */
3215c51f124SMoriah Waterland 
3225c51f124SMoriah Waterland 	if (!updatingExistingPackage) {
3235c51f124SMoriah Waterland 		if (!installStarted && pkgloc[0]) {
3245c51f124SMoriah Waterland 			/*
3255c51f124SMoriah Waterland 			 * install not yet started; if package install
3265c51f124SMoriah Waterland 			 * location is defined, remove the package.
3275c51f124SMoriah Waterland 			 */
3285c51f124SMoriah Waterland 			echoDebug(DBG_QUIT_REMOVING_PKGDIR, pkgloc);
3295c51f124SMoriah Waterland 
3305c51f124SMoriah Waterland 			(void) chdir("/");
3315c51f124SMoriah Waterland 			if (pkgloc[0]) {
3325c51f124SMoriah Waterland 				(void) rrmdir(pkgloc);
3335c51f124SMoriah Waterland 			}
3345c51f124SMoriah Waterland 		}
3355c51f124SMoriah Waterland 	} else {
3365c51f124SMoriah Waterland 		if (!installStarted) {
3375c51f124SMoriah Waterland 			/*
3385c51f124SMoriah Waterland 			 * If we haven't started, but have already done
3395c51f124SMoriah Waterland 			 * the <PKGINST>/install directory rename, then
3405c51f124SMoriah Waterland 			 * remove the new <PKGINST>/install directory
3415c51f124SMoriah Waterland 			 * and rename <PKGINST>/install.save back to
3425c51f124SMoriah Waterland 			 * <PKGINST>/install.
3435c51f124SMoriah Waterland 			 */
3445c51f124SMoriah Waterland 			if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) {
3455c51f124SMoriah Waterland 				if (pkgloc[0] && !access(pkgloc, F_OK))
3465c51f124SMoriah Waterland 					(void) rrmdir(pkgloc);
3475c51f124SMoriah Waterland 				if (rename(pkgloc_sav, pkgloc) == -1) {
3485c51f124SMoriah Waterland 					progerr(ERR_PACKAGEBINREN,
3495c51f124SMoriah Waterland 						pkgloc_sav, pkgloc);
3505c51f124SMoriah Waterland 				}
3515c51f124SMoriah Waterland 			}
3525c51f124SMoriah Waterland 		} else {
3535c51f124SMoriah Waterland 			if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) {
3545c51f124SMoriah Waterland 				echoDebug(DBG_QUIT_REMOVING_PKGSAV, pkgloc_sav);
3555c51f124SMoriah Waterland 				(void) rrmdir(pkgloc_sav);
3565c51f124SMoriah Waterland 			}
3575c51f124SMoriah Waterland 		}
3585c51f124SMoriah Waterland 	}
3595c51f124SMoriah Waterland 
3605c51f124SMoriah Waterland 	/*
3615c51f124SMoriah Waterland 	 * pkginst can be null if an administration setting doesn't all
3625c51f124SMoriah Waterland 	 * the package to be installed. Make sure pkginst exeists before
3635c51f124SMoriah Waterland 	 * updating the DB
3645c51f124SMoriah Waterland 	 */
3655c51f124SMoriah Waterland 
3665c51f124SMoriah Waterland 	if (dparts > 0)
3675c51f124SMoriah Waterland 		ds_skiptoend(pkgdev.cdevice);
3685c51f124SMoriah Waterland 	(void) ds_close(1);
3695c51f124SMoriah Waterland 
3705c51f124SMoriah Waterland 	/* Free the filesystem table. */
3715c51f124SMoriah Waterland 	fs_tab_free();
3725c51f124SMoriah Waterland 
3735c51f124SMoriah Waterland 	/* Free the package information lists. */
3745c51f124SMoriah Waterland 	pinfo_free();
3755c51f124SMoriah Waterland 
3765c51f124SMoriah Waterland 	/* Free all stragglers. */
3775c51f124SMoriah Waterland 	bl_free(BL_ALL);
3785c51f124SMoriah Waterland 	(void) pathdup(NULL);
3795c51f124SMoriah Waterland 
3805c51f124SMoriah Waterland 	/* Free regfiles. */
3815c51f124SMoriah Waterland 	regfiles_free();
3825c51f124SMoriah Waterland 
3835c51f124SMoriah Waterland 	/* final exit debugging message */
3845c51f124SMoriah Waterland 
3855c51f124SMoriah Waterland 	echoDebug(DBG_EXIT_WITH_CODE, retcode);
3865c51f124SMoriah Waterland 
3875c51f124SMoriah Waterland 	exit(retcode);
3885c51f124SMoriah Waterland 	/*NOTREACHED*/
3895c51f124SMoriah Waterland }
3905c51f124SMoriah Waterland 
3915c51f124SMoriah Waterland /*
3925c51f124SMoriah Waterland  * *****************************************************************************
3935c51f124SMoriah Waterland  * static internal (private) functions
3945c51f124SMoriah Waterland  * *****************************************************************************
3955c51f124SMoriah Waterland  */
3965c51f124SMoriah Waterland 
3975c51f124SMoriah Waterland static void
quitmsg(int retcode)3985c51f124SMoriah Waterland quitmsg(int retcode)
3995c51f124SMoriah Waterland {
4005c51f124SMoriah Waterland 	if (silentExit == B_TRUE) {
4015c51f124SMoriah Waterland 		return;
4025c51f124SMoriah Waterland 	}
4035c51f124SMoriah Waterland 
4045c51f124SMoriah Waterland 	(void) putc('\n', stderr);
4055c51f124SMoriah Waterland 	if (pkgaskFlag) {
4065c51f124SMoriah Waterland 		ptext(stderr, qreason(0, retcode, installStarted,
4075c51f124SMoriah Waterland 			includeZonename), zoneName);
4085c51f124SMoriah Waterland 	} else if (pkginst) {
4095c51f124SMoriah Waterland 		ptext(stderr, qreason(1, retcode, installStarted,
4105c51f124SMoriah Waterland 			includeZonename), pkginst, zoneName);
4115c51f124SMoriah Waterland 	}
4125c51f124SMoriah Waterland 
4135c51f124SMoriah Waterland 	if (retcode && !installStarted) {
4145c51f124SMoriah Waterland 		ptext(stderr, MSG_NOCHANGE);
4155c51f124SMoriah Waterland 	}
4165c51f124SMoriah Waterland }
4175c51f124SMoriah Waterland 
4185c51f124SMoriah Waterland static void
mailmsg(int retcode)4195c51f124SMoriah Waterland mailmsg(int retcode)
4205c51f124SMoriah Waterland {
4215c51f124SMoriah Waterland 	struct utsname utsbuf;
4225c51f124SMoriah Waterland 	FILE	*pp;
4235c51f124SMoriah Waterland 	char	*cmd;
4245c51f124SMoriah Waterland 	size_t	len;
4255c51f124SMoriah Waterland 
4265c51f124SMoriah Waterland 	if (silentExit == B_TRUE) {
4275c51f124SMoriah Waterland 		return;
4285c51f124SMoriah Waterland 	}
4295c51f124SMoriah Waterland 
4305c51f124SMoriah Waterland 	if (!installStarted || pkgaskFlag || (adm.mail == NULL)) {
4315c51f124SMoriah Waterland 		return;
4325c51f124SMoriah Waterland 	}
4335c51f124SMoriah Waterland 
4345c51f124SMoriah Waterland 	len = strlen(adm.mail) + sizeof (MAILCMD) + 2;
4355c51f124SMoriah Waterland 	cmd = calloc(len, sizeof (char));
4365c51f124SMoriah Waterland 	if (cmd == NULL) {
4375c51f124SMoriah Waterland 		logerr(WRN_NOMAIL);
4385c51f124SMoriah Waterland 		return;
4395c51f124SMoriah Waterland 	}
4405c51f124SMoriah Waterland 
4415c51f124SMoriah Waterland 	(void) snprintf(cmd, len, "%s %s", MAILCMD, adm.mail);
4425c51f124SMoriah Waterland 	if ((pp = popen(cmd, "w")) == NULL) {
4435c51f124SMoriah Waterland 		logerr(WRN_NOMAIL);
4445c51f124SMoriah Waterland 		return;
4455c51f124SMoriah Waterland 	}
4465c51f124SMoriah Waterland 
4475c51f124SMoriah Waterland 	if (msgtext)
4485c51f124SMoriah Waterland 		ptext(pp, msgtext);
4495c51f124SMoriah Waterland 
4505c51f124SMoriah Waterland 	(void) strcpy(utsbuf.nodename, MSG_NODENAME);
4515c51f124SMoriah Waterland 	(void) uname(&utsbuf);
4525c51f124SMoriah Waterland 
4535c51f124SMoriah Waterland 	ptext(pp, qreason(2, retcode, installStarted, includeZonename),
4545c51f124SMoriah Waterland 		pkgname, utsbuf.nodename, pkginst, zoneName);
4555c51f124SMoriah Waterland 
4565c51f124SMoriah Waterland 	if (pclose(pp)) {
4575c51f124SMoriah Waterland 		logerr(WRN_FLMAIL);
4585c51f124SMoriah Waterland 	}
4595c51f124SMoriah Waterland }
4605c51f124SMoriah Waterland 
4615c51f124SMoriah Waterland /*
4625c51f124SMoriah Waterland  * Name:	trap
4635c51f124SMoriah Waterland  * Description:	signal handler connected via quitGetTrapHandler()
4645c51f124SMoriah Waterland  * Arguments:	signo - [RO, *RO] - (int)
4655c51f124SMoriah Waterland  *			Integer representing the signal that caused the trap
4665c51f124SMoriah Waterland  *			to this function to occur
4675c51f124SMoriah Waterland  * Returns:	<< NONE >>
4685c51f124SMoriah Waterland  * NOTE:	This function exits the program after doing mandatory cleanup.
4695c51f124SMoriah Waterland  * NOTE:	Even though quit() should NOT return, there is a call to _exit()
4705c51f124SMoriah Waterland  *		put after each call to quit() just in case quit() ever returned
4715c51f124SMoriah Waterland  *		by mistake.
4725c51f124SMoriah Waterland  */
4735c51f124SMoriah Waterland 
4745c51f124SMoriah Waterland static void
trap(int signo)4755c51f124SMoriah Waterland trap(int signo)
4765c51f124SMoriah Waterland {
4775c51f124SMoriah Waterland 	/* prevent reentrance */
4785c51f124SMoriah Waterland 
4795c51f124SMoriah Waterland 	if (trapEntered++ != 0) {
4805c51f124SMoriah Waterland 		return;
4815c51f124SMoriah Waterland 	}
4825c51f124SMoriah Waterland 
4835c51f124SMoriah Waterland 	if ((signo == SIGINT) || (signo == SIGHUP)) {
4845c51f124SMoriah Waterland 		quit(3);
4855c51f124SMoriah Waterland 		_exit(3);
4865c51f124SMoriah Waterland 	}
4875c51f124SMoriah Waterland 	quit(1);
4885c51f124SMoriah Waterland 	_exit(1);
4895c51f124SMoriah Waterland }
490