1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland 
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*5c51f124SMoriah Waterland  * Use is subject to license terms.
25*5c51f124SMoriah Waterland  */
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland 
28*5c51f124SMoriah Waterland #include <stdio.h>
29*5c51f124SMoriah Waterland #include <stdlib.h>
30*5c51f124SMoriah Waterland #include <string.h>
31*5c51f124SMoriah Waterland #include <sys/types.h>
32*5c51f124SMoriah Waterland #include <sys/wait.h>
33*5c51f124SMoriah Waterland #include <sys/stat.h>
34*5c51f124SMoriah Waterland #include <fcntl.h>
35*5c51f124SMoriah Waterland #include <pkgstrct.h>
36*5c51f124SMoriah Waterland #include <unistd.h>
37*5c51f124SMoriah Waterland #include <pkglib.h>
38*5c51f124SMoriah Waterland #include <libintl.h>
39*5c51f124SMoriah Waterland #include "libadm.h"
40*5c51f124SMoriah Waterland #include "libinst.h"
41*5c51f124SMoriah Waterland #include "dryrun.h"
42*5c51f124SMoriah Waterland 
43*5c51f124SMoriah Waterland #define	HDR_FSUSAGE	"#name remote_name writeable bfree bused ifree iused"
44*5c51f124SMoriah Waterland 
45*5c51f124SMoriah Waterland #define	ERR_NOCREAT	"cannot create %s."
46*5c51f124SMoriah Waterland #define	ERR_NOOPEN	"cannot open %s."
47*5c51f124SMoriah Waterland #define	ERR_NOWRITE	"cannot write to %s."
48*5c51f124SMoriah Waterland #define	ERR_NOREAD	"cannot read from %s."
49*5c51f124SMoriah Waterland #define	ERR_FSFAIL	"cannot construct filesystem table entry."
50*5c51f124SMoriah Waterland #define	ERR_BADTYPE	"cannot record %s dryrun from %s continuation file."
51*5c51f124SMoriah Waterland #define	ERR_NOCONT	"cannot install from continue file due to error " \
52*5c51f124SMoriah Waterland 			    "stacking."
53*5c51f124SMoriah Waterland 
54*5c51f124SMoriah Waterland #define	ISUMASC_SUFFIX	".isum.asc"
55*5c51f124SMoriah Waterland #define	FSASC_SUFFIX	".fs.asc"
56*5c51f124SMoriah Waterland #define	IPOASC_SUFFIX	".ipo.asc"
57*5c51f124SMoriah Waterland #define	IBIN_SUFFIX	".inst.bin"
58*5c51f124SMoriah Waterland 
59*5c51f124SMoriah Waterland #define	MALCOUNT	5	/* package entries to allocate in a block */
60*5c51f124SMoriah Waterland #define	PKGNAMESIZE	32	/* package entries to allocate in a block */
61*5c51f124SMoriah Waterland 
62*5c51f124SMoriah Waterland extern struct cfextra **extlist;
63*5c51f124SMoriah Waterland extern char *pkginst;
64*5c51f124SMoriah Waterland 
65*5c51f124SMoriah Waterland static struct cfextra **extptr;
66*5c51f124SMoriah Waterland static int	dryrun_mode = 0;
67*5c51f124SMoriah Waterland static int	continue_mode = 0;
68*5c51f124SMoriah Waterland static int	this_exitcode = 0;
69*5c51f124SMoriah Waterland 
70*5c51f124SMoriah Waterland /* The dryrun and continuation filenames */
71*5c51f124SMoriah Waterland static char *dryrun_sumasc;
72*5c51f124SMoriah Waterland static char *dryrun_fsasc;
73*5c51f124SMoriah Waterland static char *dryrun_poasc;
74*5c51f124SMoriah Waterland static char *dryrun_bin;
75*5c51f124SMoriah Waterland static char *continue_bin;
76*5c51f124SMoriah Waterland 
77*5c51f124SMoriah Waterland /* These tell us if the actual files are initialized yet. */
78*5c51f124SMoriah Waterland static int dryrun_initialized = 0;
79*5c51f124SMoriah Waterland static int continue_initialized = 0;
80*5c51f124SMoriah Waterland 
81*5c51f124SMoriah Waterland static int this_type;		/* type of transaction from main.c */
82*5c51f124SMoriah Waterland 
83*5c51f124SMoriah Waterland static int pkg_handle = -1;
84*5c51f124SMoriah Waterland static int tot_pkgs;
85*5c51f124SMoriah Waterland 
86*5c51f124SMoriah Waterland /* Their associated file pointers */
87*5c51f124SMoriah Waterland static FILE *fp_dra;
88*5c51f124SMoriah Waterland static int fd_drb;
89*5c51f124SMoriah Waterland static int fd_cnb;
90*5c51f124SMoriah Waterland 
91*5c51f124SMoriah Waterland struct dr_pkg_entry {
92*5c51f124SMoriah Waterland 	char pkginst[PKGNAMESIZE + 2];
93*5c51f124SMoriah Waterland 	struct dr_pkg_entry *next;
94*5c51f124SMoriah Waterland };
95*5c51f124SMoriah Waterland 
96*5c51f124SMoriah Waterland static struct drinfo {
97*5c51f124SMoriah Waterland 	unsigned partial_set:1;	/* 1 if a partial installation was detected. */
98*5c51f124SMoriah Waterland 	unsigned partial:1;	/* 1 if a partial installation was detected. */
99*5c51f124SMoriah Waterland 	unsigned runlevel_set:1;
100*5c51f124SMoriah Waterland 	unsigned runlevel:1;	/* 1 if runlevel test returned an error. */
101*5c51f124SMoriah Waterland 	unsigned pkgfiles_set:1;
102*5c51f124SMoriah Waterland 	unsigned pkgfiles:1;
103*5c51f124SMoriah Waterland 	unsigned depend_set:1;
104*5c51f124SMoriah Waterland 	unsigned depend:1;
105*5c51f124SMoriah Waterland 	unsigned space_set:1;
106*5c51f124SMoriah Waterland 	unsigned space:1;
107*5c51f124SMoriah Waterland 	unsigned conflict_set:1;
108*5c51f124SMoriah Waterland 	unsigned conflict:1;
109*5c51f124SMoriah Waterland 	unsigned setuid_set:1;
110*5c51f124SMoriah Waterland 	unsigned setuid:1;
111*5c51f124SMoriah Waterland 	unsigned priv_set:1;
112*5c51f124SMoriah Waterland 	unsigned priv:1;
113*5c51f124SMoriah Waterland 	unsigned pkgdirs_set:1;
114*5c51f124SMoriah Waterland 	unsigned pkgdirs:1;
115*5c51f124SMoriah Waterland 	unsigned reqexit_set:1;
116*5c51f124SMoriah Waterland 	unsigned checkexit_set:1;
117*5c51f124SMoriah Waterland 
118*5c51f124SMoriah Waterland 	int	type;		/* type of operation */
119*5c51f124SMoriah Waterland 	int	reqexit;	/* request script exit code */
120*5c51f124SMoriah Waterland 	int	checkexit;	/* checkinstall script exit code */
121*5c51f124SMoriah Waterland 	int	exitcode;	/* overall program exit code. */
122*5c51f124SMoriah Waterland 
123*5c51f124SMoriah Waterland 	struct dr_pkg_entry *packages;	/* pointer to the list of packages */
124*5c51f124SMoriah Waterland 
125*5c51f124SMoriah Waterland 	int total_ext_recs;	/* total extlist entries */
126*5c51f124SMoriah Waterland 	int total_fs_recs;	/* total fs_tab entries */
127*5c51f124SMoriah Waterland 	int total_pkgs;		/* total number of dryrun packages */
128*5c51f124SMoriah Waterland 	int do_not_continue;	/* error stacking is likely */
129*5c51f124SMoriah Waterland } dr_info;
130*5c51f124SMoriah Waterland 
131*5c51f124SMoriah Waterland static char	*exitmsg;	/* the last meaningful message printed */
132*5c51f124SMoriah Waterland 
133*5c51f124SMoriah Waterland /*
134*5c51f124SMoriah Waterland  * In the event that live continue (continue from a dryrun source only)
135*5c51f124SMoriah Waterland  * becomes a feature, it will be necessary to keep track of those events such
136*5c51f124SMoriah Waterland  * as multiply edited files and files dependent upon multiple class action
137*5c51f124SMoriah Waterland  * scripts that will lead to "tolerance stacking". Calling this function
138*5c51f124SMoriah Waterland  * states that we've lost the level of precision necessary for a live
139*5c51f124SMoriah Waterland  * continue.
140*5c51f124SMoriah Waterland  */
141*5c51f124SMoriah Waterland void
set_continue_not_ok(void)142*5c51f124SMoriah Waterland set_continue_not_ok(void)
143*5c51f124SMoriah Waterland {
144*5c51f124SMoriah Waterland 	dr_info.do_not_continue = 1;
145*5c51f124SMoriah Waterland }
146*5c51f124SMoriah Waterland 
147*5c51f124SMoriah Waterland int
continue_is_ok(void)148*5c51f124SMoriah Waterland continue_is_ok(void)
149*5c51f124SMoriah Waterland {
150*5c51f124SMoriah Waterland 	return (!dr_info.do_not_continue);
151*5c51f124SMoriah Waterland }
152*5c51f124SMoriah Waterland 
153*5c51f124SMoriah Waterland static void
wr_OK(FILE * fp,char * parameter,int set,int value)154*5c51f124SMoriah Waterland wr_OK(FILE *fp, char *parameter, int set, int value)
155*5c51f124SMoriah Waterland {
156*5c51f124SMoriah Waterland 	(void) fprintf(fp, "%s=%s\n", parameter,
157*5c51f124SMoriah Waterland 		(set ? (value ? "OK" : "NOT_OK") : "NOT_TESTED"));
158*5c51f124SMoriah Waterland }
159*5c51f124SMoriah Waterland 
160*5c51f124SMoriah Waterland static void
add_pkg_to_list(char * pkgname)161*5c51f124SMoriah Waterland add_pkg_to_list(char *pkgname)
162*5c51f124SMoriah Waterland {
163*5c51f124SMoriah Waterland 	struct dr_pkg_entry **pkg_entry;
164*5c51f124SMoriah Waterland 
165*5c51f124SMoriah Waterland 	if (pkg_handle == -1) {
166*5c51f124SMoriah Waterland 		if ((pkg_handle = bl_create(MALCOUNT,
167*5c51f124SMoriah Waterland 		    sizeof (struct dr_pkg_entry), "package dryrun")) == -1)
168*5c51f124SMoriah Waterland 			return;
169*5c51f124SMoriah Waterland 	}
170*5c51f124SMoriah Waterland 
171*5c51f124SMoriah Waterland 	pkg_entry = &(dr_info.packages);
172*5c51f124SMoriah Waterland 
173*5c51f124SMoriah Waterland 	while (*pkg_entry != NULL)
174*5c51f124SMoriah Waterland 		pkg_entry = &((*pkg_entry)->next);
175*5c51f124SMoriah Waterland 
176*5c51f124SMoriah Waterland 	/* LINTED pointer cast may result in improper alignment */
177*5c51f124SMoriah Waterland 	*pkg_entry = (struct dr_pkg_entry *)bl_next_avail(pkg_handle);
178*5c51f124SMoriah Waterland 	dr_info.total_pkgs++;
179*5c51f124SMoriah Waterland 
180*5c51f124SMoriah Waterland 	(void) snprintf((*pkg_entry)->pkginst, PKGNAMESIZE, "%s%s",
181*5c51f124SMoriah Waterland 		(pkgname ? pkgname : ""), ((this_exitcode == 0) ? "" : "-"));
182*5c51f124SMoriah Waterland }
183*5c51f124SMoriah Waterland 
184*5c51f124SMoriah Waterland static void
write_pkglist_ascii(void)185*5c51f124SMoriah Waterland write_pkglist_ascii(void)
186*5c51f124SMoriah Waterland {
187*5c51f124SMoriah Waterland 	struct dr_pkg_entry *pkg_entry;
188*5c51f124SMoriah Waterland 
189*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "PKG_LIST=\"");
190*5c51f124SMoriah Waterland 
191*5c51f124SMoriah Waterland 	pkg_entry = dr_info.packages;
192*5c51f124SMoriah Waterland 	while (pkg_entry) {
193*5c51f124SMoriah Waterland 		(void) fprintf(fp_dra, " %s", pkg_entry->pkginst);
194*5c51f124SMoriah Waterland 		pkg_entry = pkg_entry->next;
195*5c51f124SMoriah Waterland 	}
196*5c51f124SMoriah Waterland 
197*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "\"\n");
198*5c51f124SMoriah Waterland }
199*5c51f124SMoriah Waterland 
200*5c51f124SMoriah Waterland static int
write_string(int fd,char * string)201*5c51f124SMoriah Waterland write_string(int fd, char *string)
202*5c51f124SMoriah Waterland {
203*5c51f124SMoriah Waterland 	int string_size;
204*5c51f124SMoriah Waterland 
205*5c51f124SMoriah Waterland 	if (string)
206*5c51f124SMoriah Waterland 		string_size = strlen(string) + 1;
207*5c51f124SMoriah Waterland 	else
208*5c51f124SMoriah Waterland 		string_size = 0;
209*5c51f124SMoriah Waterland 
210*5c51f124SMoriah Waterland 	if (write(fd, &string_size, sizeof (string_size)) == -1) {
211*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOWRITE), dryrun_bin);
212*5c51f124SMoriah Waterland 		return (0);
213*5c51f124SMoriah Waterland 	}
214*5c51f124SMoriah Waterland 
215*5c51f124SMoriah Waterland 	if (string_size > 0) {
216*5c51f124SMoriah Waterland 		if (write(fd, string, string_size) == -1) {
217*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOWRITE), dryrun_bin);
218*5c51f124SMoriah Waterland 			return (0);
219*5c51f124SMoriah Waterland 		}
220*5c51f124SMoriah Waterland 	}
221*5c51f124SMoriah Waterland 
222*5c51f124SMoriah Waterland 	return (1);
223*5c51f124SMoriah Waterland }
224*5c51f124SMoriah Waterland 
225*5c51f124SMoriah Waterland static char *
read_string(int fd,char * buffer)226*5c51f124SMoriah Waterland read_string(int fd, char *buffer)
227*5c51f124SMoriah Waterland {
228*5c51f124SMoriah Waterland 	size_t string_size;
229*5c51f124SMoriah Waterland 
230*5c51f124SMoriah Waterland 	if (read(fd, &(string_size), sizeof (string_size)) == -1) {
231*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOREAD), continue_bin);
232*5c51f124SMoriah Waterland 		return (NULL);
233*5c51f124SMoriah Waterland 	}
234*5c51f124SMoriah Waterland 
235*5c51f124SMoriah Waterland 	if (string_size != 0) {
236*5c51f124SMoriah Waterland 		if (read(fd, buffer, string_size) == -1) {
237*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOREAD), continue_bin);
238*5c51f124SMoriah Waterland 			return (NULL);
239*5c51f124SMoriah Waterland 		}
240*5c51f124SMoriah Waterland 	} else {
241*5c51f124SMoriah Waterland 		return (NULL);
242*5c51f124SMoriah Waterland 	}
243*5c51f124SMoriah Waterland 
244*5c51f124SMoriah Waterland 	return (buffer);
245*5c51f124SMoriah Waterland }
246*5c51f124SMoriah Waterland 
247*5c51f124SMoriah Waterland static void
write_dryrun_ascii()248*5c51f124SMoriah Waterland write_dryrun_ascii()
249*5c51f124SMoriah Waterland {
250*5c51f124SMoriah Waterland 	int n;
251*5c51f124SMoriah Waterland 	char *fs_mntpt, *src_name;
252*5c51f124SMoriah Waterland 
253*5c51f124SMoriah Waterland 	if ((fp_dra = fopen(dryrun_sumasc, "wb")) == NULL) {
254*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOOPEN), dryrun_sumasc);
255*5c51f124SMoriah Waterland 		return;
256*5c51f124SMoriah Waterland 	}
257*5c51f124SMoriah Waterland 
258*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "DR_TYPE=%s\n", (dr_info.type == REMOVE_TYPE ?
259*5c51f124SMoriah Waterland 	    "REMOVE" : "INSTALL"));
260*5c51f124SMoriah Waterland 
261*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "PKG_INSTALL_ROOT=%s\n", (((get_inst_root()) &&
262*5c51f124SMoriah Waterland 	    (strcmp(get_inst_root(), "/") != 0)) ?
263*5c51f124SMoriah Waterland 	    get_inst_root() : ""));
264*5c51f124SMoriah Waterland 
265*5c51f124SMoriah Waterland 	write_pkglist_ascii();
266*5c51f124SMoriah Waterland 
267*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "CONTINUE", 1, !(dr_info.do_not_continue));
268*5c51f124SMoriah Waterland 
269*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "PARTIAL", dr_info.partial_set, dr_info.partial);
270*5c51f124SMoriah Waterland 
271*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "RUNLEVEL", dr_info.runlevel_set, dr_info.runlevel);
272*5c51f124SMoriah Waterland 
273*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "REQUESTEXITCODE=%d\n", dr_info.reqexit);
274*5c51f124SMoriah Waterland 
275*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "CHECKINSTALLEXITCODE=%d\n", dr_info.checkexit);
276*5c51f124SMoriah Waterland 
277*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "PKGFILES", dr_info.pkgfiles_set, dr_info.pkgfiles);
278*5c51f124SMoriah Waterland 
279*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "DEPEND", dr_info.depend_set, dr_info.depend);
280*5c51f124SMoriah Waterland 
281*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "SPACE", dr_info.space_set, dr_info.space);
282*5c51f124SMoriah Waterland 
283*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "CONFLICT", dr_info.conflict_set, dr_info.conflict);
284*5c51f124SMoriah Waterland 
285*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "SETUID", dr_info.setuid_set, dr_info.setuid);
286*5c51f124SMoriah Waterland 
287*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "PRIV", dr_info.priv_set, dr_info.priv);
288*5c51f124SMoriah Waterland 
289*5c51f124SMoriah Waterland 	wr_OK(fp_dra, "PKGDIRS", dr_info.pkgdirs_set, dr_info.pkgdirs);
290*5c51f124SMoriah Waterland 
291*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "EXITCODE=%d\n", dr_info.exitcode);
292*5c51f124SMoriah Waterland 
293*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "ERRORMSG=%s\n", (exitmsg ? exitmsg : "NONE"));
294*5c51f124SMoriah Waterland 
295*5c51f124SMoriah Waterland 	(void) fclose(fp_dra);
296*5c51f124SMoriah Waterland 
297*5c51f124SMoriah Waterland 	if ((fp_dra = fopen(dryrun_fsasc, "wb")) == NULL) {
298*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOOPEN), dryrun_fsasc);
299*5c51f124SMoriah Waterland 		return;
300*5c51f124SMoriah Waterland 	}
301*5c51f124SMoriah Waterland 
302*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "%s\nFSUSAGE=\\\n\"\\\n", HDR_FSUSAGE);
303*5c51f124SMoriah Waterland 
304*5c51f124SMoriah Waterland 	for (n = 0; fs_mntpt = get_fs_name_n(n); n++) {
305*5c51f124SMoriah Waterland 		int bfree, bused;
306*5c51f124SMoriah Waterland 		bfree = get_blk_free_n(n);
307*5c51f124SMoriah Waterland 		bused = get_blk_used_n(n);
308*5c51f124SMoriah Waterland 
309*5c51f124SMoriah Waterland 		if (bfree || bused) {
310*5c51f124SMoriah Waterland 			(void) fprintf(fp_dra, "%s %s %s %d %d %lu %lu \\\n",
311*5c51f124SMoriah Waterland 			    fs_mntpt,
312*5c51f124SMoriah Waterland 			    ((src_name = get_source_name_n(n)) ?
313*5c51f124SMoriah Waterland 			    src_name : "none?"),
314*5c51f124SMoriah Waterland 			    (is_fs_writeable_n(n) ? "TRUE" : "FALSE"),
315*5c51f124SMoriah Waterland 			    bfree,
316*5c51f124SMoriah Waterland 			    bused,
317*5c51f124SMoriah Waterland 			    get_inode_free_n(n),
318*5c51f124SMoriah Waterland 			    get_inode_used_n(n));
319*5c51f124SMoriah Waterland 		}
320*5c51f124SMoriah Waterland 	}
321*5c51f124SMoriah Waterland 
322*5c51f124SMoriah Waterland 	dr_info.total_fs_recs = n;
323*5c51f124SMoriah Waterland 
324*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "\"\n");
325*5c51f124SMoriah Waterland 
326*5c51f124SMoriah Waterland 	(void) fclose(fp_dra);
327*5c51f124SMoriah Waterland 
328*5c51f124SMoriah Waterland 	if ((fp_dra = fopen(dryrun_poasc, "wb")) == NULL) {
329*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOOPEN), dryrun_poasc);
330*5c51f124SMoriah Waterland 		return;
331*5c51f124SMoriah Waterland 	}
332*5c51f124SMoriah Waterland 
333*5c51f124SMoriah Waterland 	dr_info.total_ext_recs = 0;
334*5c51f124SMoriah Waterland 
335*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "WOULD_INSTALL=\\\n\"\\\n");
336*5c51f124SMoriah Waterland 
337*5c51f124SMoriah Waterland 	for (n = 0; extptr && extptr[n]; n++) {
338*5c51f124SMoriah Waterland 		/*
339*5c51f124SMoriah Waterland 		 * Write it out if it's a successful change or it is from the
340*5c51f124SMoriah Waterland 		 * prior dryrun file (meaning it was a change back then).
341*5c51f124SMoriah Waterland 		 */
342*5c51f124SMoriah Waterland 		if ((this_exitcode == 0 &&
343*5c51f124SMoriah Waterland 		    (extptr[n]->mstat.contchg || extptr[n]->mstat.attrchg)) ||
344*5c51f124SMoriah Waterland 		    extptr[n]->mstat.preloaded) {
345*5c51f124SMoriah Waterland 			(void) fprintf(fp_dra, "%c %s \\\n",
346*5c51f124SMoriah Waterland 				extptr[n]->cf_ent.ftype,
347*5c51f124SMoriah Waterland 				extptr[n]->client_path);
348*5c51f124SMoriah Waterland 
349*5c51f124SMoriah Waterland 			/* Count it, if it's going into the dryrun file. */
350*5c51f124SMoriah Waterland 			if (extptr[n]->cf_ent.ftype != 'i')
351*5c51f124SMoriah Waterland 				dr_info.total_ext_recs++;
352*5c51f124SMoriah Waterland 		}
353*5c51f124SMoriah Waterland 	}
354*5c51f124SMoriah Waterland 
355*5c51f124SMoriah Waterland 	(void) fprintf(fp_dra, "\"\n");
356*5c51f124SMoriah Waterland 
357*5c51f124SMoriah Waterland 	(void) fclose(fp_dra);
358*5c51f124SMoriah Waterland }
359*5c51f124SMoriah Waterland 
360*5c51f124SMoriah Waterland /*
361*5c51f124SMoriah Waterland  * This writes out a dryrun file.
362*5c51f124SMoriah Waterland  */
363*5c51f124SMoriah Waterland static void
write_dryrun_bin()364*5c51f124SMoriah Waterland write_dryrun_bin()
365*5c51f124SMoriah Waterland {
366*5c51f124SMoriah Waterland 	struct fstable *fs_entry;
367*5c51f124SMoriah Waterland 	struct pinfo *pkginfo;
368*5c51f124SMoriah Waterland 	struct dr_pkg_entry *pkg_entry;
369*5c51f124SMoriah Waterland 	int n;
370*5c51f124SMoriah Waterland 	int fsentry_size = sizeof (struct fstable);
371*5c51f124SMoriah Waterland 	int extentry_size = sizeof (struct cfextra);
372*5c51f124SMoriah Waterland 	int pinfoentry_size = sizeof (struct pinfo);
373*5c51f124SMoriah Waterland 
374*5c51f124SMoriah Waterland 	if ((fd_drb = open(dryrun_bin,
375*5c51f124SMoriah Waterland 	    O_RDWR | O_APPEND | O_TRUNC)) == -1) {
376*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOOPEN), dryrun_bin);
377*5c51f124SMoriah Waterland 		return;
378*5c51f124SMoriah Waterland 	}
379*5c51f124SMoriah Waterland 
380*5c51f124SMoriah Waterland 	/* Write the dryrun info table. */
381*5c51f124SMoriah Waterland 	if (write(fd_drb, &dr_info, sizeof (struct drinfo)) == -1) {
382*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOWRITE), dryrun_bin);
383*5c51f124SMoriah Waterland 		return;
384*5c51f124SMoriah Waterland 	}
385*5c51f124SMoriah Waterland 
386*5c51f124SMoriah Waterland 	/* Write out the package instance list. */
387*5c51f124SMoriah Waterland 	pkg_entry = dr_info.packages;
388*5c51f124SMoriah Waterland 	while (pkg_entry) {
389*5c51f124SMoriah Waterland 		if (write(fd_drb, pkg_entry->pkginst, PKGNAMESIZE) == -1) {
390*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOWRITE), dryrun_bin);
391*5c51f124SMoriah Waterland 			return;
392*5c51f124SMoriah Waterland 		}
393*5c51f124SMoriah Waterland 		pkg_entry = pkg_entry->next;
394*5c51f124SMoriah Waterland 	}
395*5c51f124SMoriah Waterland 
396*5c51f124SMoriah Waterland 	/* Write out the fstable records. */
397*5c51f124SMoriah Waterland 	for (n = 0; n < dr_info.total_fs_recs; n++) {
398*5c51f124SMoriah Waterland 		fs_entry = get_fs_entry(n);
399*5c51f124SMoriah Waterland 
400*5c51f124SMoriah Waterland 		if (write(fd_drb, fs_entry, fsentry_size) == -1) {
401*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOWRITE), dryrun_bin);
402*5c51f124SMoriah Waterland 			return;
403*5c51f124SMoriah Waterland 		}
404*5c51f124SMoriah Waterland 
405*5c51f124SMoriah Waterland 		if (!write_string(fd_drb, fs_entry->name))
406*5c51f124SMoriah Waterland 			return;
407*5c51f124SMoriah Waterland 
408*5c51f124SMoriah Waterland 		if (!write_string(fd_drb, fs_entry->fstype))
409*5c51f124SMoriah Waterland 			return;
410*5c51f124SMoriah Waterland 
411*5c51f124SMoriah Waterland 		if (!write_string(fd_drb, fs_entry->remote_name))
412*5c51f124SMoriah Waterland 			return;
413*5c51f124SMoriah Waterland 	}
414*5c51f124SMoriah Waterland 
415*5c51f124SMoriah Waterland 	/* Write out the package objects and their attributes. */
416*5c51f124SMoriah Waterland 	for (n = 0; extptr && extptr[n]; n++) {
417*5c51f124SMoriah Waterland 		/* Don't save metafiles. */
418*5c51f124SMoriah Waterland 		if (extptr[n]->cf_ent.ftype == 'i')
419*5c51f124SMoriah Waterland 			continue;
420*5c51f124SMoriah Waterland 
421*5c51f124SMoriah Waterland 		/*
422*5c51f124SMoriah Waterland 		 * If it's a new package object (not left over from the
423*5c51f124SMoriah Waterland 		 * continuation file) and it indicates no changes to the
424*5c51f124SMoriah Waterland 		 * system, skip it. Only files that will change the system
425*5c51f124SMoriah Waterland 		 * are stored.
426*5c51f124SMoriah Waterland 		 */
427*5c51f124SMoriah Waterland 		if (extptr[n]->mstat.preloaded == 0 &&
428*5c51f124SMoriah Waterland 		    !(this_exitcode == 0 &&
429*5c51f124SMoriah Waterland 		    (extptr[n]->mstat.contchg || extptr[n]->mstat.attrchg)))
430*5c51f124SMoriah Waterland 			continue;
431*5c51f124SMoriah Waterland 
432*5c51f124SMoriah Waterland 		if (write(fd_drb, extptr[n], extentry_size) == -1) {
433*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOWRITE), dryrun_bin);
434*5c51f124SMoriah Waterland 			return;
435*5c51f124SMoriah Waterland 		}
436*5c51f124SMoriah Waterland 
437*5c51f124SMoriah Waterland 		if (!write_string(fd_drb, extptr[n]->cf_ent.path))
438*5c51f124SMoriah Waterland 			return;
439*5c51f124SMoriah Waterland 
440*5c51f124SMoriah Waterland 		if (!write_string(fd_drb, extptr[n]->cf_ent.ainfo.local))
441*5c51f124SMoriah Waterland 			return;
442*5c51f124SMoriah Waterland 
443*5c51f124SMoriah Waterland 		extptr[n]->cf_ent.pinfo = eptstat(&(extptr[n]->cf_ent),
444*5c51f124SMoriah Waterland 		    pkginst, CONFIRM_CONT);
445*5c51f124SMoriah Waterland 
446*5c51f124SMoriah Waterland 		/*
447*5c51f124SMoriah Waterland 		 * Now all of the entries about the various packages that own
448*5c51f124SMoriah Waterland 		 * this entry.
449*5c51f124SMoriah Waterland 		 */
450*5c51f124SMoriah Waterland 		pkginfo = extptr[n]->cf_ent.pinfo;
451*5c51f124SMoriah Waterland 
452*5c51f124SMoriah Waterland 		do {
453*5c51f124SMoriah Waterland 			if (write(fd_drb, pkginfo,
454*5c51f124SMoriah Waterland 			    pinfoentry_size) == -1) {
455*5c51f124SMoriah Waterland 				progerr(gettext(ERR_NOWRITE), dryrun_bin);
456*5c51f124SMoriah Waterland 				return;
457*5c51f124SMoriah Waterland 			}
458*5c51f124SMoriah Waterland 			pkginfo = pkginfo->next;	/* May be several */
459*5c51f124SMoriah Waterland 		} while (pkginfo);
460*5c51f124SMoriah Waterland 	}
461*5c51f124SMoriah Waterland 
462*5c51f124SMoriah Waterland 	(void) close(fd_drb);
463*5c51f124SMoriah Waterland }
464*5c51f124SMoriah Waterland 
465*5c51f124SMoriah Waterland static void
init_drinfo(void)466*5c51f124SMoriah Waterland init_drinfo(void) {
467*5c51f124SMoriah Waterland 
468*5c51f124SMoriah Waterland 	if (dr_info.partial != 0)
469*5c51f124SMoriah Waterland 		dr_info.partial_set = 0;
470*5c51f124SMoriah Waterland 
471*5c51f124SMoriah Waterland 	if (dr_info.runlevel != 0)
472*5c51f124SMoriah Waterland 		dr_info.runlevel_set = 0;
473*5c51f124SMoriah Waterland 
474*5c51f124SMoriah Waterland 	if (dr_info.pkgfiles != 0)
475*5c51f124SMoriah Waterland 		dr_info.pkgfiles_set = 0;
476*5c51f124SMoriah Waterland 
477*5c51f124SMoriah Waterland 	if (dr_info.depend != 0)
478*5c51f124SMoriah Waterland 		dr_info.depend_set = 0;
479*5c51f124SMoriah Waterland 
480*5c51f124SMoriah Waterland 	if (dr_info.space != 0)
481*5c51f124SMoriah Waterland 		dr_info.space_set = 0;
482*5c51f124SMoriah Waterland 
483*5c51f124SMoriah Waterland 	if (dr_info.conflict != 0)
484*5c51f124SMoriah Waterland 		dr_info.conflict_set = 0;
485*5c51f124SMoriah Waterland 
486*5c51f124SMoriah Waterland 	if (dr_info.setuid != 0)
487*5c51f124SMoriah Waterland 		dr_info.setuid_set = 0;
488*5c51f124SMoriah Waterland 
489*5c51f124SMoriah Waterland 	if (dr_info.priv != 0)
490*5c51f124SMoriah Waterland 		dr_info.priv_set = 0;
491*5c51f124SMoriah Waterland 
492*5c51f124SMoriah Waterland 	if (dr_info.pkgdirs != 0)
493*5c51f124SMoriah Waterland 		dr_info.pkgdirs_set = 0;
494*5c51f124SMoriah Waterland 
495*5c51f124SMoriah Waterland 	if (dr_info.reqexit == 0)
496*5c51f124SMoriah Waterland 		dr_info.reqexit_set = 0;
497*5c51f124SMoriah Waterland 
498*5c51f124SMoriah Waterland 	if (dr_info.checkexit == 0)
499*5c51f124SMoriah Waterland 		dr_info.checkexit_set = 0;
500*5c51f124SMoriah Waterland 
501*5c51f124SMoriah Waterland 	dr_info.packages = NULL;
502*5c51f124SMoriah Waterland 	tot_pkgs = dr_info.total_pkgs;
503*5c51f124SMoriah Waterland 	dr_info.total_pkgs = 0;
504*5c51f124SMoriah Waterland }
505*5c51f124SMoriah Waterland 
506*5c51f124SMoriah Waterland /*
507*5c51f124SMoriah Waterland  * This function reads in the various continuation file data in order to seed
508*5c51f124SMoriah Waterland  * the internal data structures.
509*5c51f124SMoriah Waterland  */
510*5c51f124SMoriah Waterland static boolean_t
read_continue_bin(void)511*5c51f124SMoriah Waterland read_continue_bin(void)
512*5c51f124SMoriah Waterland {
513*5c51f124SMoriah Waterland 	int n;
514*5c51f124SMoriah Waterland 	int fsentry_size = sizeof (struct fstable);
515*5c51f124SMoriah Waterland 	int extentry_size = sizeof (struct cfextra);
516*5c51f124SMoriah Waterland 	int pinfoentry_size = sizeof (struct pinfo);
517*5c51f124SMoriah Waterland 
518*5c51f124SMoriah Waterland 	pkgobjinit();
519*5c51f124SMoriah Waterland 	if (!init_pkgobjspace())
520*5c51f124SMoriah Waterland 		return (B_FALSE);
521*5c51f124SMoriah Waterland 
522*5c51f124SMoriah Waterland 	if ((fd_cnb = open(continue_bin, O_RDONLY)) == -1) {
523*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOOPEN), continue_bin);
524*5c51f124SMoriah Waterland 		return (B_FALSE);
525*5c51f124SMoriah Waterland 	}
526*5c51f124SMoriah Waterland 
527*5c51f124SMoriah Waterland 	/* Read the dryrun info structure. */
528*5c51f124SMoriah Waterland 	if (read(fd_cnb, &dr_info, sizeof (struct drinfo)) == -1) {
529*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOREAD), continue_bin);
530*5c51f124SMoriah Waterland 		return (B_FALSE);
531*5c51f124SMoriah Waterland 	}
532*5c51f124SMoriah Waterland 
533*5c51f124SMoriah Waterland 	init_drinfo();
534*5c51f124SMoriah Waterland 
535*5c51f124SMoriah Waterland 	if (this_type != dr_info.type) {
536*5c51f124SMoriah Waterland 		progerr(gettext(ERR_BADTYPE),
537*5c51f124SMoriah Waterland 		    (this_type == REMOVE_TYPE) ?
538*5c51f124SMoriah Waterland 		    "a remove" : "an install",
539*5c51f124SMoriah Waterland 		    (dr_info.type == REMOVE_TYPE) ?
540*5c51f124SMoriah Waterland 		    "a remove" : "an install");
541*5c51f124SMoriah Waterland 		return (B_FALSE);
542*5c51f124SMoriah Waterland 	}
543*5c51f124SMoriah Waterland 
544*5c51f124SMoriah Waterland 	/* Read in the dryrun package records. */
545*5c51f124SMoriah Waterland 	for (n = 0; n < tot_pkgs; n++) {
546*5c51f124SMoriah Waterland 		char pkg_name[PKGNAMESIZE];
547*5c51f124SMoriah Waterland 
548*5c51f124SMoriah Waterland 		if (read(fd_cnb, &pkg_name, PKGNAMESIZE) == -1) {
549*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOREAD), continue_bin);
550*5c51f124SMoriah Waterland 			return (B_FALSE);
551*5c51f124SMoriah Waterland 		}
552*5c51f124SMoriah Waterland 
553*5c51f124SMoriah Waterland 		add_pkg_to_list(pkg_name);
554*5c51f124SMoriah Waterland 	}
555*5c51f124SMoriah Waterland 
556*5c51f124SMoriah Waterland 	/* Read in the fstable records. */
557*5c51f124SMoriah Waterland 	for (n = 0; n < dr_info.total_fs_recs; n++) {
558*5c51f124SMoriah Waterland 		struct fstable fs_entry;
559*5c51f124SMoriah Waterland 		char name[PATH_MAX], remote_name[PATH_MAX];
560*5c51f124SMoriah Waterland 		char fstype[200];
561*5c51f124SMoriah Waterland 
562*5c51f124SMoriah Waterland 		if (read(fd_cnb, &fs_entry, fsentry_size) == -1) {
563*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOREAD), continue_bin);
564*5c51f124SMoriah Waterland 			return (B_FALSE);
565*5c51f124SMoriah Waterland 		}
566*5c51f124SMoriah Waterland 
567*5c51f124SMoriah Waterland 		if (read_string(fd_cnb, &name[0]) == NULL)
568*5c51f124SMoriah Waterland 			return (B_FALSE);
569*5c51f124SMoriah Waterland 
570*5c51f124SMoriah Waterland 		if (read_string(fd_cnb, &fstype[0]) == NULL)
571*5c51f124SMoriah Waterland 			return (B_FALSE);
572*5c51f124SMoriah Waterland 
573*5c51f124SMoriah Waterland 		if (read_string(fd_cnb, &remote_name[0]) == NULL)
574*5c51f124SMoriah Waterland 			return (B_FALSE);
575*5c51f124SMoriah Waterland 
576*5c51f124SMoriah Waterland 		if (load_fsentry(&fs_entry, name, fstype, remote_name)) {
577*5c51f124SMoriah Waterland 			progerr(gettext(ERR_FSFAIL));
578*5c51f124SMoriah Waterland 			return (B_FALSE);
579*5c51f124SMoriah Waterland 		}
580*5c51f124SMoriah Waterland 	}
581*5c51f124SMoriah Waterland 
582*5c51f124SMoriah Waterland 	/* Read in the package objects and their attributes. */
583*5c51f124SMoriah Waterland 	for (n = 0; n < dr_info.total_ext_recs; n++) {
584*5c51f124SMoriah Waterland 		struct cfextra ext_entry;
585*5c51f124SMoriah Waterland 		struct pinfo pinfo_area, *pinfo_ptr;
586*5c51f124SMoriah Waterland 		char path[PATH_MAX], local[PATH_MAX], *local_ptr;
587*5c51f124SMoriah Waterland 
588*5c51f124SMoriah Waterland 		if (read(fd_cnb, &ext_entry, extentry_size) == -1) {
589*5c51f124SMoriah Waterland 			progerr(gettext(ERR_NOREAD), continue_bin);
590*5c51f124SMoriah Waterland 			return (B_FALSE);
591*5c51f124SMoriah Waterland 		}
592*5c51f124SMoriah Waterland 
593*5c51f124SMoriah Waterland 		/*
594*5c51f124SMoriah Waterland 		 * If the previous dryrun replaced a directory with a
595*5c51f124SMoriah Waterland 		 * non-directory and we're going into *another* dryrun, we're
596*5c51f124SMoriah Waterland 		 * stacking errors and continuation should not be permitted.
597*5c51f124SMoriah Waterland 		 */
598*5c51f124SMoriah Waterland 		if (ext_entry.mstat.dir2nondir && dryrun_mode)
599*5c51f124SMoriah Waterland 			dr_info.do_not_continue = 1;
600*5c51f124SMoriah Waterland 
601*5c51f124SMoriah Waterland 		/*
602*5c51f124SMoriah Waterland 		 * Since we just read this from a continuation file; it is,
603*5c51f124SMoriah Waterland 		 * by definition, preloaded.
604*5c51f124SMoriah Waterland 		 */
605*5c51f124SMoriah Waterland 		ext_entry.mstat.preloaded = 1;
606*5c51f124SMoriah Waterland 
607*5c51f124SMoriah Waterland 		if (read_string(fd_cnb, &path[0]) == NULL)
608*5c51f124SMoriah Waterland 			return (B_FALSE);
609*5c51f124SMoriah Waterland 
610*5c51f124SMoriah Waterland 		local_ptr = read_string(fd_cnb, &local[0]);
611*5c51f124SMoriah Waterland 
612*5c51f124SMoriah Waterland 		ext_entry.cf_ent.pinfo = NULL;
613*5c51f124SMoriah Waterland 
614*5c51f124SMoriah Waterland 		/*
615*5c51f124SMoriah Waterland 		 * Now all of the entries about the various packages that own
616*5c51f124SMoriah Waterland 		 * this entry.
617*5c51f124SMoriah Waterland 		 */
618*5c51f124SMoriah Waterland 		do {
619*5c51f124SMoriah Waterland 			if (read(fd_cnb, &pinfo_area, pinfoentry_size) == -1) {
620*5c51f124SMoriah Waterland 				progerr(gettext(ERR_NOREAD), continue_bin);
621*5c51f124SMoriah Waterland 				return (B_FALSE);
622*5c51f124SMoriah Waterland 
623*5c51f124SMoriah Waterland 			}
624*5c51f124SMoriah Waterland 
625*5c51f124SMoriah Waterland 			pinfo_ptr = eptstat(&(ext_entry.cf_ent),
626*5c51f124SMoriah Waterland 			    pinfo_area.pkg, CONFIRM_CONT);
627*5c51f124SMoriah Waterland 
628*5c51f124SMoriah Waterland 			if (pinfo_ptr->next) {
629*5c51f124SMoriah Waterland 				pinfo_ptr = pinfo_ptr->next;
630*5c51f124SMoriah Waterland 			} else {
631*5c51f124SMoriah Waterland 				pinfo_ptr = NULL;
632*5c51f124SMoriah Waterland 			}
633*5c51f124SMoriah Waterland 
634*5c51f124SMoriah Waterland 		} while (pinfo_ptr);
635*5c51f124SMoriah Waterland 
636*5c51f124SMoriah Waterland 		seed_pkgobjmap(&ext_entry, path, local_ptr);
637*5c51f124SMoriah Waterland 	}
638*5c51f124SMoriah Waterland 
639*5c51f124SMoriah Waterland 	(void) close(fd_cnb);
640*5c51f124SMoriah Waterland 
641*5c51f124SMoriah Waterland 	/*
642*5c51f124SMoriah Waterland 	 * Return as reading is done, so pkginstall doesn't
643*5c51f124SMoriah Waterland 	 * read the same info from the system.
644*5c51f124SMoriah Waterland 	 */
645*5c51f124SMoriah Waterland 
646*5c51f124SMoriah Waterland 	return (B_TRUE);
647*5c51f124SMoriah Waterland }
648*5c51f124SMoriah Waterland 
649*5c51f124SMoriah Waterland int
in_dryrun_mode(void)650*5c51f124SMoriah Waterland in_dryrun_mode(void)
651*5c51f124SMoriah Waterland {
652*5c51f124SMoriah Waterland 	return (dryrun_mode);
653*5c51f124SMoriah Waterland }
654*5c51f124SMoriah Waterland 
655*5c51f124SMoriah Waterland void
set_dryrun_mode(void)656*5c51f124SMoriah Waterland set_dryrun_mode(void)
657*5c51f124SMoriah Waterland {
658*5c51f124SMoriah Waterland 	dryrun_mode = 1;
659*5c51f124SMoriah Waterland }
660*5c51f124SMoriah Waterland 
661*5c51f124SMoriah Waterland int
in_continue_mode(void)662*5c51f124SMoriah Waterland in_continue_mode(void)
663*5c51f124SMoriah Waterland {
664*5c51f124SMoriah Waterland 	return (continue_mode);
665*5c51f124SMoriah Waterland }
666*5c51f124SMoriah Waterland 
667*5c51f124SMoriah Waterland void
set_continue_mode(void)668*5c51f124SMoriah Waterland set_continue_mode(void)
669*5c51f124SMoriah Waterland {
670*5c51f124SMoriah Waterland 	continue_mode = 1;
671*5c51f124SMoriah Waterland }
672*5c51f124SMoriah Waterland 
673*5c51f124SMoriah Waterland /*
674*5c51f124SMoriah Waterland  * Initialize a dryrun file by assigning it a name and creating it
675*5c51f124SMoriah Waterland  * empty.
676*5c51f124SMoriah Waterland  */
677*5c51f124SMoriah Waterland static int
init_drfile(char ** targ_ptr,char * path)678*5c51f124SMoriah Waterland init_drfile(char **targ_ptr, char *path)
679*5c51f124SMoriah Waterland {
680*5c51f124SMoriah Waterland 	int n;
681*5c51f124SMoriah Waterland 	char *targ_file;
682*5c51f124SMoriah Waterland 
683*5c51f124SMoriah Waterland 	*targ_ptr = strdup(path);
684*5c51f124SMoriah Waterland 	targ_file = *targ_ptr;
685*5c51f124SMoriah Waterland 
686*5c51f124SMoriah Waterland 	if (access(targ_file, W_OK) == 0) {
687*5c51f124SMoriah Waterland 		(void) unlink(targ_file);
688*5c51f124SMoriah Waterland 	}
689*5c51f124SMoriah Waterland 
690*5c51f124SMoriah Waterland 	n = open(targ_file, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
691*5c51f124SMoriah Waterland 	if (n < 0) {
692*5c51f124SMoriah Waterland 		progerr(gettext(ERR_NOCREAT), targ_file);
693*5c51f124SMoriah Waterland 		return (0);
694*5c51f124SMoriah Waterland 	} else {
695*5c51f124SMoriah Waterland 		(void) close(n);
696*5c51f124SMoriah Waterland 	}
697*5c51f124SMoriah Waterland 
698*5c51f124SMoriah Waterland 	return (1);
699*5c51f124SMoriah Waterland }
700*5c51f124SMoriah Waterland 
701*5c51f124SMoriah Waterland /*
702*5c51f124SMoriah Waterland  * Initialize all required dryrun files and see that the target directory is
703*5c51f124SMoriah Waterland  * present. If all goes well, we're in dryrun mode. If it doesn't, we're not.
704*5c51f124SMoriah Waterland  */
705*5c51f124SMoriah Waterland void
init_dryrunfile(char * dr_dir)706*5c51f124SMoriah Waterland init_dryrunfile(char *dr_dir)
707*5c51f124SMoriah Waterland {
708*5c51f124SMoriah Waterland 	char temp_path[PATH_MAX];
709*5c51f124SMoriah Waterland 	char *dot_pos = (temp_path+strlen(dr_dir)+7);
710*5c51f124SMoriah Waterland 
711*5c51f124SMoriah Waterland 	/* First create or confirm the directory. */
712*5c51f124SMoriah Waterland 	if (isdir(dr_dir) != 0) {
713*5c51f124SMoriah Waterland 		(void) mkpath(dr_dir);
714*5c51f124SMoriah Waterland 	}
715*5c51f124SMoriah Waterland 
716*5c51f124SMoriah Waterland 	(void) snprintf(temp_path, sizeof (temp_path), "%s/dryrun", dr_dir);
717*5c51f124SMoriah Waterland 
718*5c51f124SMoriah Waterland 	(void) strcpy(dot_pos, ISUMASC_SUFFIX);
719*5c51f124SMoriah Waterland 
720*5c51f124SMoriah Waterland 	if (!init_drfile(&dryrun_sumasc, temp_path))
721*5c51f124SMoriah Waterland 		return;
722*5c51f124SMoriah Waterland 
723*5c51f124SMoriah Waterland 	(void) strcpy(dot_pos, FSASC_SUFFIX);
724*5c51f124SMoriah Waterland 
725*5c51f124SMoriah Waterland 	if (!init_drfile(&dryrun_fsasc, temp_path))
726*5c51f124SMoriah Waterland 		return;
727*5c51f124SMoriah Waterland 
728*5c51f124SMoriah Waterland 	(void) strcpy(dot_pos, IPOASC_SUFFIX);
729*5c51f124SMoriah Waterland 
730*5c51f124SMoriah Waterland 	if (!init_drfile(&dryrun_poasc, temp_path))
731*5c51f124SMoriah Waterland 		return;
732*5c51f124SMoriah Waterland 
733*5c51f124SMoriah Waterland 	(void) strcpy(dot_pos, IBIN_SUFFIX);
734*5c51f124SMoriah Waterland 
735*5c51f124SMoriah Waterland 	if (!init_drfile(&dryrun_bin, temp_path))
736*5c51f124SMoriah Waterland 		return;
737*5c51f124SMoriah Waterland 
738*5c51f124SMoriah Waterland 	dryrun_initialized = 1;
739*5c51f124SMoriah Waterland }
740*5c51f124SMoriah Waterland 
741*5c51f124SMoriah Waterland void
init_contfile(char * cn_dir)742*5c51f124SMoriah Waterland init_contfile(char *cn_dir)
743*5c51f124SMoriah Waterland {
744*5c51f124SMoriah Waterland 	char temp_path[PATH_MAX];
745*5c51f124SMoriah Waterland 
746*5c51f124SMoriah Waterland 	/* First confirm the directory. */
747*5c51f124SMoriah Waterland 	if (isdir(cn_dir) != 0)
748*5c51f124SMoriah Waterland 		return;		/* no continuation directory */
749*5c51f124SMoriah Waterland 
750*5c51f124SMoriah Waterland 	(void) snprintf(temp_path, sizeof (temp_path),
751*5c51f124SMoriah Waterland 				"%s/dryrun%s", cn_dir, IBIN_SUFFIX);
752*5c51f124SMoriah Waterland 	continue_bin = strdup(temp_path);
753*5c51f124SMoriah Waterland 
754*5c51f124SMoriah Waterland 	if (access(continue_bin, W_OK) != 0) {
755*5c51f124SMoriah Waterland 		free(continue_bin);
756*5c51f124SMoriah Waterland 		return;
757*5c51f124SMoriah Waterland 	}
758*5c51f124SMoriah Waterland 
759*5c51f124SMoriah Waterland 	continue_initialized = 1;
760*5c51f124SMoriah Waterland }
761*5c51f124SMoriah Waterland 
762*5c51f124SMoriah Waterland void
set_dr_exitmsg(char * value)763*5c51f124SMoriah Waterland set_dr_exitmsg(char *value)
764*5c51f124SMoriah Waterland {
765*5c51f124SMoriah Waterland 	exitmsg = value;
766*5c51f124SMoriah Waterland }
767*5c51f124SMoriah Waterland 
768*5c51f124SMoriah Waterland void
set_dr_info(int type,int value)769*5c51f124SMoriah Waterland set_dr_info(int type, int value)
770*5c51f124SMoriah Waterland {
771*5c51f124SMoriah Waterland 	switch (type) {
772*5c51f124SMoriah Waterland 	    case PARTIAL:
773*5c51f124SMoriah Waterland 		if (dr_info.partial_set == 0) {
774*5c51f124SMoriah Waterland 			dr_info.partial_set = 1;
775*5c51f124SMoriah Waterland 			dr_info.partial = (value ? 1 : 0);
776*5c51f124SMoriah Waterland 		}
777*5c51f124SMoriah Waterland 		break;
778*5c51f124SMoriah Waterland 
779*5c51f124SMoriah Waterland 	    case RUNLEVEL:
780*5c51f124SMoriah Waterland 		if (dr_info.runlevel_set == 0) {
781*5c51f124SMoriah Waterland 			dr_info.runlevel_set = 1;
782*5c51f124SMoriah Waterland 			dr_info.runlevel = (value ? 1 : 0);
783*5c51f124SMoriah Waterland 		}
784*5c51f124SMoriah Waterland 		break;
785*5c51f124SMoriah Waterland 
786*5c51f124SMoriah Waterland 	    case PKGFILES:
787*5c51f124SMoriah Waterland 		if (dr_info.pkgfiles_set == 0) {
788*5c51f124SMoriah Waterland 			dr_info.pkgfiles_set = 1;
789*5c51f124SMoriah Waterland 			dr_info.pkgfiles = (value ? 1 : 0);
790*5c51f124SMoriah Waterland 		}
791*5c51f124SMoriah Waterland 		break;
792*5c51f124SMoriah Waterland 
793*5c51f124SMoriah Waterland 	    case DEPEND:
794*5c51f124SMoriah Waterland 		if (dr_info.depend_set == 0) {
795*5c51f124SMoriah Waterland 			dr_info.depend_set = 1;
796*5c51f124SMoriah Waterland 			dr_info.depend = (value ? 1 : 0);
797*5c51f124SMoriah Waterland 		}
798*5c51f124SMoriah Waterland 		break;
799*5c51f124SMoriah Waterland 
800*5c51f124SMoriah Waterland 	    case SPACE:
801*5c51f124SMoriah Waterland 		if (dr_info.space_set == 0) {
802*5c51f124SMoriah Waterland 			dr_info.space_set = 1;
803*5c51f124SMoriah Waterland 			dr_info.space = (value ? 1 : 0);
804*5c51f124SMoriah Waterland 		}
805*5c51f124SMoriah Waterland 		break;
806*5c51f124SMoriah Waterland 
807*5c51f124SMoriah Waterland 	    case CONFLICT:
808*5c51f124SMoriah Waterland 		if (dr_info.conflict_set == 0) {
809*5c51f124SMoriah Waterland 			dr_info.conflict_set = 1;
810*5c51f124SMoriah Waterland 			dr_info.conflict = (value ? 1 : 0);
811*5c51f124SMoriah Waterland 		}
812*5c51f124SMoriah Waterland 		break;
813*5c51f124SMoriah Waterland 
814*5c51f124SMoriah Waterland 	    case SETUID:
815*5c51f124SMoriah Waterland 		if (dr_info.setuid_set == 0) {
816*5c51f124SMoriah Waterland 			dr_info.setuid_set = 1;
817*5c51f124SMoriah Waterland 			dr_info.setuid = (value ? 1 : 0);
818*5c51f124SMoriah Waterland 		}
819*5c51f124SMoriah Waterland 		break;
820*5c51f124SMoriah Waterland 
821*5c51f124SMoriah Waterland 	    case PRIV:
822*5c51f124SMoriah Waterland 		if (dr_info.priv_set == 0) {
823*5c51f124SMoriah Waterland 			dr_info.priv_set = 1;
824*5c51f124SMoriah Waterland 			dr_info.priv = (value ? 1 : 0);
825*5c51f124SMoriah Waterland 		}
826*5c51f124SMoriah Waterland 
827*5c51f124SMoriah Waterland 		break;
828*5c51f124SMoriah Waterland 
829*5c51f124SMoriah Waterland 	    case PKGDIRS:
830*5c51f124SMoriah Waterland 		if (dr_info.pkgdirs_set == 0) {
831*5c51f124SMoriah Waterland 			dr_info.pkgdirs_set = 1;
832*5c51f124SMoriah Waterland 			dr_info.pkgdirs = (value ? 1 : 0);
833*5c51f124SMoriah Waterland 		}
834*5c51f124SMoriah Waterland 
835*5c51f124SMoriah Waterland 		break;
836*5c51f124SMoriah Waterland 
837*5c51f124SMoriah Waterland 	    case REQUESTEXITCODE:
838*5c51f124SMoriah Waterland 		if (dr_info.reqexit_set == 0) {
839*5c51f124SMoriah Waterland 			dr_info.reqexit_set = 1;
840*5c51f124SMoriah Waterland 			dr_info.reqexit = value;
841*5c51f124SMoriah Waterland 		}
842*5c51f124SMoriah Waterland 
843*5c51f124SMoriah Waterland 		break;
844*5c51f124SMoriah Waterland 
845*5c51f124SMoriah Waterland 	    case CHECKEXITCODE:
846*5c51f124SMoriah Waterland 		if (dr_info.checkexit_set == 0) {
847*5c51f124SMoriah Waterland 			dr_info.checkexit_set = 1;
848*5c51f124SMoriah Waterland 			dr_info.checkexit = value;
849*5c51f124SMoriah Waterland 		}
850*5c51f124SMoriah Waterland 
851*5c51f124SMoriah Waterland 		break;
852*5c51f124SMoriah Waterland 
853*5c51f124SMoriah Waterland 	    case EXITCODE:
854*5c51f124SMoriah Waterland 		if (dr_info.exitcode == 0) {
855*5c51f124SMoriah Waterland 			dr_info.exitcode = value;
856*5c51f124SMoriah Waterland 		}
857*5c51f124SMoriah Waterland 
858*5c51f124SMoriah Waterland 		this_exitcode = value;
859*5c51f124SMoriah Waterland 
860*5c51f124SMoriah Waterland 		break;
861*5c51f124SMoriah Waterland 
862*5c51f124SMoriah Waterland 	    /* default to install if the value is kookie. */
863*5c51f124SMoriah Waterland 	    case DR_TYPE:
864*5c51f124SMoriah Waterland 		if (value == REMOVE_TYPE)
865*5c51f124SMoriah Waterland 			this_type = REMOVE_TYPE;
866*5c51f124SMoriah Waterland 		else
867*5c51f124SMoriah Waterland 			this_type = INSTALL_TYPE;
868*5c51f124SMoriah Waterland 
869*5c51f124SMoriah Waterland 		break;
870*5c51f124SMoriah Waterland 	}
871*5c51f124SMoriah Waterland }
872*5c51f124SMoriah Waterland 
873*5c51f124SMoriah Waterland void
write_dryrun_file(struct cfextra ** extlist)874*5c51f124SMoriah Waterland write_dryrun_file(struct cfextra **extlist)
875*5c51f124SMoriah Waterland {
876*5c51f124SMoriah Waterland 	extptr = extlist;
877*5c51f124SMoriah Waterland 
878*5c51f124SMoriah Waterland 	if (dryrun_initialized) {
879*5c51f124SMoriah Waterland 		dr_info.type = this_type;
880*5c51f124SMoriah Waterland 
881*5c51f124SMoriah Waterland 		add_pkg_to_list(pkginst);
882*5c51f124SMoriah Waterland 		write_dryrun_ascii();
883*5c51f124SMoriah Waterland 		write_dryrun_bin();
884*5c51f124SMoriah Waterland 
885*5c51f124SMoriah Waterland 		if (dryrun_mode) {
886*5c51f124SMoriah Waterland 			free(dryrun_sumasc);
887*5c51f124SMoriah Waterland 			free(dryrun_fsasc);
888*5c51f124SMoriah Waterland 			free(dryrun_poasc);
889*5c51f124SMoriah Waterland 			free(dryrun_bin);
890*5c51f124SMoriah Waterland 		}
891*5c51f124SMoriah Waterland 	}
892*5c51f124SMoriah Waterland }
893*5c51f124SMoriah Waterland 
894*5c51f124SMoriah Waterland /*
895*5c51f124SMoriah Waterland  * Name:		read_continuation
896*5c51f124SMoriah Waterland  * Description:		If continuation is initialised, reads the
897*5c51f124SMoriah Waterland  *			continuation binary file. The path for the
898*5c51f124SMoriah Waterland  *			same is freed, if set,  as this is the last
899*5c51f124SMoriah Waterland  *			chance to do so.
900*5c51f124SMoriah Waterland  * Sets:		Error condition, through the pointer passed
901*5c51f124SMoriah Waterland  *			if read failed.
902*5c51f124SMoriah Waterland  * Returns:		B_TRUE - if the continuation binary file
903*5c51f124SMoriah Waterland  *			from previous dryrun is read successfully.
904*5c51f124SMoriah Waterland  *			B_FALSE - if either continuation is not initialised
905*5c51f124SMoriah Waterland  *			or read was not successful.
906*5c51f124SMoriah Waterland  */
907*5c51f124SMoriah Waterland boolean_t
read_continuation(int * error)908*5c51f124SMoriah Waterland read_continuation(int *error)
909*5c51f124SMoriah Waterland {
910*5c51f124SMoriah Waterland 	boolean_t ret = B_FALSE;
911*5c51f124SMoriah Waterland 	*error = 0;
912*5c51f124SMoriah Waterland 	if (continue_initialized) {
913*5c51f124SMoriah Waterland 		if (!read_continue_bin()) {
914*5c51f124SMoriah Waterland 			continue_mode = 0;
915*5c51f124SMoriah Waterland 			free(continue_bin);
916*5c51f124SMoriah Waterland 			*error = -1;
917*5c51f124SMoriah Waterland 			return (ret);
918*5c51f124SMoriah Waterland 		}
919*5c51f124SMoriah Waterland 
920*5c51f124SMoriah Waterland 		if (continue_mode) {
921*5c51f124SMoriah Waterland 			free(continue_bin);
922*5c51f124SMoriah Waterland 		}
923*5c51f124SMoriah Waterland 		ret = B_TRUE;
924*5c51f124SMoriah Waterland 	}
925*5c51f124SMoriah Waterland 	return (ret);
926*5c51f124SMoriah Waterland }
927