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