1 /*
2 * CDDL HEADER START
3 *
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.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2017 Peter Tribble.
24 */
25
26 /*
27 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
28 */
29
30 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
31 /* All Rights Reserved */
32
33
34 #include <stdio.h>
35 #include <time.h>
36 #include <wait.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <ulimit.h>
40 #include <sys/stat.h>
41 #include <sys/statvfs.h>
42 #include <fcntl.h>
43 #include <errno.h>
44 #include <ctype.h>
45 #include <dirent.h>
46 #include <string.h>
47 #include <signal.h>
48 #include <locale.h>
49 #include <libintl.h>
50 #include <pkgstrct.h>
51 #include <pkginfo.h>
52 #include <pkgdev.h>
53 #include <pkglocs.h>
54 #include <pwd.h>
55 #include <assert.h>
56 #include <instzones_api.h>
57 #include <pkglib.h>
58 #include <install.h>
59 #include <libinst.h>
60 #include <libadm.h>
61 #include <dryrun.h>
62 #include <messages.h>
63 #include "pkginstall.h"
64
65 /* imported globals */
66
67 extern char **environ;
68 extern char *pkgabrv;
69 extern char *pkgname;
70 extern char *pkgarch;
71 extern char *pkgvers;
72 extern char pkgwild[];
73
74 /* libadm(3LIB) */
75
76 extern char *get_install_root(void);
77
78 /* quit.c */
79
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);
87
88
89 /* static globals */
90
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);
101 static void usage(void) __NORETURN;
102 static void do_pkgask(boolean_t a_run_request_as_root);
103 static void rm_icas(char *casdir);
104 static void set_dryrun_dir_loc(void);
105 static void unpack(void);
106
107 void ckreturn(int retcode, char *msg);
108
109 static char *ro_params[] = {
110 "PATH", "NAME", "PKG", "PKGINST",
111 "VERSION", "ARCH",
112 "INSTDATE", "CATEGORY",
113 NULL
114 };
115
116 /*
117 * The following variable is the name of the device to which stdin
118 * is connected during execution of a procedure script. PROC_STDIN is
119 * correct for all ABI compliant packages. For non-ABI-compliant
120 * packages, the '-o' command line switch changes this to PROC_XSTDIN
121 * to allow user interaction during these scripts. -- JST
122 */
123 static char *script_in = PROC_STDIN; /* assume ABI compliance */
124
125 static char *pkgdrtarg = NULL;
126 static char *pkgcontsrc = NULL;
127 static int non_abi_scripts = 0;
128 static char *respfile = NULL;
129 static char *srcinst = NULL;
130 static int suppressCopyright = 0;
131 static int nointeract = 0;
132
133 /* exported globals */
134
135 char *msgtext;
136 char *pkginst = (char *)NULL;
137 char *rw_block_size = NULL;
138 char ilockfile[PATH_MAX];
139 char instdir[PATH_MAX];
140 char saveSpoolInstallDir[PATH_MAX];
141 char pkgbin[PATH_MAX];
142 char pkgloc[PATH_MAX];
143 char pkgloc_sav[PATH_MAX];
144 char pkgsav[PATH_MAX];
145 char rlockfile[PATH_MAX];
146 char savlog[PATH_MAX];
147 char tmpdir[PATH_MAX];
148 int dbchg;
149 int dparts = 0;
150 int dreboot = 0;
151 int failflag = 0;
152 static int askflag = 0; /* non-zero if invoked as "pkgask" */
153 int ireboot = 0;
154 int maxinst = 1;
155 int nocnflct;
156 int nosetuid;
157 int pkgverbose = 0;
158 int rprcflag;
159 int warnflag = 0;
160 struct admin adm;
161 struct cfextra **extlist; /* pkgmap structure and other path info */
162 struct pkgdev pkgdev;
163 fsblkcnt_t pkgmap_blks = 0LL;
164
165 /*
166 * this global is referenced by:
167 * getinst - [RW] - incremented if:
168 * - installing same instance again
169 * - overwriting an existing instance
170 * - not installing a new instance
171 * quit - [RO] - if non-zero and started non-zero:
172 * - the new <PKGINST>/install directory and rename <PKGINST>/install.save
173 * - back to <PKGINST>/install
174 * main.c - [RO] - if non-zero:
175 * - alter manner in which parameters are setup for scripts
176 * - set UPDATE=yes in environment
177 */
178 static int update = 0;
179
180 /* Set by -O debug: debug output is enabled? */
181
182 static boolean_t debugFlag = B_FALSE;
183
184 /* Set by the -G option: install packages in global zone only */
185
186 static boolean_t globalZoneOnly = B_FALSE;
187
188 /* Set by -O preinstallcheck */
189
190 static boolean_t preinstallCheck = B_FALSE;
191
192 /* Set by -O parent-zone-name= */
193
194 static char *parentZoneName = (char *)NULL;
195
196 /* Set by -O parent-zone-type= */
197
198 static char *parentZoneType = (char *)NULL;
199
200 #define DEFPATH "/sbin:/usr/sbin:/usr/bin"
201 #define MALSIZ 4 /* best guess at likely maximum value of MAXINST */
202 #define LSIZE 256 /* maximum line size supported in copyright file */
203
204 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
205 #define TEXT_DOMAIN "SYS_TEST"
206 #endif
207
208 /* This is the text for the "-O parent-zone-name=" option */
209
210 #define PARENTZONENAME "parent-zone-name="
211 #define PARENTZONENAME_LEN ((sizeof (PARENTZONENAME))-1)
212
213 /* This is the text for the "-O parent-zone-type=" option */
214
215 #define PARENTZONETYPE "parent-zone-type="
216 #define PARENTZONETYPE_LEN ((sizeof (PARENTZONETYPE))-1)
217
218 static char *cpio_names[] = {
219 "root",
220 "root.cpio",
221 "reloc",
222 "reloc.cpio",
223 "root.Z",
224 "root.cpio.Z",
225 "reloc.Z",
226 "reloc.cpio.Z",
227 0
228 };
229
230 int
main(int argc,char * argv[])231 main(int argc, char *argv[])
232 {
233 VFP_T *cfTmpVfp = NULL; /* temporary */
234 VFP_T *pkgmapVfp; /* "../pkgmap" file */
235 boolean_t run_request_as_root = B_FALSE;
236 char **np;
237 char *abi_comp_ptr;
238 char *abi_nm_ptr;
239 char *abi_sym_ptr;
240 char *admnfile = NULL;
241 char *device;
242 char *p;
243 char *prog_full_name = NULL;
244 char *pt;
245 char *updated = (char *)NULL;
246 char *vfstab_file = NULL;
247 char *zoneName = (char *)NULL;
248 char cbuf[MAX_PKG_PARAM_LENGTH];
249 char cmdbin[PATH_MAX];
250 char p_pkginfo[PATH_MAX];
251 char p_pkgmap[PATH_MAX];
252 char param[MAX_PKG_PARAM_LENGTH];
253 char script[PATH_MAX];
254 char altscript[PATH_MAX];
255 char *temp;
256 int c;
257 int disableAttributes = 0;
258 int err;
259 int init_install = 0;
260 int is_comp_arch;
261 int live_continue = 0;
262 int map_client = 1;
263 int n;
264 int nparts;
265 int npkgs;
266 int part;
267 int saveSpoolInstall = 0;
268 boolean_t cont_file_read;
269 struct cl_attr **pclass = NULL;
270 struct cl_attr **mergd_pclass = NULL;
271 struct pkginfo *prvinfo;
272 struct sigaction nact;
273 struct sigaction oact;
274 struct stat statb;
275 struct statvfs64 svfsb;
276 time_t clock;
277 PKGserver pkgserver = NULL;
278
279 /* reset contents of all default paths */
280
281 (void) memset(path, '\0', sizeof (path));
282 (void) memset(cmdbin, '\0', sizeof (cmdbin));
283 (void) memset(script, '\0', sizeof (script));
284 (void) memset(cbuf, '\0', sizeof (cbuf));
285 (void) memset(param, '\0', sizeof (param));
286
287 /* initialize locale environment */
288
289 (void) setlocale(LC_ALL, "");
290 (void) textdomain(TEXT_DOMAIN);
291
292 /* initialize program name */
293
294 prog_full_name = argv[0];
295 (void) set_prog_name(argv[0]);
296
297 /* tell spmi zones interface how to access package output functions */
298
299 z_set_output_functions(echo, echoDebug, progerr);
300
301 /* exit if not root */
302
303 if (getuid()) {
304 progerr(ERR_NOT_ROOT, get_prog_name());
305 exit(1);
306 /* NOTREACHED */
307 }
308
309 /*
310 * determine how pkgmap() deals with environment variables:
311 * - MAPALL - resolve all variables
312 * - MAPBUILD - map only build variables
313 * - MAPINSTALL - map only install variables
314 * - MAPNONE - map no variables
315 */
316
317 setmapmode(MAPINSTALL);
318
319 /* set sane umask */
320
321 (void) umask(0022);
322
323 /* initially no source "device" */
324
325 device = NULL;
326
327 /* reset npkgs (used as pkg remaining count in quit.c) */
328
329 npkgs = 0;
330
331 /* Read PKG_INSTALL_ROOT from the environment, if it's there. */
332
333 if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
334 progerr(ERR_ROOT_SET);
335 exit(1);
336 }
337
338 pkgserversetmode(DEFAULTMODE);
339
340 /* parse command line options */
341
342 while ((c = getopt(argc, argv,
343 "?Aa:B:b:Cc:D:d:eFf:GhIiMm:N:noO:p:R:r:StV:vyz")) != EOF) {
344
345 switch (c) {
346
347 /*
348 * Same as pkgadd: This disables attribute checking.
349 * It speeds up installation a little bit.
350 */
351 case 'A':
352 disableAttributes++;
353 break;
354
355 /*
356 * Same as pkgadd: Define an installation administration
357 * file, admin, to be used in place of the default
358 * administration file. The token none overrides the use
359 * of any admin file, and thus forces interaction with the
360 * user. Unless a full path name is given, pkgadd first
361 * looks in the current working directory for the
362 * administration file. If the specified administration
363 * file is not in the current working directory, pkgadd
364 * looks in the /var/sadm/install/admin directory for the
365 * administration file.
366 */
367 case 'a':
368 admnfile = flex_device(optarg, 0);
369 break;
370
371 /*
372 * Same as pkgadd: control block size given to
373 * pkginstall - block size used in read()/write() loop;
374 * default is st_blksize from stat() of source file.
375 */
376 case 'B':
377 rw_block_size = optarg;
378 break;
379
380 /*
381 * Same as pkgadd: location where executables needed
382 * by procedure scripts can be found
383 * default is /usr/sadm/install/bin.
384 */
385 case 'b':
386 if (!path_valid(optarg)) {
387 progerr(ERR_PATH, optarg);
388 exit(1);
389 }
390 if (isdir(optarg) != 0) {
391 char *p = strerror(errno);
392 progerr(ERR_CANNOT_USE_DIR, optarg, p);
393 exit(1);
394 }
395 (void) strlcpy(cmdbin, optarg, sizeof (cmdbin));
396 break;
397
398 /*
399 * Same as pkgadd: This disables checksum tests on
400 * the source files. It speeds up installation a little bit.
401 */
402 case 'C':
403 (void) checksum_off();
404 break;
405
406 /*
407 * Same as pkgadd: This allows designation of a
408 * continuation file. It is the same format as a dryrun file
409 * but it is used to take up where the dryrun left off.
410 */
411 case 'c':
412 pkgcontsrc = optarg;
413 set_continue_mode();
414 set_dr_info(DR_TYPE, INSTALL_TYPE);
415 init_contfile(pkgcontsrc);
416 break;
417
418 /*
419 * Same as pkgadd: This allows designation of a
420 * dryrun file. This pkgadd will create dryrun files
421 * in the directory provided.
422 */
423 case 'D':
424 pkgdrtarg = optarg;
425 set_dryrun_mode();
426 set_dr_info(DR_TYPE, INSTALL_TYPE);
427 break;
428
429 /*
430 * Same as pkgadd: Install or copy a package from
431 * device. device can be a full path name to a directory
432 * or the identifiers for tape, floppy disk, or removable
433 * disk - for example, /var/tmp or /floppy/floppy_name.
434 * It can also be a device alias - for example,
435 * /floppy/floppy0, or a datastream created by pkgtrans.
436 */
437 case 'd':
438 device = flex_device(optarg, 1);
439 break;
440
441 /*
442 * Different from pkgadd: disable the 32 char name
443 * limit extension
444 */
445 case 'e':
446 (void) set_ABI_namelngth();
447 break;
448
449 /*
450 * Different from pkgadd: specify file system type for
451 * the package device. Must be used with -m.
452 */
453 case 'f':
454 pkgdev.fstyp = optarg;
455 break;
456
457 /*
458 * Same as pkgadd: install package in global zone only.
459 */
460 case 'G':
461 globalZoneOnly = B_TRUE;
462 break;
463
464 /*
465 * Same as pkgadd: Enable hollow package support. When
466 * specified, for any package that has SUNW_PKG_HOLLOW=true:
467 * Do not calculate and verify package size against target.
468 * Do not run any package procedure or class action scripts.
469 * Do not create any target directories.
470 * Do not perform any script locking.
471 * Do not install any components of any package.
472 * Do not output any status or database update messages.
473 */
474 case 'h':
475 set_depend_pkginfo_DB(B_TRUE);
476 break;
477
478 /*
479 * Same as pkgadd: Informs scripts that this is
480 * an initial install by setting the environment parameter
481 * PKG_INIT_INSTALL=TRUE for all scripts. They may use it as
482 * they see fit, safe in the knowledge that the target
483 * filesystem is tabula rasa.
484 */
485 case 'I':
486 init_install++;
487 break;
488
489 /*
490 * Different from pkgadd: use by pkgask.
491 */
492 case 'i':
493 askflag++;
494 quitSetPkgask(B_TRUE);
495 break;
496
497 /*
498 * Same as pkgadd: Instruct pkgadd not to use the
499 * $root_path/etc/vfstab file for determining the client's
500 * mount points. This option assumes the mount points are
501 * correct on the server and it behaves consistently with
502 * Solaris 2.5 and earlier releases.
503 */
504 case 'M':
505 map_client = 0;
506 break;
507
508 /*
509 * Different from pkgadd: specify device to use for package
510 * source.
511 */
512 case 'm':
513 pkgdev.mount = optarg;
514 pkgdev.rdonly++;
515 pkgdev.mntflg++;
516 break;
517
518 /*
519 * Different from pkgadd: specify program name to use
520 * for messages.
521 */
522 case 'N':
523 (void) set_prog_name(optarg);
524 break;
525
526 /*
527 * Same as pkgadd: installation occurs in
528 * non-interactive mode. Suppress output of the list of
529 * installed files. The default mode is interactive.
530 */
531 case 'n':
532 nointeract++;
533 (void) echoSetFlag(B_FALSE);
534 break;
535
536 /*
537 * Almost same as pkgadd: the -O option allows the behavior
538 * of the package tools to be modified. Recognized options:
539 * -> debug
540 * ---> enable debugging output
541 * -> preinstallcheck
542 * ---> perform a "pre installation" check of the specified
543 * ---> package - suppress all regular output and cause a
544 * ---> series of one or more "name=value" pair format lines
545 * ---> to be output that describes the "installability" of
546 * ---> the specified package
547 * -> enable-hollow-package-support
548 * --> Enable hollow package support. When specified, for any
549 * --> package that has SUNW_PKG_HOLLOW=true:
550 * --> Do not calculate and verify package size against target
551 * --> Do not run any package procedure or class action scripts
552 * --> Do not create or remove any target directories
553 * --> Do not perform any script locking
554 * --> Do not install or uninstall any components of any package
555 * --> Do not output any status or database update messages
556 */
557 case 'O':
558 for (p = strtok(optarg, ","); p != (char *)NULL;
559 p = strtok(NULL, ",")) {
560
561 /* process debug option */
562
563 if (strcmp(p, "debug") == 0) {
564 /* set debug flag/enable debug output */
565 if (debugFlag == B_TRUE) {
566 smlSetVerbose(B_TRUE);
567 }
568 debugFlag = B_TRUE;
569 (void) echoDebugSetFlag(debugFlag);
570
571 /* debug info on arguments to pkgadd */
572 for (n = 0; n < argc && argv[n]; n++) {
573 echoDebug(DBG_ARG, n, argv[n]);
574 }
575
576 continue;
577 }
578
579 /* process enable-hollow-package-support opt */
580
581 if (strcmp(p,
582 "enable-hollow-package-support") == 0) {
583 set_depend_pkginfo_DB(B_TRUE);
584 continue;
585 }
586
587 /* process preinstallcheck option */
588
589 if (strcmp(p, "preinstallcheck") == 0) {
590 preinstallCheck = B_TRUE;
591 nointeract++; /* -n */
592 suppressCopyright++; /* -S */
593 quitSetSilentExit(B_TRUE);
594 continue;
595 }
596
597 /* process addzonename option */
598
599 if (strcmp(p, "addzonename") == 0) {
600 /*
601 * set zone name to add to messages;
602 * first look in the current environment
603 * and use the default package zone name
604 * if it is set; otherwise, use the name
605 * of the current zone
606 */
607 zoneName =
608 getenv(PKG_ZONENAME_VARIABLE);
609
610 if ((zoneName == (char *)NULL) ||
611 (*zoneName == '\0')) {
612 zoneName = z_get_zonename();
613 }
614
615 if (zoneName != (char *)NULL) {
616 if (*zoneName != '\0') {
617 quitSetZoneName(
618 zoneName);
619 } else {
620 zoneName = (char *)NULL;
621 }
622 }
623 continue;
624 }
625
626 /* process parent-zone-name option */
627
628 if (strncmp(p, PARENTZONENAME,
629 PARENTZONENAME_LEN) == 0) {
630 parentZoneName = p+PARENTZONENAME_LEN;
631 continue;
632 }
633
634 /* process parent-zone-type option */
635
636 if (strncmp(p, PARENTZONETYPE,
637 PARENTZONETYPE_LEN) == 0) {
638 parentZoneType = p+PARENTZONETYPE_LEN;
639 continue;
640 }
641
642 if (strncmp(p, PKGSERV_MODE,
643 PKGSERV_MODE_LEN) == 0) {
644 pkgserversetmode(pkgparsemode(p +
645 PKGSERV_MODE_LEN));
646 continue;
647 }
648
649 /* option not recognized - issue warning */
650
651 progerr(ERR_INVALID_O_OPTION, p);
652 continue;
653
654 }
655 break;
656
657 /*
658 * Different from pkgadd: This is an old non-ABI package
659 */
660 case 'o':
661 non_abi_scripts++;
662 break;
663
664 /*
665 * Different from pkgadd: specify number of parts to package.
666 */
667 case 'p':
668 dparts = ds_getinfo(optarg);
669 break;
670
671 /*
672 * Same as pkgadd: Define the full path name of a
673 * directory to use as the root_path. All files,
674 * including package system information files, are
675 * relocated to a directory tree starting in the specified
676 * root_path. The root_path may be specified when
677 * installing to a client from a server (for example,
678 * /export/root/client1).
679 */
680 case 'R':
681 if (!set_inst_root(optarg)) {
682 progerr(ERR_ROOT_CMD);
683 exit(1);
684 }
685 break;
686
687 /*
688 * Same as pkgadd: Identify a file or directory which
689 * contains output from a previous pkgask(8)
690 * session. This file supplies the interaction responses
691 * that would be requested by the package in interactive
692 * mode. response must be a full pathname.
693 */
694 case 'r':
695 respfile = flex_device(optarg, 2);
696 break;
697
698 /*
699 * Same as pkgadd: suppress copyright notice being
700 * output during installation.
701 */
702 case 'S':
703 suppressCopyright++;
704 break;
705
706 /*
707 * Same as pkgadd: disable save spool area creation;
708 * do not spool any partial package contents, that is,
709 * suppress the creation and population of the package save
710 * spool area (var/sadm/pkg/PKG/save/pspool/PKG).
711 */
712 case 't':
713 disable_spool_create();
714 break;
715
716 /*
717 * Same as pkgadd: Specify an alternative fs_file to map
718 * the client's file systems. For example, used in
719 * situations where the $root_path/etc/vfstab file is
720 * non-existent or unreliable. Informs the pkginstall
721 * portion to mount up a client filesystem based upon the
722 * supplied vfstab-like file of stable format.
723 */
724 case 'V':
725 vfstab_file = flex_device(optarg, 2);
726 map_client = 1;
727 break;
728
729 /*
730 * Same as pkgadd: Trace all of the scripts that get
731 * executed by pkgadd, located in the pkginst/install
732 * directory. This option is used for debugging the
733 * procedural and non-procedural scripts
734 */
735 case 'v':
736 pkgverbose++;
737 break;
738
739 /*
740 * Different from pkgadd: process this package using
741 * old non-ABI symlinks
742 */
743 case 'y':
744 set_nonABI_symlinks();
745 break;
746
747 /*
748 * Same as pkgadd: perform fresh install from
749 * package save spool area. When set, the package contents
750 * are installed from the package spool save area instead
751 * of from the package root area, so that the original
752 * source packages are not required to install the
753 * package. If the -h option is also specified and the
754 * package is hollow, then this option is ignored. When -z
755 * is specified:
756 * - Editable files are installed from the package instance
757 * save area.
758 * - Volatile files are installed from the package instance
759 * save area.
760 * - Executable and data files are installed from the final
761 * installed location as specified in the pkgmap file.
762 * - Installation scripts are run from the package spool
763 * save area.
764 */
765 case 'z':
766 saveSpoolInstall++;
767 break;
768
769 /*
770 * unrecognized option
771 */
772 default:
773 usage();
774 /*NOTREACHED*/
775 /*
776 * Although usage() calls a noreturn function,
777 * needed to add return (1); so that main() would
778 * pass compilation checks. The statement below
779 * should never be executed.
780 */
781 return (1);
782 }
783 }
784
785 /*
786 * ********************************************************************
787 * validate command line options
788 * ********************************************************************
789 */
790
791 /* set "debug echo" flag according to setting of "-O debug" option */
792
793 (void) echoDebugSetFlag(debugFlag);
794 (void) log_set_verbose(debugFlag);
795
796 /* output entry debugging information */
797
798 if (z_running_in_global_zone()) {
799 echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
800 } else {
801 echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
802 z_get_zonename());
803 }
804
805 if (in_continue_mode() && !in_dryrun_mode()) {
806 progerr(ERR_LIVE_CONTINUE_NOT_SUPPORTED);
807 usage();
808 /*NOTREACHED*/
809 }
810
811 /* pkgask requires a response file */
812
813 if (askflag && (respfile == NULL)) {
814 usage();
815 /*NOTREACHED*/
816 }
817
818 /* if device specified, set appropriate device in pkgdev */
819
820 if (device) {
821 if (pkgdev.mount) {
822 pkgdev.bdevice = device;
823 } else {
824 pkgdev.cdevice = device;
825 }
826 }
827
828 /* if file system type specified, must have a device to mount */
829
830 if (pkgdev.fstyp && !pkgdev.mount) {
831 progerr(ERR_F_REQUIRES_M);
832 usage();
833 /*NOTREACHED*/
834 }
835
836 /* BEGIN DATA GATHERING PHASE */
837
838 /*
839 * Get the mount table info and store internally.
840 */
841 cont_file_read = B_FALSE;
842 if (in_continue_mode()) {
843 int error;
844 cont_file_read = read_continuation(&error);
845 if (error == -1) {
846 quit(99);
847 /*NOTREACHED*/
848 }
849 if (!in_dryrun_mode()) {
850 live_continue = 1;
851 }
852 }
853 /* Read the mount table if not done in continuation mode */
854 if (!cont_file_read) {
855 if (get_mntinfo(map_client, vfstab_file)) {
856 quit(99);
857 /*NOTREACHED*/
858 }
859 }
860
861 /*
862 * This function defines the standard /var/... directories used later
863 * to construct the paths to the various databases.
864 */
865
866 set_PKGpaths(get_inst_root());
867
868 /*
869 * If this is being installed on a client whose /var filesystem is
870 * mounted in some odd way, remap the administrative paths to the
871 * real filesystem. This could be avoided by simply mounting up the
872 * client now; but we aren't yet to the point in the process where
873 * modification of the filesystem is permitted.
874 */
875 if (is_an_inst_root()) {
876 int fsys_value;
877
878 fsys_value = fsys(get_PKGLOC());
879 if (use_srvr_map_n(fsys_value))
880 set_PKGLOC(server_map(get_PKGLOC(), fsys_value));
881
882 fsys_value = fsys(get_PKGADM());
883 if (use_srvr_map_n(fsys_value))
884 set_PKGADM(server_map(get_PKGADM(), fsys_value));
885 }
886
887 /*
888 * Initialize pkginfo PKGSAV entry, just in case we dryrun to
889 * somewhere else.
890 */
891 set_infoloc(get_PKGLOC());
892
893 /* pull off directory and package name from end of command line */
894
895 switch (argc-optind) {
896 case 0: /* missing directory and package instance */
897 progerr(ERR_MISSING_DIR_AND_PKG);
898 usage();
899 /*NOTREACHED*/
900 case 1: /* missing package instance */
901 progerr(ERR_MISSING_PKG_INSTANCE);
902 usage();
903 /*NOTREACHED*/
904 case 2: /* just right! */
905 pkgdev.dirname = argv[optind++];
906 srcinst = argv[optind++];
907 break;
908 default: /* too many args! */
909 progerr(ERR_TOO_MANY_CMD_ARGS);
910 usage();
911 break;
912 }
913
914 (void) pkgparam(NULL, NULL); /* close up prior pkg file if needed */
915
916 /*
917 * Initialize installation admin parameters by reading
918 * the adminfile.
919 */
920
921 if (!askflag && !live_continue) {
922 echoDebug(DBG_PKGINSTALL_ADMINFILE, admnfile ? admnfile : "");
923 setadminFile(admnfile);
924 }
925
926 /*
927 * about to perform first operation that could be modified by the
928 * preinstall check option - if preinstall check is selected (that is,
929 * only gathering dependencies), then output a debug message to
930 * indicate that the check is beginning. Also turn echo() output
931 * off and set various other flags.
932 */
933
934 if (preinstallCheck == B_TRUE) {
935 (void) echoSetFlag(B_FALSE);
936 echoDebug(DBG_PKGINSTALL_PREINSCHK,
937 pkginst ? pkginst : (srcinst ? srcinst : ""),
938 zoneName ? zoneName : "global");
939 cksetPreinstallCheck(B_TRUE);
940 cksetZoneName(zoneName);
941 /* inform quit that the install has started */
942 quitSetInstallStarted(B_TRUE);
943 }
944
945 /*
946 * validate the "rscriptalt" admin file setting
947 * The rscriptalt admin file parameter may be set to either
948 * RSCRIPTALT_ROOT or RSCRIPTALT_NOACCESS:
949 * --> If rscriptalt is not set, or is set to RSCRIPTALT_NOACCESS,
950 * --> or is set to any value OTHER than RSCRIPTALT_ROOT, then
951 * --> assume that the parameter is set to RSCRIPTALT_NOACCESS
952 * If rscriptalt is set to RSCRIPTALT_ROOT, then run request scripts
953 * as the "root" user if user "install" is not defined.
954 * Otherwise, assume rscriptalt is set to RSCRIPTALT_NOACCESS, and run
955 * request scripts as the "alternative" user if user "install" is not
956 * defined, as appropriate for the current setting of the NONABI_SCRIPTS
957 * environment variable.
958 */
959
960 if (ADMSET(RSCRIPTALT)) {
961 p = adm.RSCRIPTALT;
962 echoDebug(DBG_PKGINSTALL_RSCRIPT_SET_TO, RSCRIPTALT_KEYWORD, p);
963 if (strcasecmp(p, RSCRIPTALT_ROOT) == 0) {
964 /* rscriptalt=root */
965 run_request_as_root = B_TRUE;
966 } else if (strcasecmp(p, RSCRIPTALT_NOACCESS) == 0) {
967 /* rscriptalt=noaccess */
968 run_request_as_root = B_FALSE;
969 } else {
970 /* rscriptalt=??? */
971 logerr(WRN_RSCRIPTALT_BAD, RSCRIPTALT_KEYWORD, p,
972 RSCRIPTALT_ROOT, RSCRIPTALT_NOACCESS);
973 logerr(WRN_RSCRIPTALT_USING, RSCRIPTALT_KEYWORD,
974 RSCRIPTALT_NOACCESS);
975 run_request_as_root = B_FALSE;
976 }
977 } else {
978 /* rscriptalt not set - assume rscriptalt=noaccess */
979 echoDebug(DBG_PKGINSTALL_RSCRIPT_NOT_SET, RSCRIPTALT_KEYWORD);
980 run_request_as_root = B_FALSE;
981 }
982
983 echoDebug(DBG_PKGINSTALL_RSCRIPT_IS_ROOT, run_request_as_root);
984
985 /*
986 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
987 */
988
989 /* hold SIGINT/SIGHUP interrupts */
990
991 (void) sighold(SIGHUP);
992 (void) sighold(SIGINT);
993
994 /* connect quit.c:trap() to SIGINT */
995
996 nact.sa_handler = quitGetTrapHandler();
997 nact.sa_flags = SA_RESTART;
998 (void) sigemptyset(&nact.sa_mask);
999
1000 (void) sigaction(SIGINT, &nact, &oact);
1001
1002 /* connect quit.c:trap() to SIGHUP */
1003
1004 nact.sa_handler = quitGetTrapHandler();
1005 nact.sa_flags = SA_RESTART;
1006 (void) sigemptyset(&nact.sa_mask);
1007
1008 (void) sigaction(SIGHUP, &nact, &oact);
1009
1010 /* release hold on signals */
1011
1012 (void) sigrelse(SIGHUP);
1013 (void) sigrelse(SIGINT);
1014
1015 /*
1016 * create required /var... directories if they do not exist;
1017 * this function will call quit(99) if any required path cannot
1018 * be created.
1019 */
1020
1021 ckdirs();
1022
1023 tzset();
1024
1025 /*
1026 * create path to temporary directory "installXXXXXX" - if TMPDIR
1027 * environment variable is set, create the directory in $TMPDIR;
1028 * otherwise, create the directory in P_tmpdir.
1029 */
1030
1031 pt = getenv("TMPDIR");
1032 (void) snprintf(tmpdir, sizeof (tmpdir), "%s/installXXXXXX",
1033 ((pt != (char *)NULL) && (*pt != '\0')) ? pt : P_tmpdir);
1034
1035 echoDebug(DBG_PKGINSTALL_TMPDIR, tmpdir);
1036
1037 if ((mktemp(tmpdir) == NULL) || mkdir(tmpdir, 0771)) {
1038 progerr(ERR_MKDIR, tmpdir);
1039 quit(99);
1040 /*NOTREACHED*/
1041 }
1042
1043 /*
1044 * if the package device is a file containing a package stream,
1045 * unpack the stream into a temporary directory
1046 */
1047
1048 if ((isdir(pkgdev.dirname) != 0) &&
1049 (pkgdev.cdevice == (char *)NULL) &&
1050 (pkgdev.bdevice == (char *)NULL) &&
1051 (isfile((char *)NULL, pkgdev.dirname) == 0)) {
1052
1053 char *idsName = (char *)NULL;
1054 char *pkgnames[2];
1055 char *device = pkgdev.dirname;
1056 boolean_t b;
1057
1058 echoDebug(DBG_PKGINSTALL_DS_ISFILE, pkgdev.dirname);
1059
1060 /*
1061 * validate the package source device - return pkgdev info that
1062 * describes the package source device.
1063 */
1064
1065 if (devtype(device, &pkgdev)) {
1066 progerr(ERR_BAD_DEVICE, device);
1067 quit(99);
1068 /* NOTREACHED */
1069 }
1070
1071 /* generate the list of packages to verify */
1072
1073 pkgnames[0] = srcinst;
1074 pkgnames[1] = (char *)NULL;
1075
1076 b = open_package_datastream(1, pkgnames, (char *)NULL,
1077 pkgdev.dirname, (int *)NULL, &idsName, tmpdir, &pkgdev,
1078 1);
1079
1080 if (b == B_FALSE) {
1081 progerr(ERR_CANNOT_OPEN_PKG_STREAM,
1082 pkgdev.dirname ? pkgdev.dirname : "?");
1083 quit(99);
1084 /*NOTREACHED*/
1085 }
1086
1087 /* make sure temporary directory is removed on exit */
1088
1089 quitSetDstreamTmpdir(pkgdev.dirname);
1090
1091 /* unpack the package instance from the data stream */
1092
1093 b = unpack_package_from_stream(idsName, srcinst,
1094 pkgdev.dirname);
1095 if (b == B_FALSE) {
1096 progerr(ERR_CANNOT_UNPACK_PKGSTRM,
1097 srcinst ? srcinst : "?",
1098 idsName ? idsName : "?",
1099 pkgdev.dirname ? pkgdev.dirname : "?");
1100 quit(99);
1101 /*NOTREACHED*/
1102 }
1103
1104 /* close the datastream - no longer needed */
1105
1106 echoDebug(DBG_CLOSING_STREAM, idsName, pkgdev.dirname);
1107 (void) ds_close(1);
1108 }
1109
1110 if (snprintf(instdir, PATH_MAX, "%s/%s", pkgdev.dirname, srcinst)
1111 >= PATH_MAX) {
1112 progerr(ERR_SNPRINTF, instdir);
1113 quit(99);
1114 /*NOTREACHED*/
1115 }
1116
1117 zoneName = getenv(PKG_ZONENAME_VARIABLE);
1118
1119 /*
1120 * If the environment has a CLIENT_BASEDIR, that takes precedence
1121 * over anything we will construct. We need to save it here because
1122 * in three lines, the current environment goes away.
1123 */
1124 (void) set_env_cbdir(); /* copy over environ */
1125
1126 getuserlocale();
1127
1128 /*
1129 * current environment has been read; clear environment out
1130 * so putparam() can be used to populate the new environment
1131 * to be passed to any executables/scripts.
1132 */
1133
1134 environ = NULL;
1135
1136 /* write parent condition information to environment */
1137
1138 putConditionInfo(parentZoneName, parentZoneType);
1139
1140 putuserlocale();
1141
1142 if (init_install) {
1143 putparam("PKG_INIT_INSTALL", "TRUE");
1144 }
1145
1146 if (is_an_inst_root()) {
1147 export_client_env(get_inst_root());
1148 }
1149
1150 if (zoneName != (char *)NULL) {
1151 putparam(PKG_ZONENAME_VARIABLE, zoneName);
1152 }
1153
1154 putparam("INST_DATADIR", pkgdev.dirname);
1155
1156 if (non_abi_scripts) {
1157 putparam("NONABI_SCRIPTS", "TRUE");
1158 }
1159
1160 if (nonABI_symlinks()) {
1161 putparam("PKG_NONABI_SYMLINKS", "TRUE");
1162 }
1163
1164 if (get_ABI_namelngth()) {
1165 putparam("PKG_ABI_NAMELENGTH", "TRUE");
1166 }
1167
1168 /* establish path and oambase */
1169
1170 if (cmdbin[0] == '\0') {
1171 (void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
1172 }
1173
1174 (void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin);
1175
1176 putparam("PATH", path);
1177
1178 putparam("OAMBASE", OAMBASE);
1179
1180 (void) snprintf(p_pkginfo, sizeof (p_pkginfo),
1181 "%s/%s", instdir, PKGINFO);
1182 (void) snprintf(p_pkgmap, sizeof (p_pkgmap),
1183 "%s/%s", instdir, PKGMAP);
1184
1185 /* Read the environment (from pkginfo or '-e') ... */
1186 abi_nm_ptr = getenv("PKG_ABI_NAMELENGTH");
1187
1188 /* Disable the 32 char name limit extension */
1189 if (abi_nm_ptr && strncasecmp(abi_nm_ptr, "TRUE", 4) == 0) {
1190 (void) set_ABI_namelngth();
1191 }
1192
1193 /*
1194 * This tests the pkginfo and pkgmap files for validity and
1195 * puts all delivered pkginfo variables (except for PATH) into
1196 * our environment. This is where a delivered pkginfo BASEDIR
1197 * would come from. See set_basedirs() below.
1198 */
1199
1200 if (pkgenv(srcinst, p_pkginfo, p_pkgmap)) {
1201 quit(1);
1202 /*NOTREACHED*/
1203 }
1204
1205 echo("\n%s(%s) %s", pkgname, pkgarch, pkgvers);
1206
1207 /*
1208 * If this script was invoked by 'pkgask', just
1209 * execute request script and quit (do_pkgask()).
1210 */
1211
1212 if (askflag) {
1213 do_pkgask(run_request_as_root);
1214 }
1215
1216 /* validate package contents file */
1217
1218 if (vcfile() == 0) {
1219 quit(99);
1220 }
1221
1222 /* if not in dryrun mode aquire packaging lock */
1223
1224 if (!in_dryrun_mode()) {
1225 /* acquire the package lock - at install initialization */
1226 if (!lockinst(get_prog_name(), srcinst, "install-initial")) {
1227 quit(99);
1228 /*NOTREACHED*/
1229 }
1230 }
1231
1232 /*
1233 * Now do all the various setups based on ABI compliance
1234 */
1235
1236 /* Read the environment (from pkginfo or '-o') ... */
1237 abi_comp_ptr = getenv("NONABI_SCRIPTS");
1238
1239 /* Read the environment (from pkginfo or '-y') ... */
1240 abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
1241
1242 /* bug id 4244631, not ABI compliant */
1243 if (abi_comp_ptr && strncasecmp(abi_comp_ptr, "TRUE", 4) == 0) {
1244 script_in = PROC_XSTDIN;
1245 non_abi_scripts = 1;
1246 }
1247
1248 /* Set symlinks to be processed the old way */
1249 if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
1250 set_nonABI_symlinks();
1251 }
1252
1253 /*
1254 * At this point, script_in, non_abi_scripts & the environment are
1255 * all set correctly for the ABI status of the package.
1256 */
1257
1258 if (pt = getenv("MAXINST")) {
1259 maxinst = atol(pt);
1260 }
1261
1262 /*
1263 * See if were are installing a package that only wants to update
1264 * the database or only install files associated with CAS's. We
1265 * only check the PKG_HOLLOW_VARIABLE variable if told to do so by
1266 * the caller.
1267 */
1268
1269 if (is_depend_pkginfo_DB()) {
1270 pt = getenv(PKG_HOLLOW_VARIABLE);
1271 if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) {
1272 echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED);
1273 if (disableAttributes) {
1274 disable_attribute_check();
1275 }
1276
1277 /*
1278 * this is a hollow package and hollow package support
1279 * is enabled -- override admin settings to suppress
1280 * checks that do not make sense since no scripts will
1281 * be executed and no files will be installed.
1282 */
1283
1284 setadminSetting("conflict", "nocheck");
1285 setadminSetting("setuid", "nocheck");
1286 setadminSetting("action", "nocheck");
1287 setadminSetting("partial", "nocheck");
1288 setadminSetting("space", "nocheck");
1289 setadminSetting("authentication", "nocheck");
1290 } else {
1291 echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED);
1292 set_depend_pkginfo_DB(B_FALSE);
1293 }
1294 }
1295
1296 /*
1297 * if performing a fresh install to a non-global zone, and doing
1298 * more than just updating the package database (that is, the
1299 * package to install is NOT "hollow"), then set the global flag
1300 * that directs installation is from partially spooled packages
1301 * (that is, packages installed in the global zone).
1302 */
1303
1304 if (saveSpoolInstall && (!is_depend_pkginfo_DB())) {
1305 set_partial_inst();
1306 } else {
1307 saveSpoolInstall = 0;
1308 }
1309
1310 /*
1311 * verify that we are not trying to install an
1312 * INTONLY package with no interaction
1313 */
1314
1315 if (pt = getenv("INTONLY")) {
1316 if (askflag || nointeract) {
1317 progerr(ERR_INTONLY, pkgabrv ? pkgabrv : "?");
1318 quit(1);
1319 /*NOTREACHED*/
1320 }
1321 }
1322
1323 if (!suppressCopyright && !pkgdev.cdevice) {
1324 copyright();
1325 }
1326
1327 /*
1328 * inspect the system to determine if any instances of the
1329 * package being installed already exist on the system
1330 */
1331
1332 prvinfo = (struct pkginfo *)calloc(MALSIZ, sizeof (struct pkginfo));
1333 if (prvinfo == NULL) {
1334 progerr(ERR_MEMORY, errno);
1335 quit(99);
1336 /*NOTREACHED*/
1337 }
1338
1339 for (;;) {
1340 if (pkginfo(&prvinfo[npkgs], pkgwild, NULL, NULL)) {
1341 if ((errno == ESRCH) || (errno == ENOENT)) {
1342 break;
1343 }
1344 progerr(ERR_SYSINFO, errno);
1345 quit(99);
1346 /*NOTREACHED*/
1347 }
1348 if ((++npkgs % MALSIZ) == 0) {
1349 prvinfo = (struct pkginfo *)realloc(prvinfo,
1350 (npkgs+MALSIZ) * sizeof (struct pkginfo));
1351 if (prvinfo == NULL) {
1352 progerr(ERR_MEMORY, errno);
1353 quit(99);
1354 /*NOTREACHED*/
1355 }
1356 }
1357 }
1358
1359 /*
1360 * Determine the correct package instance based on how many packages are
1361 * already installed. If there are none (npkgs == 0), getinst() just
1362 * returns the package abbreviation. Otherwise, getinst() interacts with
1363 * the user (or reads the admin file) to determine if an instance which
1364 * is already installed should be overwritten, or possibly install a new
1365 * instance of this package
1366 */
1367
1368 pkginst = getinst(&update, prvinfo, npkgs, preinstallCheck);
1369
1370 /* set "update flag" if updating an existing instance of this package */
1371
1372 if (update) {
1373 setUpdate();
1374 }
1375
1376 /*
1377 * Some pkgs (SUNWcsr) already spooled to the zone, check the
1378 * value of UPDATE in their postinstall script. After a pkg
1379 * has been patched UPDATE exists statically in the pkginfo
1380 * file and this value must be reset when installing a zone.
1381 */
1382
1383 if (saveSpoolInstall != 0 && !isUpdate()) {
1384 putparam("UPDATE", "");
1385 }
1386
1387 /* inform quit() if updating existing or installing new instance */
1388
1389 quitSetUpdatingExisting(update ? B_TRUE : B_FALSE);
1390
1391 if (respfile) {
1392 (void) set_respfile(respfile, pkginst, RESP_RO);
1393 }
1394
1395 (void) snprintf(pkgloc, sizeof (pkgloc),
1396 "%s/%s", get_PKGLOC(), pkginst);
1397
1398 (void) snprintf(pkgbin, sizeof (pkgbin),
1399 "%s/install", pkgloc);
1400
1401 (void) snprintf(pkgsav, sizeof (pkgsav),
1402 "%s/save", pkgloc);
1403
1404 if (snprintf(saveSpoolInstallDir, PATH_MAX, "%s/pspool/%s", pkgsav,
1405 pkginst) < 0) {
1406 progerr(ERR_SNPRINTF, saveSpoolInstallDir);
1407 quit(99);
1408 /*NOTREACHED*/
1409 }
1410
1411 (void) snprintf(ilockfile, sizeof (ilockfile),
1412 "%s/!I-Lock!", pkgloc);
1413 (void) snprintf(rlockfile, sizeof (rlockfile),
1414 "%s/!R-Lock!", pkgloc);
1415 (void) snprintf(savlog, sizeof (savlog),
1416 "%s/logs/%s", get_PKGADM(), pkginst);
1417
1418 putparam("PKGINST", pkginst);
1419 putparam("PKGSAV", pkgsav);
1420
1421 /*
1422 * Be sure request script has access to PKG_INSTALL_ROOT if there is
1423 * one
1424 */
1425
1426 put_path_params();
1427
1428 if (!map_client) {
1429 putparam("PKG_NO_UNIFIED", "TRUE");
1430 }
1431
1432 /*
1433 * This maps the client filesystems into the server's space.
1434 */
1435
1436 if (map_client && !mount_client()) {
1437 logerr(MSG_MANMOUNT);
1438 }
1439
1440 /*
1441 * If this is an UPDATE then either this is exactly the same version
1442 * and architecture of an installed package or a different package is
1443 * intended to entirely replace an installed package of the same name
1444 * with a different VERSION or ARCH string.
1445 * Don't merge any databases if only gathering dependencies.
1446 */
1447
1448 if ((preinstallCheck == B_FALSE) && (update)) {
1449 /*
1450 * If this version and architecture is already installed,
1451 * merge the installed and installing parameters and inform
1452 * all procedure scripts by defining UPDATE in the
1453 * environment.
1454 */
1455
1456 if (is_samepkg()) {
1457 /*
1458 * If it's the same ARCH and VERSION, then a merge
1459 * and copy operation is necessary.
1460 */
1461
1462 if (n = merg_pkginfos(pclass, &mergd_pclass)) {
1463 quit(n);
1464 /*NOTREACHED*/
1465 }
1466
1467 if (n = cp_pkgdirs()) {
1468 quit(n);
1469 /*NOTREACHED*/
1470 }
1471
1472 } else {
1473 /*
1474 * If it's a different ARCH and/or VERSION then this
1475 * is an "instance=overwrite" situation. The
1476 * installed base needs to be confirmed and the
1477 * package directories renamed.
1478 */
1479
1480 if (n = ck_instbase()) {
1481 quit(n);
1482 /*NOTREACHED*/
1483 }
1484
1485 if (n = mv_pkgdirs()) {
1486 quit(n);
1487 /*NOTREACHED*/
1488 }
1489 }
1490
1491 putparam("UPDATE", "yes");
1492
1493 }
1494
1495 if (in_dryrun_mode()) {
1496 set_dryrun_dir_loc();
1497 }
1498
1499 if (preinstallCheck == B_FALSE) {
1500 /*
1501 * Determine if the package has been partially installed on or
1502 * removed from this system.
1503 */
1504 ck_w_dryrun(ckpartial, PARTIAL);
1505
1506 /*
1507 * make sure current runlevel is appropriate
1508 */
1509 ck_w_dryrun(ckrunlevel, RUNLEVEL);
1510 } else {
1511 int r;
1512
1513 /*
1514 * Just gathering dependencies - determine if the package has
1515 * been partially installed on or removed from this system and
1516 * output information to stdout
1517 */
1518 r = ckpartial();
1519 (void) fprintf(stdout, "ckpartialinstall=%d\n", r == 8 ? 1 : 0);
1520 (void) fprintf(stdout, "ckpartialremove=%d\n", r == 9 ? 1 : 0);
1521
1522 /*
1523 * make sure current runlevel is appropriate
1524 */
1525 r = ckrunlevel();
1526 (void) fprintf(stdout, "ckrunlevel=%d\n", r);
1527 }
1528
1529 if (pkgdev.cdevice) {
1530 /* get first volume which contains info files */
1531 unpack();
1532 if (!suppressCopyright) {
1533 copyright();
1534 }
1535 }
1536
1537 /* update the lock - at the request script */
1538
1539 lockupd("request");
1540
1541 /*
1542 * If no response file has been provided, initialize response file by
1543 * executing any request script provided by this package. Initialize
1544 * the response file if not gathering dependencies only.
1545 */
1546
1547 if ((!rdonly_respfile()) && (preinstallCheck == B_FALSE)) {
1548 (void) snprintf(path, sizeof (path),
1549 "%s/%s", instdir, REQUEST_FILE);
1550 n = reqexec(update, path, non_abi_scripts,
1551 run_request_as_root);
1552 if (in_dryrun_mode()) {
1553 set_dr_info(REQUESTEXITCODE, n);
1554 }
1555
1556 ckreturn(n, ERR_REQUEST);
1557 }
1558
1559 /*
1560 * Look for all parameters in response file which begin with a
1561 * capital letter, and place them in the environment.
1562 */
1563
1564 if ((is_a_respfile()) && (preinstallCheck == B_FALSE)) {
1565 if (n = merg_respfile()) {
1566 quit(n);
1567 /*NOTREACHED*/
1568 }
1569 }
1570
1571 /*
1572 * Run a checkinstall script if one is provided by the package.
1573 * Don't execute checkinstall script if we are only updating the DB.
1574 * Don't execute checkinstall script if only gathering dependencies.
1575 */
1576
1577 /* update the lock - at the checkinstall script */
1578 lockupd("checkinstall");
1579
1580 /* Execute checkinstall script if one is provided. */
1581 (void) snprintf(script, sizeof (script), "%s/install/checkinstall",
1582 instdir);
1583 if (access(script, F_OK) != 0) {
1584 /* no script present */
1585 echoDebug(DBG_PKGINSTALL_COC_NONE, pkginst, script,
1586 zoneName ? zoneName : "global");
1587 } else if (is_depend_pkginfo_DB()) {
1588 /* updating db only: skip checkinstall script */
1589 echoDebug(DBG_PKGINSTALL_COC_DBUPD, pkginst, script,
1590 zoneName ? zoneName : "global");
1591 } else if (preinstallCheck == B_TRUE) {
1592 /* only gathering dependencies: skip checkinstall script */
1593 echoDebug(DBG_PKGINSTALL_COC_NODEL, pkginst, script,
1594 zoneName ? zoneName : "global");
1595 } else {
1596 /* script present and ok to run: run the script */
1597 if (zoneName == (char *)NULL) {
1598 echo(MSG_PKGINSTALL_EXECOC_GZ);
1599 echoDebug(DBG_PKGINSTALL_EXECOC_GZ, pkginst, script);
1600 } else {
1601 echo(MSG_PKGINSTALL_EXECOC_LZ, zoneName);
1602 echoDebug(DBG_PKGINSTALL_EXECOC_LZ, pkginst, script,
1603 zoneName);
1604 }
1605 n = chkexec(update, script);
1606 if (in_dryrun_mode()) {
1607 set_dr_info(CHECKEXITCODE, n);
1608 }
1609
1610 if (n == 3) {
1611 echo(WRN_CHKINSTALL);
1612 ckreturn(4, NULL);
1613 } else if (n == 7) {
1614 /* access returned error */
1615 progerr(ERR_CHKINSTALL_NOSCRIPT, script);
1616 ckreturn(4, ERR_CHKINSTALL);
1617 } else {
1618 ckreturn(n, ERR_CHKINSTALL);
1619 }
1620 }
1621
1622 /*
1623 * Now that the internal data structures are initialized, we can
1624 * initialize the dryrun files (which may be the same files).
1625 */
1626
1627 if (pkgdrtarg) {
1628 init_dryrunfile(pkgdrtarg);
1629 }
1630
1631 /*
1632 * Look for all parameters in response file which begin with a
1633 * capital letter, and place them in the environment.
1634 */
1635 if (is_a_respfile()) {
1636 if (n = merg_respfile()) {
1637 quit(n);
1638 /*NOTREACHED*/
1639 }
1640 }
1641
1642 /* update the lock - doing analysis */
1643
1644 lockupd("analysis");
1645
1646 /*
1647 * Determine package base directory and client base directory
1648 * if appropriate. Then encapsulate them for future retrieval.
1649 */
1650 if ((err = set_basedirs(isreloc(instdir), adm.basedir, pkginst,
1651 nointeract)) != 0) {
1652 quit(err);
1653 /*NOTREACHED*/
1654 }
1655
1656 /*
1657 * Create the base directory if specified.
1658 * Don't create if we are only updating the DB.
1659 * Don't create if only gathering dependencies.
1660 */
1661
1662 if (!is_depend_pkginfo_DB() &&
1663 !preinstallCheck && is_a_basedir()) {
1664 mkbasedir(!nointeract, get_basedir());
1665 echo(MSG_BASE_USED, get_basedir());
1666 }
1667
1668 /*
1669 * Store PKG_INSTALL_ROOT, BASEDIR & CLIENT_BASEDIR in our
1670 * environment for later use by procedure scripts.
1671 */
1672 put_path_params();
1673
1674 /*
1675 * the following two checks are done in the corresponding
1676 * ck() routine, but are repeated here to avoid re-processing
1677 * the database if we are administered to not include these
1678 * processes
1679 */
1680 if (ADM(setuid, "nochange")) {
1681 nosetuid++; /* Clear setuid/gid bits. */
1682 }
1683
1684 if (ADM(conflict, "nochange")) {
1685 nocnflct++; /* Don't install conflicting files. */
1686 }
1687
1688 /*
1689 * Get the filesystem space information for the filesystem on which
1690 * the "contents" file resides.
1691 */
1692
1693 svfsb.f_bsize = 8192;
1694 svfsb.f_frsize = 1024;
1695
1696 if (statvfs64(get_PKGADM(), &svfsb) == -1) {
1697 int lerrno = errno;
1698 if (!access(get_PKGADM(), F_OK)) {
1699 progerr(ERR_PKGINSTALL_STATVFS, get_PKGADM(),
1700 strerror(errno));
1701 logerr("(errno %d)", lerrno);
1702 quit(99);
1703 /*NOTREACHED*/
1704 }
1705 }
1706
1707 /*
1708 * Get the number of blocks used by the pkgmap, ocfile()
1709 * needs this to properly determine its space requirements.
1710 */
1711
1712 if (stat(p_pkgmap, &statb) == -1) {
1713 progerr(ERR_PKGINSTALL_STATOF, p_pkgmap, strerror(errno));
1714 quit(99);
1715 /*NOTREACHED*/
1716 }
1717
1718 pkgmap_blks = nblk(statb.st_size, svfsb.f_bsize, svfsb.f_frsize);
1719
1720 /*
1721 * Merge information in memory with the "contents" file; this creates
1722 * a temporary version of the "contents" file. Note that in dryrun
1723 * mode, we still need to record the contents file data somewhere,
1724 * but we do it in the dryrun directory.
1725 */
1726
1727 if (in_dryrun_mode()) {
1728 if (n = set_cfdir(pkgdrtarg)) {
1729 quit(n);
1730 /*NOTREACHED*/
1731 }
1732 } else {
1733 if (n = set_cfdir(NULL)) {
1734 quit(n);
1735 /*NOTREACHED*/
1736 }
1737 }
1738 if (!ocfile(&pkgserver, &cfTmpVfp, pkgmap_blks)) {
1739 quit(99);
1740 /*NOTREACHED*/
1741 }
1742
1743 /*
1744 * if cpio is being used, tell pkgdbmerg since attributes will
1745 * have to be check and repaired on all file and directories
1746 */
1747 for (np = cpio_names; *np != NULL; np++) {
1748 (void) snprintf(path, sizeof (path),
1749 "%s/%s", instdir, *np);
1750 if (iscpio(path, &is_comp_arch)) {
1751 is_WOS_arch();
1752 break;
1753 }
1754 }
1755
1756 /* Establish the class list and the class attributes. */
1757 cl_sets(getenv("CLASSES"));
1758 find_CAS(I_ONLY, pkgbin, instdir);
1759
1760 if (vfpOpen(&pkgmapVfp, p_pkgmap, "r", VFP_NEEDNOW) != 0) {
1761 progerr(ERR_PKGMAP, p_pkgmap);
1762 quit(99);
1763 /*NOTREACHED*/
1764 }
1765
1766 /*
1767 * This modifies the path list entries in memory to reflect
1768 * how they should look after the merg is complete
1769 */
1770
1771 nparts = sortmap(&extlist, pkgmapVfp, pkgserver, cfTmpVfp, zoneName);
1772
1773 if ((n = files_installed()) > 0) {
1774 if (n > 1) {
1775 echo(MSG_INST_MANY, n);
1776 } else {
1777 echo(MSG_INST_ONE, n);
1778 }
1779 }
1780
1781 /*
1782 * Check ulimit requirement (provided in pkginfo). The purpose of
1783 * this limit is to terminate pathological file growth resulting from
1784 * file edits in scripts. It does not apply to files in the pkgmap
1785 * and it does not apply to any database files manipulated by the
1786 * installation service.
1787 */
1788 if (pt = getenv("ULIMIT")) {
1789 if (assign_ulimit(pt) == -1) {
1790 progerr(ERR_BADULIMIT, pt);
1791 quit(99);
1792 /*NOTREACHED*/
1793 }
1794 putparam("PKG_ULIMIT", "TRUE");
1795 }
1796
1797 /*
1798 * If only gathering dependencies, check and output status of all
1799 * remaining dependencies and exit.
1800 */
1801
1802 if (preinstallCheck == B_TRUE) {
1803 /* update the lock file - final checking */
1804
1805 lockupd("preinstallcheck");
1806
1807 /* verify package information files are not corrupt */
1808
1809 (void) fprintf(stdout, "ckpkgfiles=%d\n", ckpkgfiles());
1810
1811 /* verify package dependencies */
1812
1813 (void) fprintf(stdout, "ckdepend=%d\n", ckdepend());
1814
1815 /* Check space requirements */
1816
1817 (void) fprintf(stdout, "ckspace=%d\n", ckspace());
1818
1819 /*
1820 * Determine if any objects provided by this package conflict
1821 * with the files of previously installed packages.
1822 */
1823
1824 (void) fprintf(stdout, "ckconflict=%d\n", ckconflct());
1825
1826 /*
1827 * Determine if any objects provided by this package will be
1828 * installed with setuid or setgid enabled.
1829 */
1830
1831 (void) fprintf(stdout, "cksetuid=%d\n", cksetuid());
1832
1833 /*
1834 * Determine if any packaging scripts provided with this package
1835 * will execute as a priviledged user.
1836 */
1837
1838 (void) fprintf(stdout, "ckpriv=%d\n", ckpriv());
1839
1840 /* Verify neccessary package installation directories exist */
1841
1842 (void) fprintf(stdout, "ckpkgdirs=%d\n", ckpkgdirs());
1843
1844 /*
1845 * ****** preinstall check done - exit ******
1846 */
1847
1848 echoDebug(DBG_PKGINSTALL_PREINSCHK_OK);
1849 quit(0);
1850 /*NOTREACHED*/
1851 }
1852
1853 /*
1854 * Not gathering dependencies only, proceed to check dependencies
1855 * and continue with the package installation operation.
1856 */
1857
1858 /*
1859 * verify package information files are not corrupt
1860 */
1861 ck_w_dryrun(ckpkgfiles, PKGFILES);
1862
1863 /*
1864 * verify package dependencies
1865 */
1866 ck_w_dryrun(ckdepend, DEPEND);
1867
1868 /*
1869 * Check space requirements.
1870 */
1871 ck_w_dryrun(ckspace, SPACE);
1872
1873 /*
1874 * Determine if any objects provided by this package conflict with
1875 * the files of previously installed packages.
1876 */
1877 ck_w_dryrun(ckconflct, CONFLICT);
1878
1879 /*
1880 * Determine if any objects provided by this package will be
1881 * installed with setuid or setgid enabled.
1882 */
1883 ck_w_dryrun(cksetuid, SETUID);
1884
1885 /*
1886 * Determine if any packaging scripts provided with this package will
1887 * execute as a priviledged user.
1888 */
1889 ck_w_dryrun(ckpriv, PRIV);
1890
1891 /*
1892 * Verify neccessary package installation directories exist.
1893 */
1894 ck_w_dryrun(ckpkgdirs, PKGDIRS);
1895
1896 /*
1897 * If we have assumed that we were installing setuid or conflicting
1898 * files, and the user chose to do otherwise, we need to read in the
1899 * package map again and re-merg with the "contents" file
1900 */
1901
1902 if (rprcflag) {
1903 nparts = sortmap(&extlist, pkgmapVfp, pkgserver,
1904 cfTmpVfp, zoneName);
1905 }
1906
1907 (void) vfpClose(&pkgmapVfp);
1908
1909 /* BEGIN INSTALLATION PHASE */
1910 if (in_dryrun_mode()) {
1911 echo(MSG_PKGINSTALL_DRYRUN, pkgname, pkginst);
1912 } else if (zoneName == (char *)NULL) {
1913 echo(MSG_PKGINSTALL_INSIN_GZ, pkgname, pkginst);
1914 } else {
1915 echo(MSG_PKGINSTALL_INSIN_LZ, pkgname, pkginst, zoneName);
1916 }
1917
1918 /* inform quit that the install has started */
1919
1920 quitSetInstallStarted(B_TRUE);
1921
1922 /*
1923 * This replaces the contents file with recently created temp version
1924 * which contains information about the objects being installed.
1925 * Under old lock protocol it closes both files and releases the
1926 * locks. Beginning in Solaris 2.7, this lock method should be
1927 * reviewed.
1928 */
1929
1930 n = swapcfile(pkgserver, &cfTmpVfp, pkginst, dbchg);
1931 if (n == RESULT_WRN) {
1932 warnflag++;
1933 } else if (n == RESULT_ERR) {
1934 quit(99);
1935 /*NOTREACHED*/
1936 }
1937
1938 /*
1939 * Create install-specific lockfile to indicate start of
1940 * installation. This is really just an information file. If the
1941 * process dies, the initial lockfile (from lockinst(), is
1942 * relinquished by the kernel, but this one remains in support of the
1943 * post-mortem.
1944 */
1945
1946 if (access(ilockfile, F_OK) == 0) {
1947 (void) remove(ilockfile);
1948 }
1949
1950 if (open(ilockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644) < 0) {
1951 progerr(ERR_LOCKFILE, ilockfile);
1952 quit(99);
1953 /*NOTREACHED*/
1954 }
1955
1956 (void) time(&clock);
1957
1958 /*
1959 * We do not want the time in locale in the pkginfo.
1960 * save the LC_TIME and set it to C. Reset it with saved one
1961 * after cftime().
1962 */
1963 temp = setlocale(LC_TIME, NULL);
1964 (void) setlocale(LC_TIME, "C");
1965
1966 /* LINTED warning: do not use cftime(); ... */
1967 (void) cftime(cbuf, "%b %d \045Y \045H:\045M", &clock);
1968 putparam("INSTDATE", qstrdup(cbuf));
1969 (void) setlocale(LC_TIME, temp);
1970
1971 /*
1972 * Store information about package being installed;
1973 * modify installation parameters as neccessary and
1974 * copy contents of 'install' directory into $pkgloc
1975 */
1976 merginfo(mergd_pclass, saveSpoolInstall);
1977
1978 /* If this was just a dryrun, then quit() will write out that file. */
1979 if (in_dryrun_mode()) {
1980 quit(0);
1981 /*NOTREACHED*/
1982 }
1983
1984 /*
1985 * Execute preinstall script, if one was provided with the
1986 * package. We check the package to avoid running an old
1987 * preinstall script if one was provided with a prior instance.
1988 * Don't execute preinstall script if we are only updating the DB.
1989 */
1990
1991 /* update the lock - at the preinstall altscript */
1992 lockupd("preinstall");
1993
1994 /* preinstall script in the media (package source) */
1995 (void) snprintf(altscript, sizeof (altscript), "%s/install/preinstall",
1996 instdir);
1997
1998 /* preinstall script in the pkgbin instead of media */
1999 (void) snprintf(script, sizeof (script), "%s/preinstall", pkgbin);
2000
2001 if (access(altscript, F_OK) != 0) {
2002 /* no script present */
2003 echoDebug(DBG_PKGINSTALL_POCALT_NONE, pkginst, altscript,
2004 zoneName ? zoneName : "global");
2005 } else if (access(script, F_OK) != 0) {
2006 /* no script present */
2007 echoDebug(DBG_PKGINSTALL_POC_NONE, pkginst, script,
2008 zoneName ? zoneName : "global");
2009 } else if (is_depend_pkginfo_DB()) {
2010 /* updating db only: skip preinstall script */
2011 echoDebug(DBG_PKGINSTALL_POC_DBUPD, pkginst, script,
2012 zoneName ? zoneName : "global");
2013 } else {
2014 /* script present and ok to run: run the script */
2015 assert(preinstallCheck == B_FALSE);
2016
2017 set_ulimit("preinstall", ERR_PREINSTALL);
2018 if (zoneName == (char *)NULL) {
2019 echo(MSG_PKGINSTALL_EXEPOC_GZ);
2020 echoDebug(DBG_PKGINSTALL_EXEPOC_GZ, pkginst, script);
2021 } else {
2022 echo(MSG_PKGINSTALL_EXEPOC_LZ, zoneName);
2023 echoDebug(DBG_PKGINSTALL_EXEPOC_LZ, pkginst, script,
2024 zoneName);
2025 }
2026 putparam("PKG_PROC_script", "preinstall");
2027 if (pkgverbose) {
2028 ckreturn(pkgexecl(script_in, PROC_STDOUT,
2029 PROC_USER, PROC_GRP, SHELL, "-x",
2030 script, NULL), ERR_PREINSTALL);
2031 } else {
2032 ckreturn(pkgexecl(script_in, PROC_STDOUT,
2033 PROC_USER, PROC_GRP, SHELL, script,
2034 NULL), ERR_PREINSTALL);
2035 }
2036
2037 clr_ulimit();
2038 (void) remove(script); /* no longer needed. */
2039 }
2040
2041 /*
2042 * Check delivered package for a postinstall script while
2043 * we're still on volume 1.
2044 */
2045
2046 (void) snprintf(script, sizeof (script),
2047 "%s/install/postinstall", instdir);
2048 if (access(script, F_OK) == 0) {
2049 (void) snprintf(script, sizeof (script),
2050 "%s/postinstall", pkgbin);
2051 } else {
2052 script[0] = '\0';
2053 }
2054
2055 /* update the lock - at the install phase */
2056
2057 lockupd("install");
2058
2059 /*
2060 * install package one part (volume) at a time
2061 */
2062
2063 part = 1;
2064 while (part <= nparts) {
2065 if ((part > 1) && pkgdev.cdevice) {
2066 unpack();
2067 }
2068
2069 instvol(extlist, srcinst, part, nparts,
2070 pkgserver, &cfTmpVfp, &updated, zoneName);
2071
2072 if (part++ >= nparts) {
2073 break;
2074 }
2075 }
2076
2077 z_destroyMountTable();
2078
2079 /*
2080 * Now that all install class action scripts have been used, we
2081 * delete them from the package directory.
2082 */
2083 rm_icas(pkgbin);
2084
2085 if (globalZoneOnly) {
2086 boolean_t b;
2087 b = pkgAddPackageToGzonlyList(pkginst, get_inst_root());
2088 if (b == B_FALSE) {
2089 progerr(ERR_PKGINSTALL_GZONLY_ADD, pkginst);
2090 ckreturn(1, NULL);
2091 }
2092 }
2093
2094 /*
2095 * Execute postinstall script, if any
2096 * Don't execute postinstall script if we are only updating the DB.
2097 */
2098
2099 echoDebug(DBG_PKGINSTALL_INSDONE, is_depend_pkginfo_DB(),
2100 is_depend_pkginfo_DB(), saveSpoolInstall,
2101 updated ? updated : "",
2102 script ? script : "",
2103 script ? access(script, F_OK) : -1);
2104
2105 /* update the lock - at the postinstall script */
2106 lockupd("postinstall");
2107
2108 if ((script == (char *)NULL) || (*script == '\0')) {
2109 echoDebug(DBG_PKGINSTALL_POIS_NOPATH, pkginst,
2110 zoneName ? zoneName : "global");
2111 } else if (access(script, F_OK) != 0) {
2112 echoDebug(DBG_PKGINSTALL_POIS_NONE, pkginst, script,
2113 zoneName ? zoneName : "global");
2114 } else if (is_depend_pkginfo_DB()) {
2115 echoDebug(DBG_PKGINSTALL_POIS_DBUPD, pkginst, script,
2116 zoneName ? zoneName : "global");
2117 } else if ((saveSpoolInstall != 0) && (updated == (char *)NULL)) {
2118 /*
2119 * fresh installing into non-global zone, no object was
2120 * updated (installed/verified in area), so do not run
2121 * the postinstall script.
2122 */
2123 echoDebug(DBG_PKGINSTALL_POIS_NOUPDATING,
2124 zoneName ? zoneName : "global", pkginst, script);
2125 } else {
2126 /* script present and ok to run: run the script */
2127 set_ulimit("postinstall", ERR_POSTINSTALL);
2128 if (zoneName == (char *)NULL) {
2129 echo(MSG_PKGINSTALL_EXEPIC_GZ);
2130 echoDebug(DBG_PKGINSTALL_EXEPIC_GZ, pkginst, script);
2131 } else {
2132 echo(MSG_PKGINSTALL_EXEPIC_LZ, zoneName);
2133 echoDebug(DBG_PKGINSTALL_EXEPIC_LZ, pkginst, script,
2134 zoneName);
2135 }
2136 putparam("PKG_PROC_SCRIPT", "postinstall");
2137 putparam("TMPDIR", tmpdir);
2138 if (pkgverbose) {
2139 ckreturn(pkgexecl(script_in, PROC_STDOUT,
2140 PROC_USER, PROC_GRP, SHELL, "-x",
2141 script, NULL), ERR_POSTINSTALL);
2142 } else {
2143 ckreturn(pkgexecl(script_in, PROC_STDOUT,
2144 PROC_USER, PROC_GRP, SHELL, script,
2145 NULL), ERR_POSTINSTALL);
2146 }
2147
2148 clr_ulimit();
2149 (void) remove(script); /* no longer needed */
2150 }
2151
2152 if (!warnflag && !failflag) {
2153 (void) remove(rlockfile);
2154 (void) remove(ilockfile);
2155 (void) remove(savlog);
2156 }
2157
2158 /* release the generic package lock */
2159
2160 (void) unlockinst();
2161
2162 pkgcloseserver(pkgserver);
2163
2164 quit(0);
2165 /* LINTED: no return */
2166 }
2167
2168 /*
2169 * This function merges the environment data in the response file with the
2170 * current environment.
2171 */
2172 static int
merg_respfile()2173 merg_respfile()
2174 {
2175 int retcode = 0;
2176 char *resppath = get_respfile();
2177 char *locbasedir;
2178 char param[MAX_PKG_PARAM_LENGTH], *value;
2179 FILE *fp;
2180
2181 if ((fp = fopen(resppath, "r")) == NULL) {
2182 progerr(ERR_RESPONSE, resppath);
2183 return (99);
2184 }
2185
2186 param[0] = '\0';
2187
2188 while (value = fpkgparam(fp, param)) {
2189 if (!isupper(param[0])) {
2190 param[0] = '\0';
2191 continue;
2192 }
2193
2194 if (rdonly(param)) {
2195 progerr(ERR_RDONLY, param);
2196 param[0] = '\0';
2197 continue;
2198 }
2199
2200 /*
2201 * If this is an update, and the response file
2202 * specifies the BASEDIR, make sure it matches the
2203 * existing installation base. If it doesn't, we have
2204 * to quit.
2205 */
2206 if (update && strcmp("BASEDIR", param) == 0) {
2207 locbasedir = getenv("BASEDIR");
2208 if (locbasedir && strcmp(value, locbasedir) != 0) {
2209 char *dotptr;
2210 /* Get srcinst down to a name. */
2211 if (dotptr = strchr(srcinst, '.'))
2212 *dotptr = '\000';
2213 progerr(ERR_NEWBD, srcinst,
2214 locbasedir, value);
2215 retcode = 99;
2216 }
2217 }
2218
2219 putparam(param, value);
2220 param[0] = '\0';
2221 }
2222 (void) fclose(fp);
2223
2224 return (retcode);
2225 }
2226
2227 /*
2228 * This scans the installed pkginfo file for the current BASEDIR. If this
2229 * BASEDIR is different from the current BASEDIR, there will definitely be
2230 * problems.
2231 */
2232 static int
ck_instbase(void)2233 ck_instbase(void)
2234 {
2235 int retcode = 0;
2236 char param[MAX_PKG_PARAM_LENGTH], *value;
2237 char pkginfo_path[PATH_MAX];
2238 FILE *fp;
2239
2240 /* Open the old pkginfo file. */
2241 (void) snprintf(pkginfo_path, sizeof (pkginfo_path),
2242 "%s/%s", pkgloc, PKGINFO);
2243 if ((fp = fopen(pkginfo_path, "r")) == NULL) {
2244 progerr(ERR_PKGINFO, pkginfo_path);
2245 return (99);
2246 }
2247
2248 param[0] = '\000';
2249
2250 while (value = fpkgparam(fp, param)) {
2251 if (strcmp("BASEDIR", param) == 0) {
2252 if (adm.basedir && *(adm.basedir) &&
2253 strchr("/$", *(adm.basedir))) {
2254 char *dotptr;
2255
2256 /*
2257 * Get srcinst down to a name.
2258 */
2259 if (dotptr = strchr(srcinst, '.'))
2260 *dotptr = '\000';
2261 if (strcmp(value,
2262 adm.basedir) != 0) {
2263 progerr(ERR_ADMBD, srcinst,
2264 value, adm.basedir);
2265 retcode = 4;
2266 break;
2267 }
2268 } else if (ADM(basedir, "ask"))
2269 /*
2270 * If it's going to ask later, let it know
2271 * that it *must* agree with the BASEDIR we
2272 * just picked up.
2273 */
2274 adm.basedir = "update";
2275
2276 putparam(param, value);
2277 break;
2278 }
2279
2280 param[0] = '\0';
2281 }
2282 (void) fclose(fp);
2283
2284 return (retcode);
2285 }
2286
2287 /*
2288 * Since this is an overwrite of a different version of the package, none of
2289 * the old files should remain, so we rename them.
2290 */
2291 static int
mv_pkgdirs(void)2292 mv_pkgdirs(void)
2293 {
2294 /*
2295 * If we're not in dryrun mode and we can find an old set of package
2296 * files over which the new ones will be written, do the rename.
2297 */
2298 if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) {
2299 (void) snprintf(pkgloc_sav, sizeof (pkgloc_sav),
2300 "%s/.save.%s", get_PKGLOC(),
2301 pkginst);
2302 if (pkgloc_sav[0] && !access(pkgloc_sav, F_OK)) {
2303 (void) rrmdir(pkgloc_sav);
2304 }
2305
2306 if (rename(pkgloc, pkgloc_sav) == -1) {
2307 progerr(ERR_PKGBINREN, pkgloc, pkgloc_sav);
2308 return (99);
2309 }
2310 }
2311
2312 return (0);
2313 }
2314
2315 /*
2316 * Name: merg_pkginfos
2317 * Description: This function scans the installed pkginfo and merges that
2318 * environment with the installing environment according to
2319 * the following rules:
2320 *
2321 * 1. CLASSES is a union of the installed and installing CLASSES
2322 * lists.
2323 * 2. The installed BASEDIR takes precedence. If it doesn't agree
2324 * with an administratively imposed BASEDIR, an ERROR is issued.
2325 * 3. All other installing parameters are preserved.
2326 * 4. All installed parameters are added if they do not overwrite
2327 * an existing installing parameter.
2328 *
2329 * The current environment contains the pkginfo settings for the
2330 * new package to be installed or to be updated.
2331 *
2332 * Arguments: pclass - returned list of current classes involved in install
2333 * mpclass - pointer to returned list of current install classes
2334 * Returns: int
2335 * == 0 - all OK
2336 * != 0 - an error code if a fatal error occurred
2337 */
2338
2339 static int
merg_pkginfos(struct cl_attr ** pclass,struct cl_attr *** mpclass)2340 merg_pkginfos(struct cl_attr **pclass, struct cl_attr ***mpclass)
2341 {
2342 FILE *fp;
2343 char SUNW_PKG_ALLZONES[MAX_PKG_PARAM_LENGTH] = {'\0'};
2344 char SUNW_PKG_HOLLOW[MAX_PKG_PARAM_LENGTH] = {'\0'};
2345 char SUNW_PKG_THISZONE[MAX_PKG_PARAM_LENGTH] = {'\0'};
2346 char *newValue;
2347 char *oldValue;
2348 char *pkgName;
2349 char *pkgVersion;
2350 char param[MAX_PKG_PARAM_LENGTH];
2351 char pkginfo_path[PATH_MAX];
2352 int retcode = 0;
2353
2354 /* obtain the name of the package (for error messages) */
2355
2356 pkgName = getenv("PKG");
2357 if (pkgName == NULL) {
2358 pkgName = "*current*"; /* default name */
2359 }
2360
2361 /* obtain the version of the package (for error messages) */
2362
2363 pkgVersion = getenv("VERSION");
2364 if (pkgVersion == NULL) {
2365 pkgVersion = "*current*"; /* default version */
2366 }
2367
2368 /* open installed package pkginfo file */
2369
2370 (void) snprintf(pkginfo_path, sizeof (pkginfo_path),
2371 "%s/%s", pkgloc, PKGINFO);
2372 if ((fp = fopen(pkginfo_path, "r")) == NULL) {
2373 progerr(ERR_PKGINFO, pkginfo_path);
2374 return (99);
2375 }
2376
2377 /* entry debugging info */
2378
2379 echoDebug(DBG_MERGINFOS_ENTRY, pkginfo_path);
2380
2381 /*
2382 * cycle through the currently installed package's pkginfo parameters
2383 * and let the currently installed package's settings survive if the
2384 * update to the package does not provide an overriding value
2385 */
2386
2387 for (param[0] = '\0'; (oldValue = fpkgparam(fp, param)) != NULL;
2388 param[0] = '\0') {
2389
2390 boolean_t setZoneAttribute = B_FALSE;
2391
2392 /* debug info - attribute currently set to value */
2393
2394 echoDebug(DBG_MERGINFOS_SET_TO, param, oldValue);
2395
2396 /*
2397 * if zone package attribute is present in the currently
2398 * installed package, then remember the value for the
2399 * specific zone package attribute, and set the flag that
2400 * indicates a zone package attribute is being processed.
2401 */
2402
2403 if (strcmp(param, PKG_THISZONE_VARIABLE) == 0) {
2404 /* SUNW_PKG_THISZONE currently set */
2405 setZoneAttribute = B_TRUE;
2406 (void) strlcpy(SUNW_PKG_THISZONE, oldValue,
2407 sizeof (SUNW_PKG_THISZONE));
2408 } else if (strcmp(param, PKG_ALLZONES_VARIABLE) == 0) {
2409 /* SUNW_PKG_ALLZONES currently set */
2410 setZoneAttribute = B_TRUE;
2411 (void) strlcpy(SUNW_PKG_ALLZONES, oldValue,
2412 sizeof (SUNW_PKG_ALLZONES));
2413 } else if (strcmp(param, PKG_HOLLOW_VARIABLE) == 0) {
2414 /* SUNW_PKG_THISZONE currently set */
2415 setZoneAttribute = B_TRUE;
2416 (void) strlcpy(SUNW_PKG_HOLLOW, oldValue,
2417 sizeof (SUNW_PKG_HOLLOW));
2418 }
2419
2420 /* handle CLASSES currently being set */
2421
2422 if (strcmp(param, "CLASSES") == 0) {
2423 echoDebug(DBG_MERGINFOS_SET_CLASSES, oldValue);
2424 /* create a list of the current classes */
2425 (void) setlist(&pclass, qstrdup(oldValue));
2426 /* set pointer to list of current classes */
2427 *mpclass = pclass;
2428 continue;
2429 }
2430
2431 /* handle BASEDIR currently being set */
2432
2433 if (strcmp("BASEDIR", param) == 0) {
2434 if (adm.basedir && *(adm.basedir) &&
2435 strchr("/$", *(adm.basedir))) {
2436 char *dotptr;
2437
2438 /* Get srcinst down to a* name */
2439
2440 if (dotptr = strchr(srcinst, '.')) {
2441 *dotptr = '\000';
2442 }
2443 if (strcmp(oldValue, adm.basedir) != 0) {
2444 progerr(ERR_ADMBD, srcinst,
2445 oldValue, adm.basedir);
2446 /* administration */
2447 retcode = 4;
2448 break;
2449 }
2450 } else if (ADM(basedir, "ask")) {
2451 /*
2452 * If it's going to ask
2453 * later, let it know that it
2454 * *must* agree with the
2455 * BASEDIR we just picked up.
2456 */
2457 adm.basedir = "update";
2458 echoDebug(DBG_MERGINFOS_ASK_BASEDIR);
2459 }
2460
2461 echoDebug(DBG_MERGINFOS_SET_BASEDIR, oldValue);
2462 putparam(param, oldValue);
2463 continue;
2464 }
2465
2466 /*
2467 * determine if there is a new value for this attribute.
2468 */
2469
2470 newValue = getenv(param);
2471
2472 /*
2473 * If there is no new value, and a zone attribute
2474 * is being changed, it is the same as setting the zone package
2475 * attribute to 'false' - make sure current setting is 'false'.
2476 */
2477
2478 if ((newValue == NULL) &&
2479 (setZoneAttribute == B_TRUE) &&
2480 (strcasecmp(oldValue, "false") != 0)) {
2481
2482 /* unset existing non-"false" zone pkg attr */
2483 progerr(ERR_MERGINFOS_UNSET_ZONEATTR,
2484 pkgName, pkgVersion, param, oldValue);
2485 retcode = 1;
2486 break;
2487 }
2488
2489 /* retain old value if no new value specified */
2490
2491 if (newValue == NULL) {
2492 /* no new value - retain the old value */
2493 echoDebug(DBG_MERGINFOS_RETAIN_OLD, param, oldValue);
2494 putparam(param, oldValue);
2495 continue;
2496 }
2497
2498 /* note if the old and new values are the same */
2499
2500 if (strcmp(newValue, oldValue) == 0) {
2501 /* set existing package parameter to same value */
2502 echoDebug(DBG_MERGINFOS_SET_DUPLICATE, param, oldValue);
2503 continue;
2504 }
2505
2506 /*
2507 * Check if old and new values differ.
2508 * Error if zone parameter
2509 */
2510
2511 if (setZoneAttribute == B_TRUE) {
2512 /* illegal change to zone attribute */
2513
2514 progerr(ERR_MERGINFOS_CHANGE_ZONEATTR, pkgName,
2515 pkgVersion, param, oldValue, newValue);
2516
2517 /* set return code to "fatal error" */
2518 retcode = 1;
2519 break;
2520 }
2521
2522 /* note valid change to existing package parameter */
2523
2524 echoDebug(DBG_MERGINFOS_SET_CHANGE, param,
2525 oldValue, newValue);
2526 }
2527
2528 /* close handle on currently installed package's pkginfo file */
2529
2530 (void) fclose(fp);
2531
2532 /* return error if not successful up to this point */
2533
2534 if (retcode != 0) {
2535 echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, retcode);
2536
2537 return (retcode);
2538 }
2539
2540 /*
2541 * verify that no zone attribute has been
2542 * set to an invalid value
2543 */
2544
2545 /* SUNW_PKG_ALLZONES */
2546
2547 newValue = getenv(PKG_ALLZONES_VARIABLE);
2548
2549 /*
2550 * complain if setting SUNW_PKG_ALLZONES to other than "false"
2551 */
2552
2553
2554 if ((newValue != NULL) && (*SUNW_PKG_ALLZONES == '\0') &&
2555 (strcasecmp(newValue, "false") != 0)) {
2556 /* change ALLZONES from "true" to "false" (unset) */
2557 progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2558 pkgVersion, PKG_ALLZONES_VARIABLE, newValue);
2559 return (1);
2560 }
2561
2562 /* SUNW_PKG_THISZONE */
2563
2564 newValue = getenv(PKG_THISZONE_VARIABLE);
2565
2566 /*
2567 * complain if setting SUNW_PKG_THISZONE to other than "false"
2568 */
2569
2570 if ((newValue != NULL) && (*SUNW_PKG_THISZONE == '\0') &&
2571 (strcasecmp(newValue, "false") != 0)) {
2572 /* change THISZONE from "true" to "false" (unset) */
2573 progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2574 pkgVersion, PKG_THISZONE_VARIABLE, newValue);
2575 return (1);
2576 }
2577
2578 /* SUNW_PKG_HOLLOW */
2579
2580 newValue = getenv(PKG_HOLLOW_VARIABLE);
2581
2582 /* complain if setting SUNW_PKG_HOLLOW to other than "false" */
2583
2584 if ((newValue != NULL) && (*SUNW_PKG_HOLLOW == '\0') &&
2585 (strcasecmp(newValue, "false") != 0)) {
2586 /* change HOLLOW from "true" to 'false" (unset) */
2587 progerr(ERR_MERGINFOS_SET_ZONEATTR, pkgName,
2588 pkgVersion, PKG_HOLLOW_VARIABLE, newValue);
2589 return (1);
2590 }
2591
2592 echoDebug(DBG_MERGINFOS_EXIT, pkginfo_path, 0);
2593
2594 return (0);
2595 }
2596
2597 static void
set_dryrun_dir_loc(void)2598 set_dryrun_dir_loc(void)
2599 {
2600 /* Set pkg location to the dryrun directory */
2601 set_PKGLOC(pkgdrtarg);
2602 (void) snprintf(pkgloc, sizeof (pkgloc),
2603 "%s/%s", get_PKGLOC(), pkginst);
2604 (void) snprintf(pkgbin, sizeof (pkgbin),
2605 "%s/install", pkgloc);
2606 (void) snprintf(pkgsav, sizeof (pkgsav),
2607 "%s/save", pkgloc);
2608 (void) snprintf(ilockfile, sizeof (ilockfile),
2609 "%s/!I-Lock!", pkgloc);
2610 (void) snprintf(rlockfile, sizeof (rlockfile),
2611 "%s/!R-Lock!", pkgloc);
2612 (void) snprintf(savlog, sizeof (savlog),
2613 "%s/logs/%s", get_PKGADM(), pkginst);
2614 }
2615
2616 /*
2617 * If we are updating a pkg, then we need to copy the "old" pkgloc so that
2618 * any scripts that got removed in the new version aren't left around. So we
2619 * copy it here to .save.pkgloc, then in quit() we can restore our state, or
2620 * remove it.
2621 */
2622 static int
cp_pkgdirs(void)2623 cp_pkgdirs(void)
2624 {
2625 if (in_dryrun_mode()) {
2626 set_dryrun_dir_loc();
2627 }
2628
2629 /*
2630 * If we're not in dryrun mode and we can find an old set of package
2631 * files over which the new ones will be written, do the copy.
2632 */
2633 if (!in_dryrun_mode() && pkgloc[0] && !access(pkgloc, F_OK)) {
2634 int status;
2635 int r;
2636
2637 (void) snprintf(pkgloc_sav, sizeof (pkgloc_sav), "%s/.save.%s",
2638 get_PKGLOC(), pkginst);
2639
2640 /*
2641 * Even though it takes a while, we use a recursive copy here
2642 * because if the current pkgadd fails for any reason, we
2643 * don't want to lose this data.
2644 */
2645 r = e_ExecCmdList(&status, (char **)NULL, (char *)NULL,
2646 "/usr/bin/cp", "cp", "-r", pkgloc, pkgloc_sav,
2647 (char *)NULL);
2648
2649 if ((r != 0) || (status == -1) || (WEXITSTATUS(status) != 0)) {
2650 progerr(ERR_PKGBINCP, pkgloc, pkgloc_sav);
2651 return (99);
2652 }
2653 }
2654
2655 return (0);
2656 }
2657
2658 /*
2659 * This implements the pkgask function. It just executes the request script
2660 * and stores the results in a response file.
2661 */
2662 static void
do_pkgask(boolean_t a_run_request_as_root)2663 do_pkgask(boolean_t a_run_request_as_root)
2664 {
2665 if (pkgdev.cdevice) {
2666 unpack();
2667 if (!suppressCopyright) {
2668 copyright();
2669 }
2670 }
2671 (void) snprintf(path, sizeof (path), "%s/%s", instdir, REQUEST_FILE);
2672 if (access(path, F_OK)) {
2673 progerr(ERR_NOREQUEST);
2674 quit(1);
2675 /*NOTREACHED*/
2676 }
2677
2678 (void) set_respfile(respfile, srcinst, RESP_WR);
2679
2680 if (is_a_respfile()) {
2681 ckreturn(reqexec(update, path, non_abi_scripts,
2682 a_run_request_as_root), ERR_REQUEST);
2683 } else {
2684 failflag++;
2685 }
2686
2687 if (warnflag || failflag) {
2688 (void) remove(respfile);
2689 echo("\nResponse file <%s> was not created.",
2690 get_respfile());
2691 } else {
2692 echo("\nResponse file <%s> was created.",
2693 get_respfile());
2694 }
2695
2696 quit(0);
2697 /*NOTREACHED*/
2698 }
2699
2700 /*
2701 * This function runs a check utility and acts appropriately based upon the
2702 * return code. It deals appropriately with the dryrun file if it is present.
2703 */
2704 static void
ck_w_dryrun(int (* func)(),int type)2705 ck_w_dryrun(int (*func)(), int type)
2706 {
2707 int n;
2708
2709 n = func();
2710 if (in_dryrun_mode())
2711 set_dr_info(type, !n);
2712
2713 if (n) {
2714 quit(n);
2715 /*NOTREACHED*/
2716 }
2717 }
2718
2719 /*
2720 * This function deletes all install class action scripts from the package
2721 * directory on the root filesystem.
2722 */
2723 static void
rm_icas(char * cas_dir)2724 rm_icas(char *cas_dir)
2725 {
2726 DIR *pdirfp;
2727 struct dirent *dp;
2728 char path[PATH_MAX];
2729
2730 if ((pdirfp = opendir(cas_dir)) == NULL)
2731 return;
2732
2733 while ((dp = readdir(pdirfp)) != NULL) {
2734 if (dp->d_name[0] == '.')
2735 continue;
2736
2737 if (dp->d_name[0] == 'i' && dp->d_name[1] == '.') {
2738 (void) snprintf(path, sizeof (path),
2739 "%s/%s", cas_dir, dp->d_name);
2740 (void) remove(path);
2741 }
2742 }
2743 (void) closedir(pdirfp);
2744 }
2745
2746 void
ckreturn(int retcode,char * msg)2747 ckreturn(int retcode, char *msg)
2748 {
2749 switch (retcode) {
2750 case 2:
2751 case 12:
2752 case 22:
2753 warnflag++;
2754 if (msg) {
2755 progerr("%s", msg);
2756 }
2757 /*FALLTHRU*/
2758 case 10:
2759 case 20:
2760 if (retcode >= 10 && retcode < 20) {
2761 dreboot++;
2762 }
2763 if (retcode >= 20) {
2764 ireboot++;
2765 }
2766 /*FALLTHRU*/
2767 case 0:
2768 break; /* okay */
2769
2770 case -1:
2771 retcode = 99;
2772 /*FALLTHRU*/
2773 case 99:
2774 case 1:
2775 case 11:
2776 case 21:
2777 case 4:
2778 case 14:
2779 case 24:
2780 case 5:
2781 case 15:
2782 case 25:
2783 if (msg) {
2784 progerr("%s", msg);
2785 }
2786 /*FALLTHRU*/
2787 case 3:
2788 case 13:
2789 case 23:
2790 quit(retcode);
2791 /*NOTREACHED*/
2792 default:
2793 if (msg) {
2794 progerr("%s", msg);
2795 }
2796 quit(1);
2797 /*NOTREACHED*/
2798 }
2799 }
2800
2801 static void
copyright(void)2802 copyright(void)
2803 {
2804 FILE *fp;
2805 char line[LSIZE];
2806 char path[PATH_MAX];
2807
2808 /* Compose full path for copyright file */
2809 (void) snprintf(path, sizeof (path), "%s/%s", instdir, COPYRIGHT_FILE);
2810
2811 if ((fp = fopen(path, "r")) == NULL) {
2812 if (getenv("VENDOR") != NULL)
2813 echo(getenv("VENDOR"));
2814 } else {
2815 while (fgets(line, LSIZE, fp))
2816 (void) fprintf(stdout, "%s", line); /* bug #1083713 */
2817 (void) fclose(fp);
2818 }
2819 }
2820
2821 static int
rdonly(char * p)2822 rdonly(char *p)
2823 {
2824 int i;
2825
2826 for (i = 0; ro_params[i]; i++) {
2827 if (strcmp(p, ro_params[i]) == 0)
2828 return (1);
2829 }
2830 return (0);
2831 }
2832
2833 static void
unpack(void)2834 unpack(void)
2835 {
2836 /*
2837 * read in next part from stream, even if we decide
2838 * later that we don't need it
2839 */
2840 if (dparts < 1) {
2841 progerr(ERR_DSTREAMCNT);
2842 quit(99);
2843 /*NOTREACHED*/
2844 }
2845 if ((access(instdir, F_OK) == 0) && rrmdir(instdir)) {
2846 progerr(ERR_RMDIR, instdir);
2847 quit(99);
2848 /*NOTREACHED*/
2849 }
2850 if (mkdir(instdir, 0755)) {
2851 progerr(ERR_MKDIR, instdir);
2852 quit(99);
2853 /*NOTREACHED*/
2854 }
2855 if (chdir(instdir)) {
2856 progerr(ERR_CHDIR, instdir);
2857 quit(99);
2858 /*NOTREACHED*/
2859 }
2860 if (!ds_fd_open()) {
2861 dparts = ds_findpkg(pkgdev.cdevice, srcinst);
2862 if (dparts < 1) {
2863 progerr(ERR_DSARCH, srcinst);
2864 quit(99);
2865 /*NOTREACHED*/
2866 }
2867 }
2868
2869 dparts--;
2870
2871 if (ds_next(pkgdev.cdevice, instdir)) {
2872 progerr(ERR_DSTREAM);
2873 quit(99);
2874 /*NOTREACHED*/
2875 }
2876 if (chdir(get_PKGADM())) {
2877 progerr(ERR_CHDIR, get_PKGADM());
2878 quit(99);
2879 /*NOTREACHED*/
2880 }
2881 ds_close(1);
2882 }
2883
2884 static void
usage(void)2885 usage(void)
2886 {
2887 (void) fprintf(stderr, ERR_USAGE_PKGINSTALL);
2888 exit(1);
2889 /*NOTREACHED*/
2890 }
2891