4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
40 #include <sys/types.h>
42 #include <sys/param.h>
45 #include <sys/sysmacros.h>
53 #include <sys/statvfs.h>
54 #include <sys/utsname.h>
55 #include <instzones_api.h>
60 extern char **environ
, *pkgdir
;
63 extern int mkpkgmap(char *outfile
, char *protofile
, char **cmdparam
);
65 extern int splpkgmap(struct cfent
**eptlist
, unsigned int eptnum
,
66 char *order
[], ulong_t bsize
, ulong_t frsize
, fsblkcnt_t
*plimit
,
67 fsfilcnt_t
*pilimit
, fsblkcnt_t
*pllimit
);
69 extern int checkscripts(char *inst_dir
, int silent
);
71 /* libpkg/gpkgmap.c */
72 extern void setmapmode(int mode_no
);
74 static boolean_t
valid_zone_attr(struct cfent
**eptlist
);
78 #define SPOOLDEV "spool"
80 #define MSG_PROTOTYPE "## Building pkgmap from package prototype file.\n"
81 #define MSG_PKGINFO "## Processing pkginfo file.\n"
82 #define MSG_VOLUMIZE "## Attempting to volumize %d entries in pkgmap.\n"
83 #define MSG_PACKAGE1 "## Packaging one part.\n"
84 #define MSG_PACKAGEM "## Packaging %d parts.\n"
85 #define MSG_VALSCRIPTS "## Validating control scripts.\n"
88 #define ERR_MEMORY "memory allocation failure, errno=%d"
89 #define ERR_NROOT "too many paths listed with -r option, limit is %d"
90 #define ERR_PKGINST "invalid package instance identifier <%s>"
91 #define ERR_PKGABRV "invalid package abbreviation <%s>"
92 #define ERR_BADDEV "unknown or invalid device specified <%s>"
93 #define ERR_TEMP "unable to obtain temporary file resources, errno=%d"
94 #define ERR_DSTREAM "invalid device specified (datastream) <%s>"
95 #define ERR_SPLIT "unable to volumize package"
96 #define ERR_MKDIR "unable to make directory <%s>"
97 #define ERR_SYMLINK "unable to create symbolic link for <%s>"
98 #define ERR_OVERWRITE "must use -o option to overwrite <%s>"
99 #define ERR_UMOUNT "unable to unmount device <%s>"
100 #define ERR_NOPKGINFO "required pkginfo file is not specified in prototype " \
102 #define ERR_RDPKGINFO "unable to process pkginfo file <%s>"
103 #define ERR_PROTOTYPE "unable to locate prototype file"
104 #define ERR_STATVFS "unable to stat filesystem <%s>"
105 #define ERR_WHATVFS "unable to determine or access output filesystem for " \
107 #define ERR_DEVICE "unable to find info for device <%s>"
108 #define ERR_BUILD "unable to build pkgmap from prototype file"
109 #define ERR_ONEVOL "other packages found - package must fit on a single " \
111 #define ERR_NOPARAM "parameter <%s> is not defined in <%s>"
112 #define ERR_PKGMTCH "PKG parameter <%s> does not match instance <%s>"
113 #define ERR_NO_PKG_INFOFILE "unable to open pkginfo file <%s>: %s"
114 #define ERR_ALLZONES_AND_THISZONE "The package <%s> has <%s> = true " \
115 "and <%s> = true: the package may " \
116 "set either parameter to true, but " \
117 "may not set both parameters to " \
118 "true. NOTE: if the package " \
119 "contains a request script, it is " \
120 "treated as though it has " \
121 "<SUNW_PKG_THISZONE> = true"
122 #define ERR_NO_ALLZONES_AND_HOLLOW "The package <%s> has <%s> = false " \
123 "and <%s> = true: a hollow package " \
124 "must also be set to install in all " \
126 #define ERR_PKGINFO_INVALID_OPTION_COMB "Invalid combinations of zone " \
127 "parameters in pkginfo file"
129 #define ERR_USAGE "usage: %s [options] [VAR=value [VAR=value]] " \
131 " where options may include:\n" \
141 #define WRN_MISSINGDIR "WARNING: missing directory entry for <%s>"
142 #define WRN_SETPARAM "WARNING: parameter <%s> set to \"%s\""
143 #define WRN_CLASSES "WARNING: unreferenced class <%s> in prototype file"
147 struct pkgdev pkgdev
; /* holds info about the installation device */
149 char pkgloc
[PATH_MAX
];
152 char *rootlist
[NROOT
];
156 static struct cfent
*svept
;
157 static char *protofile
,
159 static fsblkcnt_t limit
= 0;
160 static fsblkcnt_t llimit
= 0;
161 static fsfilcnt_t ilimit
= 0;
162 static int overwrite
,
165 static void ckmissing(char *path
, char type
);
166 static void outvol(struct cfent
**eptlist
, unsigned int eptnum
, int part
,
168 static void trap(int n
);
169 static void usage(void);
171 static int slinkf(char *from
, char *to
);
174 main(int argc
, char *argv
[])
176 struct utsname utsbuf
;
177 struct statvfs64 svfsb
;
178 struct cfent
**eptlist
;
182 int part
, nparts
, npkgs
, objects
;
183 char buf
[MAX_PKG_PARAM_LENGTH
];
184 char temp
[MAX_PKG_PARAM_LENGTH
];
185 char param
[MAX_PKG_PARAM_LENGTH
];
186 char *pt
, *value
, *pkginst
, *tmpdir
, *abi_sym_ptr
,
196 struct cl_attr
**allclass
= NULL
;
197 struct cl_attr
**order
;
198 unsigned int eptnum
, i
;
200 /* initialize locale environment */
202 (void) setlocale(LC_ALL
, "");
204 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
205 #define TEXT_DOMAIN "SYS_TEST"
207 (void) textdomain(TEXT_DOMAIN
);
209 /* initialize program name */
211 (void) set_prog_name(argv
[0]);
213 /* tell spmi zones interface how to access package output functions */
215 z_set_output_functions(echo
, echoDebug
, progerr
);
217 func
= sigset(SIGINT
, trap
);
219 func
= sigset(SIGINT
, func
);
220 func
= sigset(SIGHUP
, trap
);
221 setmapmode(MAPBUILD
); /* variable binding */
223 func
= sigset(SIGHUP
, func
);
226 while ((c
= getopt(argc
, argv
, "osnp:l:r:b:d:f:a:v:?")) != EOF
) {
241 putparam("PSTAMP", optarg
);
245 llimit
= strtoull(optarg
, NULL
, 10);
249 pt
= strtok(optarg
, " \t\n, ");
252 rootlist
[n
++] = flex_device(pt
, 0);
254 progerr(gettext(ERR_NROOT
), NROOT
);
257 } while (pt
= strtok(NULL
, " \t\n, "));
270 device
= flex_device(optarg
, 1);
274 putparam("ARCH", optarg
);
278 putparam("VERSION", optarg
);
285 * Although usage() calls a noreturn function,
286 * needed to add return (1); so that main() would
287 * pass compilation checks. The statement below
288 * should never be executed.
295 * Store command line variable assignments for later
296 * incorporation into the environment.
298 cmdparam
= &argv
[optind
];
300 /* Skip past equates. */
301 while (argv
[optind
] && strchr(argv
[optind
], '='))
304 /* Confirm that the instance name is valid */
305 if ((pkginst
= argv
[optind
]) != NULL
) {
306 if (pkgnmchk(pkginst
, "all", 0)) {
307 progerr(gettext(ERR_PKGINST
), pkginst
);
310 argv
[optind
++] = NULL
;
315 tmpdir
= getenv("TMPDIR");
319 /* bug id 4244631, not ABI compliant */
320 abi_sym_ptr
= getenv("PKG_NONABI_SYMLINKS");
321 if (abi_sym_ptr
&& (strncasecmp(abi_sym_ptr
, "TRUE", 4) == 0)) {
322 set_nonABI_symlinks();
325 if (device
== NULL
) {
326 device
= devattr(SPOOLDEV
, "pathname");
327 if (device
== NULL
) {
328 progerr(gettext(ERR_DEVICE
), SPOOLDEV
);
333 if (protofile
== NULL
) {
334 if (access("prototype", 0) == 0)
335 protofile
= "prototype";
336 else if (access("Prototype", 0) == 0)
337 protofile
= "Prototype";
339 progerr(gettext(ERR_PROTOTYPE
));
344 if (devtype(device
, &pkgdev
)) {
345 progerr(gettext(ERR_BADDEV
), device
);
348 if (pkgdev
.norewind
) {
349 /* initialize datastream */
350 progerr(gettext(ERR_DSTREAM
), device
);
354 if (n
= pkgmount(&pkgdev
, NULL
, 0, 0, 1))
359 * convert prototype file to a pkgmap, while locating
360 * package objects in the current environment
362 t_pkgmap
= tempnam(tmpdir
, "tmpmap");
363 if (t_pkgmap
== NULL
) {
364 progerr(gettext(ERR_TEMP
), errno
);
368 (void) fprintf(stderr
, gettext(MSG_PROTOTYPE
));
369 if (n
= mkpkgmap(t_pkgmap
, protofile
, cmdparam
)) {
370 progerr(gettext(ERR_BUILD
));
374 setmapmode(MAPNONE
); /* All appropriate variables are now bound */
376 if (vfpOpen(&vfp
, t_pkgmap
, "r", VFP_NEEDNOW
) != 0) {
377 progerr(gettext(ERR_TEMP
), errno
);
381 eptlist
= procmap(vfp
, 0, NULL
);
383 if (eptlist
== NULL
) {
387 (void) vfpClose(&vfp
);
389 /* Validate the zone attributes in pkginfo, before creation */
390 if (!valid_zone_attr(eptlist
)) {
391 progerr(ERR_PKGINFO_INVALID_OPTION_COMB
);
395 (void) fprintf(stderr
, gettext(MSG_PKGINFO
));
397 for (i
= 0; eptlist
[i
]; i
++) {
398 ckmissing(eptlist
[i
]->path
, eptlist
[i
]->ftype
);
399 if (eptlist
[i
]->ftype
!= 'i')
401 if (strcmp(eptlist
[i
]->path
, "pkginfo") == 0)
405 progerr(gettext(ERR_NOPKGINFO
));
411 * process all parameters from the pkginfo file
412 * and place them in the execution environment
415 if ((fp
= fopen(svept
->ainfo
.local
, "r")) == NULL
) {
416 progerr(gettext(ERR_RDPKGINFO
), svept
->ainfo
.local
);
420 while (value
= fpkgparam(fp
, param
)) {
421 if (getenv(param
) == NULL
)
422 putparam(param
, value
);
428 /* add command line variables */
429 while (*cmdparam
&& (value
= strchr(*cmdparam
, '=')) != NULL
) {
430 *value
= NULL
; /* terminate the parameter */
431 value
++; /* value is now the value (not '=') */
432 putparam(*cmdparam
++, value
); /* store it in environ */
435 /* make sure parameters are valid */
437 if (pt
= getenv("PKG")) {
438 if (pkgnmchk(pt
, NULL
, 0) || strchr(pt
, '.')) {
439 progerr(gettext(ERR_PKGABRV
), pt
);
445 progerr(gettext(ERR_NOPARAM
), "PKG", svept
->path
);
449 * verify consistency between PKG parameter and pkginst
451 (void) snprintf(param
, sizeof (param
), "%s.*", pt
);
452 if (pkgnmchk(pkginst
, param
, 0)) {
453 progerr(gettext(ERR_PKGMTCH
), pt
, pkginst
);
457 if ((pkgname
= getenv("NAME")) == NULL
) {
458 progerr(gettext(ERR_NOPARAM
), "NAME", svept
->path
);
461 if (ckparam("NAME", pkgname
))
463 if ((pkgvers
= getenv("VERSION")) == NULL
) {
465 /* LINTED do not use cftime(); use strftime instead */
466 (void) cftime(buf
, "\045m/\045d/\045Y", &clock
);
467 (void) snprintf(temp
, sizeof (temp
),
468 gettext("Dev Release %s"), buf
);
469 putparam("VERSION", temp
);
470 pkgvers
= getenv("VERSION");
471 logerr(gettext(WRN_SETPARAM
), "VERSION", temp
);
473 if (ckparam("VERSION", pkgvers
))
475 if ((pkgarch
= getenv("ARCH")) == NULL
) {
476 (void) uname(&utsbuf
);
477 putparam("ARCH", utsbuf
.machine
);
478 pkgarch
= getenv("ARCH");
479 logerr(gettext(WRN_SETPARAM
), "ARCH", utsbuf
.machine
);
481 if (ckparam("ARCH", pkgarch
))
483 if (getenv("PSTAMP") == NULL
) {
484 /* use octal value of '%' to fight sccs expansion */
486 /* LINTED do not use cftime(); use strftime instead */
487 (void) cftime(buf
, "\045Y\045m\045d\045H\045M\045S", &clock
);
488 (void) uname(&utsbuf
);
489 (void) snprintf(temp
, sizeof (temp
), "%s%s",
490 utsbuf
.nodename
, buf
);
491 putparam("PSTAMP", temp
);
492 logerr(gettext(WRN_SETPARAM
), "PSTAMP", temp
);
494 if ((pkgcat
= getenv("CATEGORY")) == NULL
) {
495 progerr(gettext(ERR_NOPARAM
), "CATEGORY", svept
->path
);
498 if (ckparam("CATEGORY", pkgcat
))
502 * warn user of classes listed in package which do
503 * not appear in CLASSES variable in pkginfo file
506 for (i
= 0; eptlist
[i
]; i
++) {
507 if (eptlist
[i
]->ftype
!= 'i') {
509 addlist(&allclass
, eptlist
[i
]->pkg_class
);
513 if ((pt
= getenv("CLASSES")) == NULL
) {
514 if (allclass
&& *allclass
) {
516 cl_putl("CLASSES", allclass
);
517 logerr(gettext(WRN_SETPARAM
), "CLASSES",
521 cl_sets(qstrdup(pt
));
522 if (allclass
&& *allclass
) {
523 for (i
= 0; allclass
[i
]; i
++) {
525 if (cl_idx(allclass
[i
]->name
) != -1) {
530 logerr(gettext(WRN_CLASSES
),
531 (char *)allclass
[i
]);
537 (void) fprintf(stderr
, gettext(MSG_VOLUMIZE
), objects
);
538 order
= (struct cl_attr
**)0;
539 if (pt
= getenv("ORDER")) {
541 (void) setlist(&order
, pt
);
542 cl_putl("ORDER", order
);
545 /* stat the intended output filesystem to get blocking information */
546 if (pkgdev
.dirname
== NULL
) {
547 progerr(gettext(ERR_WHATVFS
), device
);
550 if (statvfs64(pkgdev
.dirname
, &svfsb
)) {
551 progerr(gettext(ERR_STATVFS
), pkgdev
.dirname
);
556 bsize
= svfsb
.f_bsize
;
559 frsize
= svfsb
.f_frsize
;
564 * bavail is in terms of fragment size blocks - change
567 limit
= (fsblkcnt_t
)(((fsblkcnt_t
)frsize
> 0) ?
568 howmany(frsize
, DEV_BSIZE
) :
569 howmany(bsize
, DEV_BSIZE
)) * svfsb
.f_bavail
;
572 ilimit
= (svfsb
.f_favail
> 0) ?
573 svfsb
.f_favail
: svfsb
.f_ffree
;
576 nparts
= splpkgmap(eptlist
, eptnum
, (char **)order
, bsize
, frsize
,
577 &limit
, &ilimit
, &llimit
);
580 progerr(gettext(ERR_SPLIT
));
585 for (i
= 0; eptlist
[i
]; i
++)
586 (void) ppkgmap(eptlist
[i
], stdout
);
591 (void) snprintf(pkgloc
, sizeof (pkgloc
), "%s/%s",
592 pkgdev
.dirname
, pkginst
);
593 if (!isdir(pkgloc
) && !overwrite
) {
594 progerr(gettext(ERR_OVERWRITE
), pkgloc
);
598 /* output all environment install parameters */
599 t_pkginfo
= tempnam(tmpdir
, "pkginfo");
600 if ((fp
= fopen(t_pkginfo
, "w")) == NULL
) {
601 progerr(gettext(ERR_TEMP
), errno
);
604 for (i
= 0; environ
[i
]; i
++) {
605 if (isupper(*environ
[i
])) {
606 (void) fputs(environ
[i
], fp
);
607 (void) fputc('\n', fp
);
613 (void) rrmdir(pkgloc
);
614 if (mkdir(pkgloc
, 0755)) {
615 progerr(gettext(ERR_MKDIR
), pkgloc
);
619 /* determine how many packages already reside on the medium */
620 pkgdir
= pkgdev
.dirname
;
622 while (pt
= fpkginst("all", NULL
, NULL
))
624 (void) fpkginst(NULL
); /* free resource usage */
627 if (pkgdev
.mount
&& npkgs
) {
628 progerr(gettext(ERR_ONEVOL
));
634 * update pkgmap entry for pkginfo file, since it may
635 * have changed due to command line or failure to
636 * specify all neccessary parameters
638 for (i
= 0; eptlist
[i
]; i
++) {
639 if (eptlist
[i
]->ftype
!= 'i')
641 if (strcmp(eptlist
[i
]->path
, "pkginfo") == 0) {
644 svept
->ainfo
.local
= t_pkginfo
;
645 (void) cverify(0, &svept
->ftype
, t_pkginfo
,
653 (void) fprintf(stderr
, gettext(MSG_PACKAGEM
), nparts
);
655 (void) fprintf(stderr
, gettext(MSG_PACKAGE1
));
657 for (part
= 1; part
<= nparts
; part
++) {
658 if ((part
> 1) && pkgdev
.mount
) {
659 if (pkgumount(&pkgdev
)) {
660 progerr(gettext(ERR_UMOUNT
), pkgdev
.mount
);
663 if (n
= pkgmount(&pkgdev
, NULL
, part
, nparts
, 1))
665 (void) rrmdir(pkgloc
);
666 if (mkdir(pkgloc
, 0555)) {
667 progerr(gettext(ERR_MKDIR
), pkgloc
);
671 outvol(eptlist
, eptnum
, part
, nparts
);
673 /* Validate (as much as possible) the control scripts. */
675 char inst_path
[PATH_MAX
];
677 (void) fprintf(stderr
, gettext(MSG_VALSCRIPTS
));
678 (void) snprintf(inst_path
, sizeof (inst_path
),
679 "%s/install", pkgloc
);
680 checkscripts(inst_path
, 0);
685 /* LINTED: no return */
691 (void) signal(SIGINT
, SIG_IGN
);
692 (void) signal(SIGHUP
, SIG_IGN
);
697 (void) fprintf(stderr
, gettext("%s terminated (signal %d).\n"),
704 outvol(struct cfent
**eptlist
, unsigned int eptnum
, int part
, int nparts
)
707 char *svpt
, *path
, temp
[PATH_MAX
];
712 (void) fprintf(stderr
, gettext(" -- part %2d:\n"), part
);
714 /* re-write pkgmap, but exclude local pathnames */
715 (void) snprintf(temp
, sizeof (temp
), "%s/pkgmap", pkgloc
);
716 if ((fp
= fopen(temp
, "w")) == NULL
) {
717 progerr(gettext(ERR_TEMP
), errno
);
720 (void) fprintf(fp
, ": %d %llu\n", nparts
, limit
);
721 for (i
= 0; eptlist
[i
]; i
++) {
722 svpt
= eptlist
[i
]->ainfo
.local
;
723 if (!strchr("sl", eptlist
[i
]->ftype
))
724 eptlist
[i
]->ainfo
.local
= NULL
;
725 if (ppkgmap(eptlist
[i
], fp
)) {
726 progerr(gettext(ERR_TEMP
), errno
);
729 eptlist
[i
]->ainfo
.local
= svpt
;
732 (void) fprintf(stderr
, "%s\n", temp
);
735 (void) snprintf(temp
, sizeof (temp
), "%s/pkginfo", pkgloc
);
736 if (copyf(svept
->ainfo
.local
, temp
, svept
->cinfo
.modtime
))
738 (void) fprintf(stderr
, "%s\n", temp
);
740 for (i
= 0; i
< eptnum
; i
++) {
741 if (eptlist
[i
]->volno
!= part
)
743 if (strchr("dxslcbp", eptlist
[i
]->ftype
))
745 if (eptlist
[i
]->ftype
== 'i') {
746 if (eptlist
[i
] == svept
)
747 continue; /* don't copy pkginfo file */
748 (void) snprintf(temp
, sizeof (temp
),
749 "%s/install/%s", pkgloc
,
753 path
= srcpath(pkgloc
, eptlist
[i
]->path
, part
, nparts
);
755 if (slinkf(eptlist
[i
]->ainfo
.local
, path
))
757 } else if (copyf(eptlist
[i
]->ainfo
.local
, path
,
758 eptlist
[i
]->cinfo
.modtime
)) {
763 * If the package file attributes can be sync'd up with
764 * the pkgmap, we fix the attributes here.
766 if (*(eptlist
[i
]->ainfo
.owner
) != '$' &&
767 *(eptlist
[i
]->ainfo
.group
) != '$') {
768 /* Clear dangerous bits. */
769 eptlist
[i
]->ainfo
.mode
=
770 (eptlist
[i
]->ainfo
.mode
& S_IAMB
);
772 * Make sure it can be read by the world and written
775 eptlist
[i
]->ainfo
.mode
|= 0644;
776 if (!strchr("in", eptlist
[i
]->ftype
)) {
777 /* Set the safe attributes. */
778 averify(1, &(eptlist
[i
]->ftype
),
779 path
, &(eptlist
[i
]->ainfo
));
783 (void) fprintf(stderr
, "%s\n", path
);
788 ckmissing(char *path
, char type
)
796 dir
= (char **)calloc(MALSIZ
, sizeof (char *));
798 progerr(gettext(ERR_MEMORY
), errno
);
803 if (strchr("dx", type
)) {
805 if ((++ndir
% MALSIZ
) == 0) {
806 dir
= (char **)realloc((void *)dir
,
807 (ndir
+MALSIZ
)*sizeof (char *));
809 progerr(gettext(ERR_MEMORY
), errno
);
813 dir
[ndir
] = (char *)NULL
;
819 while (pt
= strchr(pt
, '/')) {
822 for (i
= 0; i
< ndir
; i
++) {
823 if (strcmp(path
, dir
[i
]) == 0) {
829 logerr(gettext(WRN_MISSINGDIR
), path
);
830 ckmissing(qstrdup(path
), 'd');
837 slinkf(char *from
, char *to
)
842 while (pt
= strchr(pt
+1, '/')) {
844 if (isdir(to
) && mkdir(to
, 0755)) {
845 progerr(gettext(ERR_MKDIR
), to
);
851 if (symlink(from
, to
)) {
852 progerr(gettext(ERR_SYMLINK
), to
);
861 (void) fprintf(stderr
, gettext(ERR_USAGE
), get_prog_name());
867 * valid_zone_attr: Validates the zone attributes specified in
868 * pkginfo file for this package. The package
869 * can not be created with certain combinations
873 valid_zone_attr(struct cfent
**eptlist
)
876 boolean_t all_zones
; /* pkg is "all zones" only */
877 boolean_t is_hollow
; /* pkg is "hollow" */
878 boolean_t this_zone
; /* pkg is "this zone" only */
879 char pkginfoPath
[PATH_MAX
]; /* pkginfo file path */
883 /* Path to pkginfo file within the package to be installed */
886 for (i
= 0; eptlist
[i
]; i
++) {
887 if (eptlist
[i
]->ftype
!= 'i')
889 if (strcmp(eptlist
[i
]->path
, "pkginfo") == 0)
890 (void) strcpy(pkginfoPath
, eptlist
[i
]->ainfo
.local
);
893 * Check to see if this package has a request script. If this
894 * package does have a request script, then mark the package
895 * for installation in this zone only. Any package with a
896 * request script cannot be installed outside of the zone the
897 * pkgadd command is being run in, nor can such a package be
898 * installed as part of a new zone install. A new zone install
899 * must be non-interactive, which is required by all packages
900 * integrated into the Solaris WOS.
901 * If request file is set in prototype, then this_zone is TRUE.
903 if (strcmp(eptlist
[i
]->path
, "request") == 0)
907 /* Gather information from the pkginfo file */
909 pkginfoFP
= fopen(pkginfoPath
, "r");
911 if (pkginfoFP
== NULL
) {
912 progerr(ERR_NO_PKG_INFOFILE
, pkginfoPath
, strerror(errno
));
916 if ((pkgInst
= fpkgparam(pkginfoFP
, "PKG")) == NULL
) {
917 progerr(gettext(ERR_NOPARAM
), "PKG", pkginfoPath
);
922 /* Determine "HOLLOW" setting for this package */
923 is_hollow
= pkginfoParamTruth(pkginfoFP
, PKG_HOLLOW_VARIABLE
,
926 /* Determine "ALLZONES" setting for this package */
927 all_zones
= pkginfoParamTruth(pkginfoFP
, PKG_ALLZONES_VARIABLE
,
930 /* Determine "THISZONE" setting for this package, if no request file */
932 this_zone
= pkginfoParamTruth(pkginfoFP
, PKG_THISZONE_VARIABLE
,
935 /* Close pkginfo file */
936 (void) fclose(pkginfoFP
);
939 * Validate zone attributes based on information gathered,
940 * and validate the three SUNW_PKG_ options:
942 * -----------------------------|---------------|
943 * <ALLZONES><HOLLOW><THISZONE> | If Allowed |
944 * ----1------------------------|---------------|
948 * ----2------------------------|---------------|
952 * -----------------------------|---------------|
955 /* pkg "all zones" && "this zone" (#2) */
957 if (all_zones
&& this_zone
) {
958 progerr(ERR_ALLZONES_AND_THISZONE
, pkgInst
,
959 PKG_ALLZONES_VARIABLE
, PKG_THISZONE_VARIABLE
);
963 /* pkg "!all zones" && "hollow" (#1) */
965 if ((!all_zones
) && is_hollow
) {
966 progerr(ERR_NO_ALLZONES_AND_HOLLOW
, pkgInst
,
967 PKG_ALLZONES_VARIABLE
, PKG_HOLLOW_VARIABLE
);