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 *
quitGetTrapHandler(void)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
quitSetZoneName(char * a_zoneName)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
quitSetDstreamTmpdir(char * a_dstreamTempDir)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
quitSetUpdatingExisting(boolean_t a_updatingExistingPackage)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
quitSetInstallStarted(boolean_t a_installStarted)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
quitSetPkgask(boolean_t a_pkgaskFlag)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
quitSetSilentExit(boolean_t a_silentExit)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
quit(int retcode)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
quitmsg(int retcode)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
mailmsg(int retcode)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
trap(int signo)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