4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2017 Peter Tribble.
27 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
30 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
31 /* All Rights Reserved */
41 #include <sys/statvfs.h>
56 #include <instzones_api.h>
63 #include "pkginstall.h"
65 /* imported globals */
67 extern char **environ
;
72 extern char pkgwild
[];
76 extern char *get_install_root(void);
80 extern sighdlrFunc_t
*quitGetTrapHandler(void);
81 extern void quitSetDstreamTmpdir(char *a_dstreamTempDir
);
82 extern void quitSetInstallStarted(boolean_t a_installStarted
);
83 extern void quitSetPkgask(boolean_t a_pkgaskFlag
);
84 extern void quitSetSilentExit(boolean_t a_silentExit
);
85 extern void quitSetUpdatingExisting(boolean_t a_updatingExisting
);
86 extern void quitSetZoneName(char *a_zoneName
);
91 static char path
[PATH_MAX
];
92 static int ck_instbase(void);
93 static int cp_pkgdirs(void);
94 static int merg_pkginfos(struct cl_attr
**pclass
,
95 struct cl_attr
***mpclass
);
96 static int merg_respfile(void);
97 static int mv_pkgdirs(void);
98 static int rdonly(char *p
);
99 static void ck_w_dryrun(int (*func
)(), int type
);
100 static void copyright(void), usage(void);
101 static void do_pkgask(boolean_t a_run_request_as_root
);
102 static void rm_icas(char *casdir
);
103 static void set_dryrun_dir_loc(void);
104 static void unpack(void);
106 void ckreturn(int retcode
, char *msg
);
108 static char *ro_params
[] = {
109 "PATH", "NAME", "PKG", "PKGINST",
111 "INSTDATE", "CATEGORY",
116 * The following variable is the name of the device to which stdin
117 * is connected during execution of a procedure script. PROC_STDIN is
118 * correct for all ABI compliant packages. For non-ABI-compliant
119 * packages, the '-o' command line switch changes this to PROC_XSTDIN
120 * to allow user interaction during these scripts. -- JST
122 static char *script_in
= PROC_STDIN
; /* assume ABI compliance */
124 static char *pkgdrtarg
= NULL
;
125 static char *pkgcontsrc
= NULL
;
126 static int non_abi_scripts
= 0;
127 static char *respfile
= NULL
;
128 static char *srcinst
= NULL
;
129 static int suppressCopyright
= 0;
130 static int nointeract
= 0;
132 /* exported globals */
135 char *pkginst
= (char *)NULL
;
136 char *rw_block_size
= NULL
;
137 char ilockfile
[PATH_MAX
];
138 char instdir
[PATH_MAX
];
139 char saveSpoolInstallDir
[PATH_MAX
];
140 char pkgbin
[PATH_MAX
];
141 char pkgloc
[PATH_MAX
];
142 char pkgloc_sav
[PATH_MAX
];
143 char pkgsav
[PATH_MAX
];
144 char rlockfile
[PATH_MAX
];
145 char savlog
[PATH_MAX
];
146 char tmpdir
[PATH_MAX
];
151 static int askflag
= 0; /* non-zero if invoked as "pkgask" */
160 struct cfextra
**extlist
; /* pkgmap structure and other path info */
161 struct pkgdev pkgdev
;
162 fsblkcnt_t pkgmap_blks
= 0LL;
165 * this global is referenced by:
166 * getinst - [RW] - incremented if:
167 * - installing same instance again
168 * - overwriting an existing instance
169 * - not installing a new instance
170 * quit - [RO] - if non-zero and started non-zero:
171 * - the new <PKGINST>/install directory and rename <PKGINST>/install.save
172 * - back to <PKGINST>/install
173 * main.c - [RO] - if non-zero:
174 * - alter manner in which parameters are setup for scripts
175 * - set UPDATE=yes in environment
177 static int update
= 0;
179 /* Set by -O debug: debug output is enabled? */
181 static boolean_t debugFlag
= B_FALSE
;
183 /* Set by the -G option: install packages in global zone only */
185 static boolean_t globalZoneOnly
= B_FALSE
;
187 /* Set by -O preinstallcheck */
189 static boolean_t preinstallCheck
= B_FALSE
;
191 /* Set by -O parent-zone-name= */
193 static char *parentZoneName
= (char *)NULL
;
195 /* Set by -O parent-zone-type= */
197 static char *parentZoneType
= (char *)NULL
;
199 #define DEFPATH "/sbin:/usr/sbin:/usr/bin"
200 #define MALSIZ 4 /* best guess at likely maximum value of MAXINST */
201 #define LSIZE 256 /* maximum line size supported in copyright file */
203 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
204 #define TEXT_DOMAIN "SYS_TEST"
207 /* This is the text for the "-O parent-zone-name=" option */
209 #define PARENTZONENAME "parent-zone-name="
210 #define PARENTZONENAME_LEN ((sizeof (PARENTZONENAME))-1)
212 /* This is the text for the "-O parent-zone-type=" option */
214 #define PARENTZONETYPE "parent-zone-type="
215 #define PARENTZONETYPE_LEN ((sizeof (PARENTZONETYPE))-1)
217 static char *cpio_names
[] = {
230 main(int argc
, char *argv
[])
232 VFP_T
*cfTmpVfp
= NULL
; /* temporary */
233 VFP_T
*pkgmapVfp
; /* "../pkgmap" file */
234 boolean_t run_request_as_root
= B_FALSE
;
239 char *admnfile
= NULL
;
242 char *prog_full_name
= NULL
;
244 char *updated
= (char *)NULL
;
245 char *vfstab_file
= NULL
;
246 char *zoneName
= (char *)NULL
;
247 char cbuf
[MAX_PKG_PARAM_LENGTH
];
248 char cmdbin
[PATH_MAX
];
249 char p_pkginfo
[PATH_MAX
];
250 char p_pkgmap
[PATH_MAX
];
251 char param
[MAX_PKG_PARAM_LENGTH
];
252 char script
[PATH_MAX
];
253 char altscript
[PATH_MAX
];
256 int disableAttributes
= 0;
258 int init_install
= 0;
260 int live_continue
= 0;
266 int saveSpoolInstall
= 0;
267 boolean_t cont_file_read
;
268 struct cl_attr
**pclass
= NULL
;
269 struct cl_attr
**mergd_pclass
= NULL
;
270 struct pkginfo
*prvinfo
;
271 struct sigaction nact
;
272 struct sigaction oact
;
274 struct statvfs64 svfsb
;
276 PKGserver pkgserver
= NULL
;
278 /* reset contents of all default paths */
280 (void) memset(path
, '\0', sizeof (path
));
281 (void) memset(cmdbin
, '\0', sizeof (cmdbin
));
282 (void) memset(script
, '\0', sizeof (script
));
283 (void) memset(cbuf
, '\0', sizeof (cbuf
));
284 (void) memset(param
, '\0', sizeof (param
));
286 /* initialize locale environment */
288 (void) setlocale(LC_ALL
, "");
289 (void) textdomain(TEXT_DOMAIN
);
291 /* initialize program name */
293 prog_full_name
= argv
[0];
294 (void) set_prog_name(argv
[0]);
296 /* tell spmi zones interface how to access package output functions */
298 z_set_output_functions(echo
, echoDebug
, progerr
);
300 /* exit if not root */
303 progerr(ERR_NOT_ROOT
, get_prog_name());
309 * determine how pkgmap() deals with environment variables:
310 * - MAPALL - resolve all variables
311 * - MAPBUILD - map only build variables
312 * - MAPINSTALL - map only install variables
313 * - MAPNONE - map no variables
316 setmapmode(MAPINSTALL
);
322 /* initially no source "device" */
326 /* reset npkgs (used as pkg remaining count in quit.c) */
330 /* Read PKG_INSTALL_ROOT from the environment, if it's there. */
332 if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
333 progerr(ERR_ROOT_SET
);
337 pkgserversetmode(DEFAULTMODE
);
339 /* parse command line options */
341 while ((c
= getopt(argc
, argv
,
342 "?Aa:B:b:Cc:D:d:eFf:GhIiMm:N:noO:p:R:r:StV:vyz")) != EOF
) {
347 * Same as pkgadd: This disables attribute checking.
348 * It speeds up installation a little bit.
355 * Same as pkgadd: Define an installation administration
356 * file, admin, to be used in place of the default
357 * administration file. The token none overrides the use
358 * of any admin file, and thus forces interaction with the
359 * user. Unless a full path name is given, pkgadd first
360 * looks in the current working directory for the
361 * administration file. If the specified administration
362 * file is not in the current working directory, pkgadd
363 * looks in the /var/sadm/install/admin directory for the
364 * administration file.
367 admnfile
= flex_device(optarg
, 0);
371 * Same as pkgadd: control block size given to
372 * pkginstall - block size used in read()/write() loop;
373 * default is st_blksize from stat() of source file.
376 rw_block_size
= optarg
;
380 * Same as pkgadd: location where executables needed
381 * by procedure scripts can be found
382 * default is /usr/sadm/install/bin.
385 if (!path_valid(optarg
)) {
386 progerr(ERR_PATH
, optarg
);
389 if (isdir(optarg
) != 0) {
390 char *p
= strerror(errno
);
391 progerr(ERR_CANNOT_USE_DIR
, optarg
, p
);
394 (void) strlcpy(cmdbin
, optarg
, sizeof (cmdbin
));
398 * Same as pkgadd: This disables checksum tests on
399 * the source files. It speeds up installation a little bit.
402 (void) checksum_off();
406 * Same as pkgadd: This allows designation of a
407 * continuation file. It is the same format as a dryrun file
408 * but it is used to take up where the dryrun left off.
413 set_dr_info(DR_TYPE
, INSTALL_TYPE
);
414 init_contfile(pkgcontsrc
);
418 * Same as pkgadd: This allows designation of a
419 * dryrun file. This pkgadd will create dryrun files
420 * in the directory provided.
425 set_dr_info(DR_TYPE
, INSTALL_TYPE
);
429 * Same as pkgadd: Install or copy a package from
430 * device. device can be a full path name to a directory
431 * or the identifiers for tape, floppy disk, or removable
432 * disk - for example, /var/tmp or /floppy/floppy_name.
433 * It can also be a device alias - for example,
434 * /floppy/floppy0, or a datastream created by pkgtrans.
437 device
= flex_device(optarg
, 1);
441 * Different from pkgadd: disable the 32 char name
445 (void) set_ABI_namelngth();
449 * Different from pkgadd: specify file system type for
450 * the package device. Must be used with -m.
453 pkgdev
.fstyp
= optarg
;
457 * Same as pkgadd: install package in global zone only.
460 globalZoneOnly
= B_TRUE
;
464 * Same as pkgadd: Enable hollow package support. When
465 * specified, for any package that has SUNW_PKG_HOLLOW=true:
466 * Do not calculate and verify package size against target.
467 * Do not run any package procedure or class action scripts.
468 * Do not create any target directories.
469 * Do not perform any script locking.
470 * Do not install any components of any package.
471 * Do not output any status or database update messages.
474 set_depend_pkginfo_DB(B_TRUE
);
478 * Same as pkgadd: Informs scripts that this is
479 * an initial install by setting the environment parameter
480 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
481 * they see fit, safe in the knowledge that the target
482 * filesystem is tabula rasa.
489 * Different from pkgadd: use by pkgask.
493 quitSetPkgask(B_TRUE
);
497 * Same as pkgadd: Instruct pkgadd not to use the
498 * $root_path/etc/vfstab file for determining the client's
499 * mount points. This option assumes the mount points are
500 * correct on the server and it behaves consistently with
501 * Solaris 2.5 and earlier releases.
508 * Different from pkgadd: specify device to use for package
512 pkgdev
.mount
= optarg
;
518 * Different from pkgadd: specify program name to use
522 (void) set_prog_name(optarg
);
526 * Same as pkgadd: installation occurs in
527 * non-interactive mode. Suppress output of the list of
528 * installed files. The default mode is interactive.
532 (void) echoSetFlag(B_FALSE
);
536 * Almost same as pkgadd: the -O option allows the behavior
537 * of the package tools to be modified. Recognized options:
539 * ---> enable debugging output
541 * ---> perform a "pre installation" check of the specified
542 * ---> package - suppress all regular output and cause a
543 * ---> series of one or more "name=value" pair format lines
544 * ---> to be output that describes the "installability" of
545 * ---> the specified package
546 * -> enable-hollow-package-support
547 * --> Enable hollow package support. When specified, for any
548 * --> package that has SUNW_PKG_HOLLOW=true:
549 * --> Do not calculate and verify package size against target
550 * --> Do not run any package procedure or class action scripts
551 * --> Do not create or remove any target directories
552 * --> Do not perform any script locking
553 * --> Do not install or uninstall any components of any package
554 * --> Do not output any status or database update messages
557 for (p
= strtok(optarg
, ","); p
!= (char *)NULL
;
558 p
= strtok(NULL
, ",")) {
560 /* process debug option */
562 if (strcmp(p
, "debug") == 0) {
563 /* set debug flag/enable debug output */
564 if (debugFlag
== B_TRUE
) {
565 smlSetVerbose(B_TRUE
);
568 (void) echoDebugSetFlag(debugFlag
);
570 /* debug info on arguments to pkgadd */
571 for (n
= 0; n
< argc
&& argv
[n
]; n
++) {
572 echoDebug(DBG_ARG
, n
, argv
[n
]);
578 /* process enable-hollow-package-support opt */
581 "enable-hollow-package-support") == 0) {
582 set_depend_pkginfo_DB(B_TRUE
);
586 /* process preinstallcheck option */
588 if (strcmp(p
, "preinstallcheck") == 0) {
589 preinstallCheck
= B_TRUE
;
590 nointeract
++; /* -n */
591 suppressCopyright
++; /* -S */
592 quitSetSilentExit(B_TRUE
);
596 /* process addzonename option */
598 if (strcmp(p
, "addzonename") == 0) {
600 * set zone name to add to messages;
601 * first look in the current environment
602 * and use the default package zone name
603 * if it is set; otherwise, use the name
604 * of the current zone
607 getenv(PKG_ZONENAME_VARIABLE
);
609 if ((zoneName
== (char *)NULL
) ||
610 (*zoneName
== '\0')) {
611 zoneName
= z_get_zonename();
614 if (zoneName
!= (char *)NULL
) {
615 if (*zoneName
!= '\0') {
619 zoneName
= (char *)NULL
;
625 /* process parent-zone-name option */
627 if (strncmp(p
, PARENTZONENAME
,
628 PARENTZONENAME_LEN
) == 0) {
629 parentZoneName
= p
+PARENTZONENAME_LEN
;
633 /* process parent-zone-type option */
635 if (strncmp(p
, PARENTZONETYPE
,
636 PARENTZONETYPE_LEN
) == 0) {
637 parentZoneType
= p
+PARENTZONETYPE_LEN
;
641 if (strncmp(p
, PKGSERV_MODE
,
642 PKGSERV_MODE_LEN
) == 0) {
643 pkgserversetmode(pkgparsemode(p
+
648 /* option not recognized - issue warning */
650 progerr(ERR_INVALID_O_OPTION
, p
);
657 * Different from pkgadd: This is an old non-ABI package
664 * Different from pkgadd: specify number of parts to package.
667 dparts
= ds_getinfo(optarg
);
671 * Same as pkgadd: Define the full path name of a
672 * directory to use as the root_path. All files,
673 * including package system information files, are
674 * relocated to a directory tree starting in the specified
675 * root_path. The root_path may be specified when
676 * installing to a client from a server (for example,
677 * /export/root/client1).
680 if (!set_inst_root(optarg
)) {
681 progerr(ERR_ROOT_CMD
);
687 * Same as pkgadd: Identify a file or directory which
688 * contains output from a previous pkgask(1M)
689 * session. This file supplies the interaction responses
690 * that would be requested by the package in interactive
691 * mode. response must be a full pathname.
694 respfile
= flex_device(optarg
, 2);
698 * Same as pkgadd: suppress copyright notice being
699 * output during installation.
706 * Same as pkgadd: disable save spool area creation;
707 * do not spool any partial package contents, that is,
708 * suppress the creation and population of the package save
709 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
712 disable_spool_create();
716 * Same as pkgadd: Specify an alternative fs_file to map
717 * the client's file systems. For example, used in
718 * situations where the $root_path/etc/vfstab file is
719 * non-existent or unreliable. Informs the pkginstall
720 * portion to mount up a client filesystem based upon the
721 * supplied vfstab-like file of stable format.
724 vfstab_file
= flex_device(optarg
, 2);
729 * Same as pkgadd: Trace all of the scripts that get
730 * executed by pkgadd, located in the pkginst/install
731 * directory. This option is used for debugging the
732 * procedural and non-procedural scripts
739 * Different from pkgadd: process this package using
740 * old non-ABI symlinks
743 set_nonABI_symlinks();
747 * Same as pkgadd: perform fresh install from
748 * package save spool area. When set, the package contents
749 * are installed from the package spool save area instead
750 * of from the package root area, so that the original
751 * source packages are not required to install the
752 * package. If the -h option is also specified and the
753 * package is hollow, then this option is ignored. When -z
755 * - Editable files are installed from the package instance
757 * - Volatile files are installed from the package instance
759 * - Executable and data files are installed from the final
760 * installed location as specified in the pkgmap file.
761 * - Installation scripts are run from the package spool
769 * unrecognized option
775 * Although usage() calls a noreturn function,
776 * needed to add return (1); so that main() would
777 * pass compilation checks. The statement below
778 * should never be executed.
785 * ********************************************************************
786 * validate command line options
787 * ********************************************************************
790 /* set "debug echo" flag according to setting of "-O debug" option */
792 (void) echoDebugSetFlag(debugFlag
);
793 (void) log_set_verbose(debugFlag
);
795 /* output entry debugging information */
797 if (z_running_in_global_zone()) {
798 echoDebug(DBG_ENTRY_IN_GZ
, prog_full_name
);
800 echoDebug(DBG_ENTRY_IN_LZ
, prog_full_name
, getzoneid(),
804 if (in_continue_mode() && !in_dryrun_mode()) {
805 progerr(ERR_LIVE_CONTINUE_NOT_SUPPORTED
);
810 /* pkgask requires a response file */
812 if (askflag
&& (respfile
== NULL
)) {
817 /* if device specified, set appropriate device in pkgdev */
821 pkgdev
.bdevice
= device
;
823 pkgdev
.cdevice
= device
;
827 /* if file system type specified, must have a device to mount */
829 if (pkgdev
.fstyp
&& !pkgdev
.mount
) {
830 progerr(ERR_F_REQUIRES_M
);
835 /* BEGIN DATA GATHERING PHASE */
838 * Get the mount table info and store internally.
840 cont_file_read
= B_FALSE
;
841 if (in_continue_mode()) {
843 cont_file_read
= read_continuation(&error
);
848 if (!in_dryrun_mode()) {
852 /* Read the mount table if not done in continuation mode */
853 if (!cont_file_read
) {
854 if (get_mntinfo(map_client
, vfstab_file
)) {
861 * This function defines the standard /var/... directories used later
862 * to construct the paths to the various databases.
865 set_PKGpaths(get_inst_root());
868 * If this is being installed on a client whose /var filesystem is
869 * mounted in some odd way, remap the administrative paths to the
870 * real filesystem. This could be avoided by simply mounting up the
871 * client now; but we aren't yet to the point in the process where
872 * modification of the filesystem is permitted.
874 if (is_an_inst_root()) {
877 fsys_value
= fsys(get_PKGLOC());
878 if (use_srvr_map_n(fsys_value
))
879 set_PKGLOC(server_map(get_PKGLOC(), fsys_value
));
881 fsys_value
= fsys(get_PKGADM());
882 if (use_srvr_map_n(fsys_value
))
883 set_PKGADM(server_map(get_PKGADM(), fsys_value
));
887 * Initialize pkginfo PKGSAV entry, just in case we dryrun to
890 set_infoloc(get_PKGLOC());
892 /* pull off directory and package name from end of command line */
894 switch (argc
-optind
) {
895 case 0: /* missing directory and package instance */
896 progerr(ERR_MISSING_DIR_AND_PKG
);
899 case 1: /* missing package instance */
900 progerr(ERR_MISSING_PKG_INSTANCE
);
903 case 2: /* just right! */
904 pkgdev
.dirname
= argv
[optind
++];
905 srcinst
= argv
[optind
++];
907 default: /* too many args! */
908 progerr(ERR_TOO_MANY_CMD_ARGS
);
913 (void) pkgparam(NULL
, NULL
); /* close up prior pkg file if needed */
916 * Initialize installation admin parameters by reading
920 if (!askflag
&& !live_continue
) {
921 echoDebug(DBG_PKGINSTALL_ADMINFILE
, admnfile
? admnfile
: "");
922 setadminFile(admnfile
);
926 * about to perform first operation that could be modified by the
927 * preinstall check option - if preinstall check is selected (that is,
928 * only gathering dependencies), then output a debug message to
929 * indicate that the check is beginning. Also turn echo() output
930 * off and set various other flags.
933 if (preinstallCheck
== B_TRUE
) {
934 (void) echoSetFlag(B_FALSE
);
935 echoDebug(DBG_PKGINSTALL_PREINSCHK
,
936 pkginst
? pkginst
: (srcinst
? srcinst
: ""),
937 zoneName
? zoneName
: "global");
938 cksetPreinstallCheck(B_TRUE
);
939 cksetZoneName(zoneName
);
940 /* inform quit that the install has started */
941 quitSetInstallStarted(B_TRUE
);
945 * validate the "rscriptalt" admin file setting
946 * The rscriptalt admin file parameter may be set to either
947 * RSCRIPTALT_ROOT or RSCRIPTALT_NOACCESS:
948 * --> If rscriptalt is not set, or is set to RSCRIPTALT_NOACCESS,
949 * --> or is set to any value OTHER than RSCRIPTALT_ROOT, then
950 * --> assume that the parameter is set to RSCRIPTALT_NOACCESS
951 * If rscriptalt is set to RSCRIPTALT_ROOT, then run request scripts
952 * as the "root" user if user "install" is not defined.
953 * Otherwise, assume rscriptalt is set to RSCRIPTALT_NOACCESS, and run
954 * request scripts as the "alternative" user if user "install" is not
955 * defined, as appropriate for the current setting of the NONABI_SCRIPTS
956 * environment variable.
959 if (ADMSET(RSCRIPTALT
)) {
961 echoDebug(DBG_PKGINSTALL_RSCRIPT_SET_TO
, RSCRIPTALT_KEYWORD
, p
);
962 if (strcasecmp(p
, RSCRIPTALT_ROOT
) == 0) {
963 /* rscriptalt=root */
964 run_request_as_root
= B_TRUE
;
965 } else if (strcasecmp(p
, RSCRIPTALT_NOACCESS
) == 0) {
966 /* rscriptalt=noaccess */
967 run_request_as_root
= B_FALSE
;
970 logerr(WRN_RSCRIPTALT_BAD
, RSCRIPTALT_KEYWORD
, p
,
971 RSCRIPTALT_ROOT
, RSCRIPTALT_NOACCESS
);
972 logerr(WRN_RSCRIPTALT_USING
, RSCRIPTALT_KEYWORD
,
973 RSCRIPTALT_NOACCESS
);
974 run_request_as_root
= B_FALSE
;
977 /* rscriptalt not set - assume rscriptalt=noaccess */
978 echoDebug(DBG_PKGINSTALL_RSCRIPT_NOT_SET
, RSCRIPTALT_KEYWORD
);
979 run_request_as_root
= B_FALSE
;
982 echoDebug(DBG_PKGINSTALL_RSCRIPT_IS_ROOT
, run_request_as_root
);
985 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
988 /* hold SIGINT/SIGHUP interrupts */
990 (void) sighold(SIGHUP
);
991 (void) sighold(SIGINT
);
993 /* connect quit.c:trap() to SIGINT */
995 nact
.sa_handler
= quitGetTrapHandler();
996 nact
.sa_flags
= SA_RESTART
;
997 (void) sigemptyset(&nact
.sa_mask
);
999 (void) sigaction(SIGINT
, &nact
, &oact
);
1001 /* connect quit.c:trap() to SIGHUP */
1003 nact
.sa_handler
= quitGetTrapHandler();
1004 nact
.sa_flags
= SA_RESTART
;
1005 (void) sigemptyset(&nact
.sa_mask
);
1007 (void) sigaction(SIGHUP
, &nact
, &oact
);
1009 /* release hold on signals */
1011 (void) sigrelse(SIGHUP
);
1012 (void) sigrelse(SIGINT
);
1015 * create required /var... directories if they do not exist;
1016 * this function will call quit(99) if any required path cannot
1025 * create path to temporary directory "installXXXXXX" - if TMPDIR
1026 * environment variable is set, create the directory in $TMPDIR;
1027 * otherwise, create the directory in P_tmpdir.
1030 pt
= getenv("TMPDIR");
1031 (void) snprintf(tmpdir
, sizeof (tmpdir
), "%s/installXXXXXX",
1032 ((pt
!= (char *)NULL
) && (*pt
!= '\0')) ? pt
: P_tmpdir
);
1034 echoDebug(DBG_PKGINSTALL_TMPDIR
, tmpdir
);
1036 if ((mktemp(tmpdir
) == NULL
) || mkdir(tmpdir
, 0771)) {
1037 progerr(ERR_MKDIR
, tmpdir
);
1043 * if the package device is a file containing a package stream,
1044 * unpack the stream into a temporary directory
1047 if ((isdir(pkgdev
.dirname
) != 0) &&
1048 (pkgdev
.cdevice
== (char *)NULL
) &&
1049 (pkgdev
.bdevice
== (char *)NULL
) &&
1050 (isfile((char *)NULL
, pkgdev
.dirname
) == 0)) {
1052 char *idsName
= (char *)NULL
;
1054 char *device
= pkgdev
.dirname
;
1057 echoDebug(DBG_PKGINSTALL_DS_ISFILE
, pkgdev
.dirname
);
1060 * validate the package source device - return pkgdev info that
1061 * describes the package source device.
1064 if (devtype(device
, &pkgdev
)) {
1065 progerr(ERR_BAD_DEVICE
, device
);
1070 /* generate the list of packages to verify */
1072 pkgnames
[0] = srcinst
;
1073 pkgnames
[1] = (char *)NULL
;
1075 b
= open_package_datastream(1, pkgnames
, (char *)NULL
,
1076 pkgdev
.dirname
, (int *)NULL
, &idsName
, tmpdir
, &pkgdev
,
1080 progerr(ERR_CANNOT_OPEN_PKG_STREAM
,
1081 pkgdev
.dirname
? pkgdev
.dirname
: "?");
1086 /* make sure temporary directory is removed on exit */
1088 quitSetDstreamTmpdir(pkgdev
.dirname
);
1090 /* unpack the package instance from the data stream */
1092 b
= unpack_package_from_stream(idsName
, srcinst
,
1095 progerr(ERR_CANNOT_UNPACK_PKGSTRM
,
1096 srcinst
? srcinst
: "?",
1097 idsName
? idsName
: "?",
1098 pkgdev
.dirname
? pkgdev
.dirname
: "?");
1103 /* close the datastream - no longer needed */
1105 echoDebug(DBG_CLOSING_STREAM
, idsName
, pkgdev
.dirname
);
1109 if (snprintf(instdir
, PATH_MAX
, "%s/%s", pkgdev
.dirname
, srcinst
)
1111 progerr(ERR_SNPRINTF
, instdir
);
1116 zoneName
= getenv(PKG_ZONENAME_VARIABLE
);
1119 * If the environment has a CLIENT_BASEDIR, that takes precedence
1120 * over anything we will construct. We need to save it here because
1121 * in three lines, the current environment goes away.
1123 (void) set_env_cbdir(); /* copy over environ */
1128 * current environment has been read; clear environment out
1129 * so putparam() can be used to populate the new environment
1130 * to be passed to any executables/scripts.
1135 /* write parent condition information to environment */
1137 putConditionInfo(parentZoneName
, parentZoneType
);
1142 putparam("PKG_INIT_INSTALL", "TRUE");
1145 if (is_an_inst_root()) {
1146 export_client_env(get_inst_root());
1149 if (zoneName
!= (char *)NULL
) {
1150 putparam(PKG_ZONENAME_VARIABLE
, zoneName
);
1153 putparam("INST_DATADIR", pkgdev
.dirname
);
1155 if (non_abi_scripts
) {
1156 putparam("NONABI_SCRIPTS", "TRUE");
1159 if (nonABI_symlinks()) {
1160 putparam("PKG_NONABI_SYMLINKS", "TRUE");
1163 if (get_ABI_namelngth()) {
1164 putparam("PKG_ABI_NAMELENGTH", "TRUE");
1167 /* establish path and oambase */
1169 if (cmdbin
[0] == '\0') {
1170 (void) strlcpy(cmdbin
, PKGBIN
, sizeof (cmdbin
));
1173 (void) snprintf(path
, sizeof (path
), "%s:%s", DEFPATH
, cmdbin
);
1175 putparam("PATH", path
);
1177 putparam("OAMBASE", OAMBASE
);
1179 (void) snprintf(p_pkginfo
, sizeof (p_pkginfo
),
1180 "%s/%s", instdir
, PKGINFO
);
1181 (void) snprintf(p_pkgmap
, sizeof (p_pkgmap
),
1182 "%s/%s", instdir
, PKGMAP
);
1184 /* Read the environment (from pkginfo or '-e') ... */
1185 abi_nm_ptr
= getenv("PKG_ABI_NAMELENGTH");
1187 /* Disable the 32 char name limit extension */
1188 if (abi_nm_ptr
&& strncasecmp(abi_nm_ptr
, "TRUE", 4) == 0) {
1189 (void) set_ABI_namelngth();
1193 * This tests the pkginfo and pkgmap files for validity and
1194 * puts all delivered pkginfo variables (except for PATH) into
1195 * our environment. This is where a delivered pkginfo BASEDIR
1196 * would come from. See set_basedirs() below.
1199 if (pkgenv(srcinst
, p_pkginfo
, p_pkgmap
)) {
1204 echo("\n%s(%s) %s", pkgname
, pkgarch
, pkgvers
);
1207 * If this script was invoked by 'pkgask', just
1208 * execute request script and quit (do_pkgask()).
1212 do_pkgask(run_request_as_root
);
1215 /* validate package contents file */
1217 if (vcfile() == 0) {
1221 /* if not in dryrun mode aquire packaging lock */
1223 if (!in_dryrun_mode()) {
1224 /* acquire the package lock - at install initialization */
1225 if (!lockinst(get_prog_name(), srcinst
, "install-initial")) {
1232 * Now do all the various setups based on ABI compliance
1235 /* Read the environment (from pkginfo or '-o') ... */
1236 abi_comp_ptr
= getenv("NONABI_SCRIPTS");
1238 /* Read the environment (from pkginfo or '-y') ... */
1239 abi_sym_ptr
= getenv("PKG_NONABI_SYMLINKS");
1241 /* bug id 4244631, not ABI compliant */
1242 if (abi_comp_ptr
&& strncasecmp(abi_comp_ptr
, "TRUE", 4) == 0) {
1243 script_in
= PROC_XSTDIN
;
1244 non_abi_scripts
= 1;
1247 /* Set symlinks to be processed the old way */
1248 if (abi_sym_ptr
&& strncasecmp(abi_sym_ptr
, "TRUE", 4) == 0) {
1249 set_nonABI_symlinks();
1253 * At this point, script_in, non_abi_scripts & the environment are
1254 * all set correctly for the ABI status of the package.
1257 if (pt
= getenv("MAXINST")) {
1262 * See if were are installing a package that only wants to update
1263 * the database or only install files associated with CAS's. We
1264 * only check the PKG_HOLLOW_VARIABLE variable if told to do so by
1268 if (is_depend_pkginfo_DB()) {
1269 pt
= getenv(PKG_HOLLOW_VARIABLE
);
1270 if ((pt
!= NULL
) && (strncasecmp(pt
, "true", 4) == 0)) {
1271 echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED
);
1272 if (disableAttributes
) {
1273 disable_attribute_check();
1277 * this is a hollow package and hollow package support
1278 * is enabled -- override admin settings to suppress
1279 * checks that do not make sense since no scripts will
1280 * be executed and no files will be installed.
1283 setadminSetting("conflict", "nocheck");
1284 setadminSetting("setuid", "nocheck");
1285 setadminSetting("action", "nocheck");
1286 setadminSetting("partial", "nocheck");
1287 setadminSetting("space", "nocheck");
1288 setadminSetting("authentication", "nocheck");
1290 echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED
);
1291 set_depend_pkginfo_DB(B_FALSE
);
1296 * if performing a fresh install to a non-global zone, and doing
1297 * more than just updating the package database (that is, the
1298 * package to install is NOT "hollow"), then set the global flag
1299 * that directs installation is from partially spooled packages
1300 * (that is, packages installed in the global zone).
1303 if (saveSpoolInstall
&& (!is_depend_pkginfo_DB())) {
1306 saveSpoolInstall
= 0;
1310 * verify that we are not trying to install an
1311 * INTONLY package with no interaction
1314 if (pt
= getenv("INTONLY")) {
1315 if (askflag
|| nointeract
) {
1316 progerr(ERR_INTONLY
, pkgabrv
? pkgabrv
: "?");
1322 if (!suppressCopyright
&& !pkgdev
.cdevice
) {
1327 * inspect the system to determine if any instances of the
1328 * package being installed already exist on the system
1331 prvinfo
= (struct pkginfo
*)calloc(MALSIZ
, sizeof (struct pkginfo
));
1332 if (prvinfo
== NULL
) {
1333 progerr(ERR_MEMORY
, errno
);
1339 if (pkginfo(&prvinfo
[npkgs
], pkgwild
, NULL
, NULL
)) {
1340 if ((errno
== ESRCH
) || (errno
== ENOENT
)) {
1343 progerr(ERR_SYSINFO
, errno
);
1347 if ((++npkgs
% MALSIZ
) == 0) {
1348 prvinfo
= (struct pkginfo
*)realloc(prvinfo
,
1349 (npkgs
+MALSIZ
) * sizeof (struct pkginfo
));
1350 if (prvinfo
== NULL
) {
1351 progerr(ERR_MEMORY
, errno
);
1359 * Determine the correct package instance based on how many packages are
1360 * already installed. If there are none (npkgs == 0), getinst() just
1361 * returns the package abbreviation. Otherwise, getinst() interacts with
1362 * the user (or reads the admin file) to determine if an instance which
1363 * is already installed should be overwritten, or possibly install a new
1364 * instance of this package
1367 pkginst
= getinst(&update
, prvinfo
, npkgs
, preinstallCheck
);
1369 /* set "update flag" if updating an existing instance of this package */
1376 * Some pkgs (SUNWcsr) already spooled to the zone, check the
1377 * value of UPDATE in their postinstall script. After a pkg
1378 * has been patched UPDATE exists statically in the pkginfo
1379 * file and this value must be reset when installing a zone.
1382 if (saveSpoolInstall
!= 0 && !isUpdate()) {
1383 putparam("UPDATE", "");
1386 /* inform quit() if updating existing or installing new instance */
1388 quitSetUpdatingExisting(update
? B_TRUE
: B_FALSE
);
1391 (void) set_respfile(respfile
, pkginst
, RESP_RO
);
1394 (void) snprintf(pkgloc
, sizeof (pkgloc
),
1395 "%s/%s", get_PKGLOC(), pkginst
);
1397 (void) snprintf(pkgbin
, sizeof (pkgbin
),
1398 "%s/install", pkgloc
);
1400 (void) snprintf(pkgsav
, sizeof (pkgsav
),
1403 if (snprintf(saveSpoolInstallDir
, PATH_MAX
, "%s/pspool/%s", pkgsav
,
1405 progerr(ERR_SNPRINTF
, saveSpoolInstallDir
);
1410 (void) snprintf(ilockfile
, sizeof (ilockfile
),
1411 "%s/!I-Lock!", pkgloc
);
1412 (void) snprintf(rlockfile
, sizeof (rlockfile
),
1413 "%s/!R-Lock!", pkgloc
);
1414 (void) snprintf(savlog
, sizeof (savlog
),
1415 "%s/logs/%s", get_PKGADM(), pkginst
);
1417 putparam("PKGINST", pkginst
);
1418 putparam("PKGSAV", pkgsav
);
1421 * Be sure request script has access to PKG_INSTALL_ROOT if there is
1428 putparam("PKG_NO_UNIFIED", "TRUE");
1432 * This maps the client filesystems into the server's space.
1435 if (map_client
&& !mount_client()) {
1436 logerr(MSG_MANMOUNT
);
1440 * If this is an UPDATE then either this is exactly the same version
1441 * and architecture of an installed package or a different package is
1442 * intended to entirely replace an installed package of the same name
1443 * with a different VERSION or ARCH string.
1444 * Don't merge any databases if only gathering dependencies.
1447 if ((preinstallCheck
== B_FALSE
) && (update
)) {
1449 * If this version and architecture is already installed,
1450 * merge the installed and installing parameters and inform
1451 * all procedure scripts by defining UPDATE in the
1457 * If it's the same ARCH and VERSION, then a merge
1458 * and copy operation is necessary.
1461 if (n
= merg_pkginfos(pclass
, &mergd_pclass
)) {
1466 if (n
= cp_pkgdirs()) {
1473 * If it's a different ARCH and/or VERSION then this
1474 * is an "instance=overwrite" situation. The
1475 * installed base needs to be confirmed and the
1476 * package directories renamed.
1479 if (n
= ck_instbase()) {
1484 if (n
= mv_pkgdirs()) {
1490 putparam("UPDATE", "yes");
1494 if (in_dryrun_mode()) {
1495 set_dryrun_dir_loc();
1498 if (preinstallCheck
== B_FALSE
) {
1500 * Determine if the package has been partially installed on or
1501 * removed from this system.
1503 ck_w_dryrun(ckpartial
, PARTIAL
);
1506 * make sure current runlevel is appropriate
1508 ck_w_dryrun(ckrunlevel
, RUNLEVEL
);
1513 * Just gathering dependencies - determine if the package has
1514 * been partially installed on or removed from this system and
1515 * output information to stdout
1518 (void) fprintf(stdout
, "ckpartialinstall=%d\n", r
== 8 ? 1 : 0);
1519 (void) fprintf(stdout
, "ckpartialremove=%d\n", r
== 9 ? 1 : 0);
1522 * make sure current runlevel is appropriate
1525 (void) fprintf(stdout
, "ckrunlevel=%d\n", r
);
1528 if (pkgdev
.cdevice
) {
1529 /* get first volume which contains info files */
1531 if (!suppressCopyright
) {
1536 /* update the lock - at the request script */
1541 * If no response file has been provided, initialize response file by
1542 * executing any request script provided by this package. Initialize
1543 * the response file if not gathering dependencies only.
1546 if ((!rdonly_respfile()) && (preinstallCheck
== B_FALSE
)) {
1547 (void) snprintf(path
, sizeof (path
),
1548 "%s/%s", instdir
, REQUEST_FILE
);
1549 n
= reqexec(update
, path
, non_abi_scripts
,
1550 run_request_as_root
);
1551 if (in_dryrun_mode()) {
1552 set_dr_info(REQUESTEXITCODE
, n
);
1555 ckreturn(n
, ERR_REQUEST
);
1559 * Look for all parameters in response file which begin with a
1560 * capital letter, and place them in the environment.
1563 if ((is_a_respfile()) && (preinstallCheck
== B_FALSE
)) {
1564 if (n
= merg_respfile()) {
1571 * Run a checkinstall script if one is provided by the package.
1572 * Don't execute checkinstall script if we are only updating the DB.
1573 * Don't execute checkinstall script if only gathering dependencies.
1576 /* update the lock - at the checkinstall script */
1577 lockupd("checkinstall");
1579 /* Execute checkinstall script if one is provided. */
1580 (void) snprintf(script
, sizeof (script
), "%s/install/checkinstall",
1582 if (access(script
, F_OK
) != 0) {
1583 /* no script present */
1584 echoDebug(DBG_PKGINSTALL_COC_NONE
, pkginst
, script
,
1585 zoneName
? zoneName
: "global");
1586 } else if (is_depend_pkginfo_DB()) {
1587 /* updating db only: skip checkinstall script */
1588 echoDebug(DBG_PKGINSTALL_COC_DBUPD
, pkginst
, script
,
1589 zoneName
? zoneName
: "global");
1590 } else if (preinstallCheck
== B_TRUE
) {
1591 /* only gathering dependencies: skip checkinstall script */
1592 echoDebug(DBG_PKGINSTALL_COC_NODEL
, pkginst
, script
,
1593 zoneName
? zoneName
: "global");
1595 /* script present and ok to run: run the script */
1596 if (zoneName
== (char *)NULL
) {
1597 echo(MSG_PKGINSTALL_EXECOC_GZ
);
1598 echoDebug(DBG_PKGINSTALL_EXECOC_GZ
, pkginst
, script
);
1600 echo(MSG_PKGINSTALL_EXECOC_LZ
, zoneName
);
1601 echoDebug(DBG_PKGINSTALL_EXECOC_LZ
, pkginst
, script
,
1604 n
= chkexec(update
, script
);
1605 if (in_dryrun_mode()) {
1606 set_dr_info(CHECKEXITCODE
, n
);
1610 echo(WRN_CHKINSTALL
);
1612 } else if (n
== 7) {
1613 /* access returned error */
1614 progerr(ERR_CHKINSTALL_NOSCRIPT
, script
);
1615 ckreturn(4, ERR_CHKINSTALL
);
1617 ckreturn(n
, ERR_CHKINSTALL
);
1622 * Now that the internal data structures are initialized, we can
1623 * initialize the dryrun files (which may be the same files).
1627 init_dryrunfile(pkgdrtarg
);
1631 * Look for all parameters in response file which begin with a
1632 * capital letter, and place them in the environment.
1634 if (is_a_respfile()) {
1635 if (n
= merg_respfile()) {
1641 /* update the lock - doing analysis */
1643 lockupd("analysis");
1646 * Determine package base directory and client base directory
1647 * if appropriate. Then encapsulate them for future retrieval.
1649 if ((err
= set_basedirs(isreloc(instdir
), adm
.basedir
, pkginst
,
1650 nointeract
)) != 0) {
1656 * Create the base directory if specified.
1657 * Don't create if we are only updating the DB.
1658 * Don't create if only gathering dependencies.
1661 if (!is_depend_pkginfo_DB() &&
1662 !preinstallCheck
&& is_a_basedir()) {
1663 mkbasedir(!nointeract
, get_basedir());
1664 echo(MSG_BASE_USED
, get_basedir());
1668 * Store PKG_INSTALL_ROOT, BASEDIR & CLIENT_BASEDIR in our
1669 * environment for later use by procedure scripts.
1674 * the following two checks are done in the corresponding
1675 * ck() routine, but are repeated here to avoid re-processing
1676 * the database if we are administered to not include these
1679 if (ADM(setuid
, "nochange")) {
1680 nosetuid
++; /* Clear setuid/gid bits. */
1683 if (ADM(conflict
, "nochange")) {
1684 nocnflct
++; /* Don't install conflicting files. */
1688 * Get the filesystem space information for the filesystem on which
1689 * the "contents" file resides.
1692 svfsb
.f_bsize
= 8192;
1693 svfsb
.f_frsize
= 1024;
1695 if (statvfs64(get_PKGADM(), &svfsb
) == -1) {
1697 if (!access(get_PKGADM(), F_OK
)) {
1698 progerr(ERR_PKGINSTALL_STATVFS
, get_PKGADM(),
1700 logerr("(errno %d)", lerrno
);
1707 * Get the number of blocks used by the pkgmap, ocfile()
1708 * needs this to properly determine its space requirements.
1711 if (stat(p_pkgmap
, &statb
) == -1) {
1712 progerr(ERR_PKGINSTALL_STATOF
, p_pkgmap
, strerror(errno
));
1717 pkgmap_blks
= nblk(statb
.st_size
, svfsb
.f_bsize
, svfsb
.f_frsize
);
1720 * Merge information in memory with the "contents" file; this creates
1721 * a temporary version of the "contents" file. Note that in dryrun
1722 * mode, we still need to record the contents file data somewhere,
1723 * but we do it in the dryrun directory.
1726 if (in_dryrun_mode()) {
1727 if (n
= set_cfdir(pkgdrtarg
)) {
1732 if (n
= set_cfdir(NULL
)) {
1737 if (!ocfile(&pkgserver
, &cfTmpVfp
, pkgmap_blks
)) {
1743 * if cpio is being used, tell pkgdbmerg since attributes will
1744 * have to be check and repaired on all file and directories
1746 for (np
= cpio_names
; *np
!= NULL
; np
++) {
1747 (void) snprintf(path
, sizeof (path
),
1748 "%s/%s", instdir
, *np
);
1749 if (iscpio(path
, &is_comp_arch
)) {
1755 /* Establish the class list and the class attributes. */
1756 cl_sets(getenv("CLASSES"));
1757 find_CAS(I_ONLY
, pkgbin
, instdir
);
1759 if (vfpOpen(&pkgmapVfp
, p_pkgmap
, "r", VFP_NEEDNOW
) != 0) {
1760 progerr(ERR_PKGMAP
, p_pkgmap
);
1766 * This modifies the path list entries in memory to reflect
1767 * how they should look after the merg is complete
1770 nparts
= sortmap(&extlist
, pkgmapVfp
, pkgserver
, cfTmpVfp
, zoneName
);
1772 if ((n
= files_installed()) > 0) {
1774 echo(MSG_INST_MANY
, n
);
1776 echo(MSG_INST_ONE
, n
);
1781 * Check ulimit requirement (provided in pkginfo). The purpose of
1782 * this limit is to terminate pathological file growth resulting from
1783 * file edits in scripts. It does not apply to files in the pkgmap
1784 * and it does not apply to any database files manipulated by the
1785 * installation service.
1787 if (pt
= getenv("ULIMIT")) {
1788 if (assign_ulimit(pt
) == -1) {
1789 progerr(ERR_BADULIMIT
, pt
);
1793 putparam("PKG_ULIMIT", "TRUE");
1797 * If only gathering dependencies, check and output status of all
1798 * remaining dependencies and exit.
1801 if (preinstallCheck
== B_TRUE
) {
1802 /* update the lock file - final checking */
1804 lockupd("preinstallcheck");
1806 /* verify package information files are not corrupt */
1808 (void) fprintf(stdout
, "ckpkgfiles=%d\n", ckpkgfiles());
1810 /* verify package dependencies */
1812 (void) fprintf(stdout
, "ckdepend=%d\n", ckdepend());
1814 /* Check space requirements */
1816 (void) fprintf(stdout
, "ckspace=%d\n", ckspace());
1819 * Determine if any objects provided by this package conflict
1820 * with the files of previously installed packages.
1823 (void) fprintf(stdout
, "ckconflict=%d\n", ckconflct());
1826 * Determine if any objects provided by this package will be
1827 * installed with setuid or setgid enabled.
1830 (void) fprintf(stdout
, "cksetuid=%d\n", cksetuid());
1833 * Determine if any packaging scripts provided with this package
1834 * will execute as a priviledged user.
1837 (void) fprintf(stdout
, "ckpriv=%d\n", ckpriv());
1839 /* Verify neccessary package installation directories exist */
1841 (void) fprintf(stdout
, "ckpkgdirs=%d\n", ckpkgdirs());
1844 * ****** preinstall check done - exit ******
1847 echoDebug(DBG_PKGINSTALL_PREINSCHK_OK
);
1853 * Not gathering dependencies only, proceed to check dependencies
1854 * and continue with the package installation operation.
1858 * verify package information files are not corrupt
1860 ck_w_dryrun(ckpkgfiles
, PKGFILES
);
1863 * verify package dependencies
1865 ck_w_dryrun(ckdepend
, DEPEND
);
1868 * Check space requirements.
1870 ck_w_dryrun(ckspace
, SPACE
);
1873 * Determine if any objects provided by this package conflict with
1874 * the files of previously installed packages.
1876 ck_w_dryrun(ckconflct
, CONFLICT
);
1879 * Determine if any objects provided by this package will be
1880 * installed with setuid or setgid enabled.
1882 ck_w_dryrun(cksetuid
, SETUID
);
1885 * Determine if any packaging scripts provided with this package will
1886 * execute as a priviledged user.
1888 ck_w_dryrun(ckpriv
, PRIV
);
1891 * Verify neccessary package installation directories exist.
1893 ck_w_dryrun(ckpkgdirs
, PKGDIRS
);
1896 * If we have assumed that we were installing setuid or conflicting
1897 * files, and the user chose to do otherwise, we need to read in the
1898 * package map again and re-merg with the "contents" file
1902 nparts
= sortmap(&extlist
, pkgmapVfp
, pkgserver
,
1903 cfTmpVfp
, zoneName
);
1906 (void) vfpClose(&pkgmapVfp
);
1908 /* BEGIN INSTALLATION PHASE */
1909 if (in_dryrun_mode()) {
1910 echo(MSG_PKGINSTALL_DRYRUN
, pkgname
, pkginst
);
1911 } else if (zoneName
== (char *)NULL
) {
1912 echo(MSG_PKGINSTALL_INSIN_GZ
, pkgname
, pkginst
);
1914 echo(MSG_PKGINSTALL_INSIN_LZ
, pkgname
, pkginst
, zoneName
);
1917 /* inform quit that the install has started */
1919 quitSetInstallStarted(B_TRUE
);
1922 * This replaces the contents file with recently created temp version
1923 * which contains information about the objects being installed.
1924 * Under old lock protocol it closes both files and releases the
1925 * locks. Beginning in Solaris 2.7, this lock method should be
1929 n
= swapcfile(pkgserver
, &cfTmpVfp
, pkginst
, dbchg
);
1930 if (n
== RESULT_WRN
) {
1932 } else if (n
== RESULT_ERR
) {
1938 * Create install-specific lockfile to indicate start of
1939 * installation. This is really just an information file. If the
1940 * process dies, the initial lockfile (from lockinst(), is
1941 * relinquished by the kernel, but this one remains in support of the
1945 if (access(ilockfile
, F_OK
) == 0) {
1946 (void) remove(ilockfile
);
1949 if (open(ilockfile
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644) < 0) {
1950 progerr(ERR_LOCKFILE
, ilockfile
);
1955 (void) time(&clock
);
1958 * We do not want the time in locale in the pkginfo.
1959 * save the LC_TIME and set it to C. Reset it with saved one
1962 temp
= setlocale(LC_TIME
, NULL
);
1963 (void) setlocale(LC_TIME
, "C");
1965 /* LINTED warning: do not use cftime(); ... */
1966 (void) cftime(cbuf
, "%b %d \045Y \045H:\045M", &clock
);
1967 putparam("INSTDATE", qstrdup(cbuf
));
1968 (void) setlocale(LC_TIME
, temp
);
1971 * Store information about package being installed;
1972 * modify installation parameters as neccessary and
1973 * copy contents of 'install' directory into $pkgloc
1975 merginfo(mergd_pclass
, saveSpoolInstall
);
1977 /* If this was just a dryrun, then quit() will write out that file. */
1978 if (in_dryrun_mode()) {
1984 * Execute preinstall script, if one was provided with the
1985 * package. We check the package to avoid running an old
1986 * preinstall script if one was provided with a prior instance.
1987 * Don't execute preinstall script if we are only updating the DB.
1990 /* update the lock - at the preinstall altscript */
1991 lockupd("preinstall");
1993 /* preinstall script in the media (package source) */
1994 (void) snprintf(altscript
, sizeof (altscript
), "%s/install/preinstall",
1997 /* preinstall script in the pkgbin instead of media */
1998 (void) snprintf(script
, sizeof (script
), "%s/preinstall", pkgbin
);
2000 if (access(altscript
, F_OK
) != 0) {
2001 /* no script present */
2002 echoDebug(DBG_PKGINSTALL_POCALT_NONE
, pkginst
, altscript
,
2003 zoneName
? zoneName
: "global");
2004 } else if (access(script
, F_OK
) != 0) {
2005 /* no script present */
2006 echoDebug(DBG_PKGINSTALL_POC_NONE
, pkginst
, script
,
2007 zoneName
? zoneName
: "global");
2008 } else if (is_depend_pkginfo_DB()) {
2009 /* updating db only: skip preinstall script */
2010 echoDebug(DBG_PKGINSTALL_POC_DBUPD
, pkginst
, script
,
2011 zoneName
? zoneName
: "global");
2013 /* script present and ok to run: run the script */
2014 assert(preinstallCheck
== B_FALSE
);
2016 set_ulimit("preinstall", ERR_PREINSTALL
);
2017 if (zoneName
== (char *)NULL
) {
2018 echo(MSG_PKGINSTALL_EXEPOC_GZ
);
2019 echoDebug(DBG_PKGINSTALL_EXEPOC_GZ
, pkginst
, script
);
2021 echo(MSG_PKGINSTALL_EXEPOC_LZ
, zoneName
);
2022 echoDebug(DBG_PKGINSTALL_EXEPOC_LZ
, pkginst
, script
,
2025 putparam("PKG_PROC_script", "preinstall");
2027 ckreturn(pkgexecl(script_in
, PROC_STDOUT
,
2028 PROC_USER
, PROC_GRP
, SHELL
, "-x",
2029 script
, NULL
), ERR_PREINSTALL
);
2031 ckreturn(pkgexecl(script_in
, PROC_STDOUT
,
2032 PROC_USER
, PROC_GRP
, SHELL
, script
,
2033 NULL
), ERR_PREINSTALL
);
2037 (void) remove(script
); /* no longer needed. */
2041 * Check delivered package for a postinstall script while
2042 * we're still on volume 1.
2045 (void) snprintf(script
, sizeof (script
),
2046 "%s/install/postinstall", instdir
);
2047 if (access(script
, F_OK
) == 0) {
2048 (void) snprintf(script
, sizeof (script
),
2049 "%s/postinstall", pkgbin
);
2054 /* update the lock - at the install phase */
2059 * install package one part (volume) at a time
2063 while (part
<= nparts
) {
2064 if ((part
> 1) && pkgdev
.cdevice
) {
2068 instvol(extlist
, srcinst
, part
, nparts
,
2069 pkgserver
, &cfTmpVfp
, &updated
, zoneName
);
2071 if (part
++ >= nparts
) {
2076 z_destroyMountTable();
2079 * Now that all install class action scripts have been used, we
2080 * delete them from the package directory.
2084 if (globalZoneOnly
) {
2086 b
= pkgAddPackageToGzonlyList(pkginst
, get_inst_root());
2088 progerr(ERR_PKGINSTALL_GZONLY_ADD
, pkginst
);
2094 * Execute postinstall script, if any
2095 * Don't execute postinstall script if we are only updating the DB.
2098 echoDebug(DBG_PKGINSTALL_INSDONE
, is_depend_pkginfo_DB(),
2099 is_depend_pkginfo_DB(), saveSpoolInstall
,
2100 updated
? updated
: "",
2101 script
? script
: "",
2102 script
? access(script
, F_OK
) : -1);
2104 /* update the lock - at the postinstall script */
2105 lockupd("postinstall");
2107 if ((script
== (char *)NULL
) || (*script
== '\0')) {
2108 echoDebug(DBG_PKGINSTALL_POIS_NOPATH
, pkginst
,
2109 zoneName
? zoneName
: "global");
2110 } else if (access(script
, F_OK
) != 0) {
2111 echoDebug(DBG_PKGINSTALL_POIS_NONE
, pkginst
, script
,
2112 zoneName
? zoneName
: "global");
2113 } else if (is_depend_pkginfo_DB()) {
2114 echoDebug(DBG_PKGINSTALL_POIS_DBUPD
, pkginst
, script
,
2115 zoneName
? zoneName
: "global");
2116 } else if ((saveSpoolInstall
!= 0) && (updated
== (char *)NULL
)) {
2118 * fresh installing into non-global zone, no object was
2119 * updated (installed/verified in area), so do not run
2120 * the postinstall script.
2122 echoDebug(DBG_PKGINSTALL_POIS_NOUPDATING
,
2123 zoneName
? zoneName
: "global", pkginst
, script
);
2125 /* script present and ok to run: run the script */
2126 set_ulimit("postinstall", ERR_POSTINSTALL
);
2127 if (zoneName
== (char *)NULL
) {
2128 echo(MSG_PKGINSTALL_EXEPIC_GZ
);
2129 echoDebug(DBG_PKGINSTALL_EXEPIC_GZ
, pkginst
, script
);
2131 echo(MSG_PKGINSTALL_EXEPIC_LZ
, zoneName
);
2132 echoDebug(DBG_PKGINSTALL_EXEPIC_LZ
, pkginst
, script
,
2135 putparam("PKG_PROC_SCRIPT", "postinstall");
2136 putparam("TMPDIR", tmpdir
);
2138 ckreturn(pkgexecl(script_in
, PROC_STDOUT
,
2139 PROC_USER
, PROC_GRP
, SHELL
, "-x",
2140 script
, NULL
), ERR_POSTINSTALL
);
2142 ckreturn(pkgexecl(script_in
, PROC_STDOUT
,
2143 PROC_USER
, PROC_GRP
, SHELL
, script
,
2144 NULL
), ERR_POSTINSTALL
);
2148 (void) remove(script
); /* no longer needed */
2151 if (!warnflag
&& !failflag
) {
2152 (void) remove(rlockfile
);
2153 (void) remove(ilockfile
);
2154 (void) remove(savlog
);
2157 /* release the generic package lock */
2159 (void) unlockinst();
2161 pkgcloseserver(pkgserver
);
2164 /* LINTED: no return */
2168 * This function merges the environment data in the response file with the
2169 * current environment.
2175 char *resppath
= get_respfile();
2177 char param
[MAX_PKG_PARAM_LENGTH
], *value
;
2180 if ((fp
= fopen(resppath
, "r")) == NULL
) {
2181 progerr(ERR_RESPONSE
, resppath
);
2187 while (value
= fpkgparam(fp
, param
)) {
2188 if (!isupper(param
[0])) {
2193 if (rdonly(param
)) {
2194 progerr(ERR_RDONLY
, param
);
2200 * If this is an update, and the response file
2201 * specifies the BASEDIR, make sure it matches the
2202 * existing installation base. If it doesn't, we have
2205 if (update
&& strcmp("BASEDIR", param
) == 0) {
2206 locbasedir
= getenv("BASEDIR");
2207 if (locbasedir
&& strcmp(value
, locbasedir
) != 0) {
2209 /* Get srcinst down to a name. */
2210 if (dotptr
= strchr(srcinst
, '.'))
2212 progerr(ERR_NEWBD
, srcinst
,
2218 putparam(param
, value
);
2227 * This scans the installed pkginfo file for the current BASEDIR. If this
2228 * BASEDIR is different from the current BASEDIR, there will definitely be
2235 char param
[MAX_PKG_PARAM_LENGTH
], *value
;
2236 char pkginfo_path
[PATH_MAX
];
2239 /* Open the old pkginfo file. */
2240 (void) snprintf(pkginfo_path
, sizeof (pkginfo_path
),
2241 "%s/%s", pkgloc
, PKGINFO
);
2242 if ((fp
= fopen(pkginfo_path
, "r")) == NULL
) {
2243 progerr(ERR_PKGINFO
, pkginfo_path
);
2249 while (value
= fpkgparam(fp
, param
)) {
2250 if (strcmp("BASEDIR", param
) == 0) {
2251 if (adm
.basedir
&& *(adm
.basedir
) &&
2252 strchr("/$", *(adm
.basedir
))) {
2256 * Get srcinst down to a name.
2258 if (dotptr
= strchr(srcinst
, '.'))
2261 adm
.basedir
) != 0) {
2262 progerr(ERR_ADMBD
, srcinst
,
2263 value
, adm
.basedir
);
2267 } else if (ADM(basedir
, "ask"))
2269 * If it's going to ask later, let it know
2270 * that it *must* agree with the BASEDIR we
2273 adm
.basedir
= "update";
2275 putparam(param
, value
);
2287 * Since this is an overwrite of a different version of the package, none of
2288 * the old files should remain, so we rename them.
2294 * If we're not in dryrun mode and we can find an old set of package
2295 * files over which the new ones will be written, do the rename.
2297 if (!in_dryrun_mode() && pkgloc
[0] && !access(pkgloc
, F_OK
)) {
2298 (void) snprintf(pkgloc_sav
, sizeof (pkgloc_sav
),
2299 "%s/.save.%s", get_PKGLOC(),
2301 if (pkgloc_sav
[0] && !access(pkgloc_sav
, F_OK
)) {
2302 (void) rrmdir(pkgloc_sav
);
2305 if (rename(pkgloc
, pkgloc_sav
) == -1) {
2306 progerr(ERR_PKGBINREN
, pkgloc
, pkgloc_sav
);
2315 * Name: merg_pkginfos
2316 * Description: This function scans the installed pkginfo and merges that
2317 * environment with the installing environment according to
2318 * the following rules:
2320 * 1. CLASSES is a union of the installed and installing CLASSES
2322 * 2. The installed BASEDIR takes precedence. If it doesn't agree
2323 * with an administratively imposed BASEDIR, an ERROR is issued.
2324 * 3. All other installing parameters are preserved.
2325 * 4. All installed parameters are added if they do not overwrite
2326 * an existing installing parameter.
2328 * The current environment contains the pkginfo settings for the
2329 * new package to be installed or to be updated.
2331 * Arguments: pclass - returned list of current classes involved in install
2332 * mpclass - pointer to returned list of current install classes
2335 * != 0 - an error code if a fatal error occurred
2339 merg_pkginfos(struct cl_attr
**pclass
, struct cl_attr
***mpclass
)
2342 char SUNW_PKG_ALLZONES
[MAX_PKG_PARAM_LENGTH
] = {'\0'};
2343 char SUNW_PKG_HOLLOW
[MAX_PKG_PARAM_LENGTH
] = {'\0'};
2344 char SUNW_PKG_THISZONE
[MAX_PKG_PARAM_LENGTH
] = {'\0'};
2349 char param
[MAX_PKG_PARAM_LENGTH
];
2350 char pkginfo_path
[PATH_MAX
];
2353 /* obtain the name of the package (for error messages) */
2355 pkgName
= getenv("PKG");
2356 if (pkgName
== NULL
) {
2357 pkgName
= "*current*"; /* default name */
2360 /* obtain the version of the package (for error messages) */
2362 pkgVersion
= getenv("VERSION");
2363 if (pkgVersion
== NULL
) {
2364 pkgVersion
= "*current*"; /* default version */
2367 /* open installed package pkginfo file */
2369 (void) snprintf(pkginfo_path
, sizeof (pkginfo_path
),
2370 "%s/%s", pkgloc
, PKGINFO
);
2371 if ((fp
= fopen(pkginfo_path
, "r")) == NULL
) {
2372 progerr(ERR_PKGINFO
, pkginfo_path
);
2376 /* entry debugging info */
2378 echoDebug(DBG_MERGINFOS_ENTRY
, pkginfo_path
);
2381 * cycle through the currently installed package's pkginfo parameters
2382 * and let the currently installed package's settings survive if the
2383 * update to the package does not provide an overriding value
2386 for (param
[0] = '\0'; (oldValue
= fpkgparam(fp
, param
)) != NULL
;
2389 boolean_t setZoneAttribute
= B_FALSE
;
2391 /* debug info - attribute currently set to value */
2393 echoDebug(DBG_MERGINFOS_SET_TO
, param
, oldValue
);
2396 * if zone package attribute is present in the currently
2397 * installed package, then remember the value for the
2398 * specific zone package attribute, and set the flag that
2399 * indicates a zone package attribute is being processed.
2402 if (strcmp(param
, PKG_THISZONE_VARIABLE
) == 0) {
2403 /* SUNW_PKG_THISZONE currently set */
2404 setZoneAttribute
= B_TRUE
;
2405 (void) strlcpy(SUNW_PKG_THISZONE
, oldValue
,
2406 sizeof (SUNW_PKG_THISZONE
));
2407 } else if (strcmp(param
, PKG_ALLZONES_VARIABLE
) == 0) {
2408 /* SUNW_PKG_ALLZONES currently set */
2409 setZoneAttribute
= B_TRUE
;
2410 (void) strlcpy(SUNW_PKG_ALLZONES
, oldValue
,
2411 sizeof (SUNW_PKG_ALLZONES
));
2412 } else if (strcmp(param
, PKG_HOLLOW_VARIABLE
) == 0) {
2413 /* SUNW_PKG_THISZONE currently set */
2414 setZoneAttribute
= B_TRUE
;
2415 (void) strlcpy(SUNW_PKG_HOLLOW
, oldValue
,
2416 sizeof (SUNW_PKG_HOLLOW
));
2419 /* handle CLASSES currently being set */
2421 if (strcmp(param
, "CLASSES") == 0) {
2422 echoDebug(DBG_MERGINFOS_SET_CLASSES
, oldValue
);
2423 /* create a list of the current classes */
2424 (void) setlist(&pclass
, qstrdup(oldValue
));
2425 /* set pointer to list of current classes */
2430 /* handle BASEDIR currently being set */
2432 if (strcmp("BASEDIR", param
) == 0) {
2433 if (adm
.basedir
&& *(adm
.basedir
) &&
2434 strchr("/$", *(adm
.basedir
))) {
2437 /* Get srcinst down to a* name */
2439 if (dotptr
= strchr(srcinst
, '.')) {
2442 if (strcmp(oldValue
, adm
.basedir
) != 0) {
2443 progerr(ERR_ADMBD
, srcinst
,
2444 oldValue
, adm
.basedir
);
2445 /* administration */
2449 } else if (ADM(basedir
, "ask")) {
2451 * If it's going to ask
2452 * later, let it know that it
2453 * *must* agree with the
2454 * BASEDIR we just picked up.
2456 adm
.basedir
= "update";
2457 echoDebug(DBG_MERGINFOS_ASK_BASEDIR
);
2460 echoDebug(DBG_MERGINFOS_SET_BASEDIR
, oldValue
);
2461 putparam(param
, oldValue
);
2466 * determine if there is a new value for this attribute.
2469 newValue
= getenv(param
);
2472 * If there is no new value, and a zone attribute
2473 * is being changed, it is the same as setting the zone package
2474 * attribute to 'false' - make sure current setting is 'false'.
2477 if ((newValue
== NULL
) &&
2478 (setZoneAttribute
== B_TRUE
) &&
2479 (strcasecmp(oldValue
, "false") != 0)) {
2481 /* unset existing non-"false" zone pkg attr */
2482 progerr(ERR_MERGINFOS_UNSET_ZONEATTR
,
2483 pkgName
, pkgVersion
, param
, oldValue
);
2488 /* retain old value if no new value specified */
2490 if (newValue
== NULL
) {
2491 /* no new value - retain the old value */
2492 echoDebug(DBG_MERGINFOS_RETAIN_OLD
, param
, oldValue
);
2493 putparam(param
, oldValue
);
2497 /* note if the old and new values are the same */
2499 if (strcmp(newValue
, oldValue
) == 0) {
2500 /* set existing package parameter to same value */
2501 echoDebug(DBG_MERGINFOS_SET_DUPLICATE
, param
, oldValue
);
2506 * Check if old and new values differ.
2507 * Error if zone parameter
2510 if (setZoneAttribute
== B_TRUE
) {
2511 /* illegal change to zone attribute */
2513 progerr(ERR_MERGINFOS_CHANGE_ZONEATTR
, pkgName
,
2514 pkgVersion
, param
, oldValue
, newValue
);
2516 /* set return code to "fatal error" */
2521 /* note valid change to existing package parameter */
2523 echoDebug(DBG_MERGINFOS_SET_CHANGE
, param
,
2524 oldValue
, newValue
);
2527 /* close handle on currently installed package's pkginfo file */
2531 /* return error if not successful up to this point */
2534 echoDebug(DBG_MERGINFOS_EXIT
, pkginfo_path
, retcode
);
2540 * verify that no zone attribute has been
2541 * set to an invalid value
2544 /* SUNW_PKG_ALLZONES */
2546 newValue
= getenv(PKG_ALLZONES_VARIABLE
);
2549 * complain if setting SUNW_PKG_ALLZONES to other than "false"
2553 if ((newValue
!= NULL
) && (*SUNW_PKG_ALLZONES
== '\0') &&
2554 (strcasecmp(newValue
, "false") != 0)) {
2555 /* change ALLZONES from "true" to "false" (unset) */
2556 progerr(ERR_MERGINFOS_SET_ZONEATTR
, pkgName
,
2557 pkgVersion
, PKG_ALLZONES_VARIABLE
, newValue
);
2561 /* SUNW_PKG_THISZONE */
2563 newValue
= getenv(PKG_THISZONE_VARIABLE
);
2566 * complain if setting SUNW_PKG_THISZONE to other than "false"
2569 if ((newValue
!= NULL
) && (*SUNW_PKG_THISZONE
== '\0') &&
2570 (strcasecmp(newValue
, "false") != 0)) {
2571 /* change THISZONE from "true" to "false" (unset) */
2572 progerr(ERR_MERGINFOS_SET_ZONEATTR
, pkgName
,
2573 pkgVersion
, PKG_THISZONE_VARIABLE
, newValue
);
2577 /* SUNW_PKG_HOLLOW */
2579 newValue
= getenv(PKG_HOLLOW_VARIABLE
);
2581 /* complain if setting SUNW_PKG_HOLLOW to other than "false" */
2583 if ((newValue
!= NULL
) && (*SUNW_PKG_HOLLOW
== '\0') &&
2584 (strcasecmp(newValue
, "false") != 0)) {
2585 /* change HOLLOW from "true" to 'false" (unset) */
2586 progerr(ERR_MERGINFOS_SET_ZONEATTR
, pkgName
,
2587 pkgVersion
, PKG_HOLLOW_VARIABLE
, newValue
);
2591 echoDebug(DBG_MERGINFOS_EXIT
, pkginfo_path
, 0);
2597 set_dryrun_dir_loc(void)
2599 /* Set pkg location to the dryrun directory */
2600 set_PKGLOC(pkgdrtarg
);
2601 (void) snprintf(pkgloc
, sizeof (pkgloc
),
2602 "%s/%s", get_PKGLOC(), pkginst
);
2603 (void) snprintf(pkgbin
, sizeof (pkgbin
),
2604 "%s/install", pkgloc
);
2605 (void) snprintf(pkgsav
, sizeof (pkgsav
),
2607 (void) snprintf(ilockfile
, sizeof (ilockfile
),
2608 "%s/!I-Lock!", pkgloc
);
2609 (void) snprintf(rlockfile
, sizeof (rlockfile
),
2610 "%s/!R-Lock!", pkgloc
);
2611 (void) snprintf(savlog
, sizeof (savlog
),
2612 "%s/logs/%s", get_PKGADM(), pkginst
);
2616 * If we are updating a pkg, then we need to copy the "old" pkgloc so that
2617 * any scripts that got removed in the new version aren't left around. So we
2618 * copy it here to .save.pkgloc, then in quit() we can restore our state, or
2624 if (in_dryrun_mode()) {
2625 set_dryrun_dir_loc();
2629 * If we're not in dryrun mode and we can find an old set of package
2630 * files over which the new ones will be written, do the copy.
2632 if (!in_dryrun_mode() && pkgloc
[0] && !access(pkgloc
, F_OK
)) {
2636 (void) snprintf(pkgloc_sav
, sizeof (pkgloc_sav
), "%s/.save.%s",
2637 get_PKGLOC(), pkginst
);
2640 * Even though it takes a while, we use a recursive copy here
2641 * because if the current pkgadd fails for any reason, we
2642 * don't want to lose this data.
2644 r
= e_ExecCmdList(&status
, (char **)NULL
, (char *)NULL
,
2645 "/usr/bin/cp", "cp", "-r", pkgloc
, pkgloc_sav
,
2648 if ((r
!= 0) || (status
== -1) || (WEXITSTATUS(status
) != 0)) {
2649 progerr(ERR_PKGBINCP
, pkgloc
, pkgloc_sav
);
2658 * This implements the pkgask function. It just executes the request script
2659 * and stores the results in a response file.
2662 do_pkgask(boolean_t a_run_request_as_root
)
2664 if (pkgdev
.cdevice
) {
2666 if (!suppressCopyright
) {
2670 (void) snprintf(path
, sizeof (path
), "%s/%s", instdir
, REQUEST_FILE
);
2671 if (access(path
, F_OK
)) {
2672 progerr(ERR_NOREQUEST
);
2677 (void) set_respfile(respfile
, srcinst
, RESP_WR
);
2679 if (is_a_respfile()) {
2680 ckreturn(reqexec(update
, path
, non_abi_scripts
,
2681 a_run_request_as_root
), ERR_REQUEST
);
2686 if (warnflag
|| failflag
) {
2687 (void) remove(respfile
);
2688 echo("\nResponse file <%s> was not created.",
2691 echo("\nResponse file <%s> was created.",
2700 * This function runs a check utility and acts appropriately based upon the
2701 * return code. It deals appropriately with the dryrun file if it is present.
2704 ck_w_dryrun(int (*func
)(), int type
)
2709 if (in_dryrun_mode())
2710 set_dr_info(type
, !n
);
2719 * This function deletes all install class action scripts from the package
2720 * directory on the root filesystem.
2723 rm_icas(char *cas_dir
)
2727 char path
[PATH_MAX
];
2729 if ((pdirfp
= opendir(cas_dir
)) == NULL
)
2732 while ((dp
= readdir(pdirfp
)) != NULL
) {
2733 if (dp
->d_name
[0] == '.')
2736 if (dp
->d_name
[0] == 'i' && dp
->d_name
[1] == '.') {
2737 (void) snprintf(path
, sizeof (path
),
2738 "%s/%s", cas_dir
, dp
->d_name
);
2739 (void) remove(path
);
2742 (void) closedir(pdirfp
);
2746 ckreturn(int retcode
, char *msg
)
2759 if (retcode
>= 10 && retcode
< 20) {
2762 if (retcode
>= 20) {
2805 char path
[PATH_MAX
];
2807 /* Compose full path for copyright file */
2808 (void) snprintf(path
, sizeof (path
), "%s/%s", instdir
, COPYRIGHT_FILE
);
2810 if ((fp
= fopen(path
, "r")) == NULL
) {
2811 if (getenv("VENDOR") != NULL
)
2812 echo(getenv("VENDOR"));
2814 while (fgets(line
, LSIZE
, fp
))
2815 (void) fprintf(stdout
, "%s", line
); /* bug #1083713 */
2825 for (i
= 0; ro_params
[i
]; i
++) {
2826 if (strcmp(p
, ro_params
[i
]) == 0)
2836 * read in next part from stream, even if we decide
2837 * later that we don't need it
2840 progerr(ERR_DSTREAMCNT
);
2844 if ((access(instdir
, F_OK
) == 0) && rrmdir(instdir
)) {
2845 progerr(ERR_RMDIR
, instdir
);
2849 if (mkdir(instdir
, 0755)) {
2850 progerr(ERR_MKDIR
, instdir
);
2854 if (chdir(instdir
)) {
2855 progerr(ERR_CHDIR
, instdir
);
2859 if (!ds_fd_open()) {
2860 dparts
= ds_findpkg(pkgdev
.cdevice
, srcinst
);
2862 progerr(ERR_DSARCH
, srcinst
);
2870 if (ds_next(pkgdev
.cdevice
, instdir
)) {
2871 progerr(ERR_DSTREAM
);
2875 if (chdir(get_PKGADM())) {
2876 progerr(ERR_CHDIR
, get_PKGADM());
2886 (void) fprintf(stderr
, ERR_USAGE_PKGINSTALL
);