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