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