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