8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / cmd / svr4pkg / libinst / dryrun.c
blobc4f08d5f7c4c5202a583dce112ec0e2f4e2a8eeb
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/wait.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <pkgstrct.h>
36 #include <unistd.h>
37 #include <pkglib.h>
38 #include <libintl.h>
39 #include "libadm.h"
40 #include "libinst.h"
41 #include "dryrun.h"
43 #define HDR_FSUSAGE "#name remote_name writeable bfree bused ifree iused"
45 #define ERR_NOCREAT "cannot create %s."
46 #define ERR_NOOPEN "cannot open %s."
47 #define ERR_NOWRITE "cannot write to %s."
48 #define ERR_NOREAD "cannot read from %s."
49 #define ERR_FSFAIL "cannot construct filesystem table entry."
50 #define ERR_BADTYPE "cannot record %s dryrun from %s continuation file."
51 #define ERR_NOCONT "cannot install from continue file due to error " \
52 "stacking."
54 #define ISUMASC_SUFFIX ".isum.asc"
55 #define FSASC_SUFFIX ".fs.asc"
56 #define IPOASC_SUFFIX ".ipo.asc"
57 #define IBIN_SUFFIX ".inst.bin"
59 #define MALCOUNT 5 /* package entries to allocate in a block */
60 #define PKGNAMESIZE 32 /* package entries to allocate in a block */
62 extern struct cfextra **extlist;
63 extern char *pkginst;
65 static struct cfextra **extptr;
66 static int dryrun_mode = 0;
67 static int continue_mode = 0;
68 static int this_exitcode = 0;
70 /* The dryrun and continuation filenames */
71 static char *dryrun_sumasc;
72 static char *dryrun_fsasc;
73 static char *dryrun_poasc;
74 static char *dryrun_bin;
75 static char *continue_bin;
77 /* These tell us if the actual files are initialized yet. */
78 static int dryrun_initialized = 0;
79 static int continue_initialized = 0;
81 static int this_type; /* type of transaction from main.c */
83 static int pkg_handle = -1;
84 static int tot_pkgs;
86 /* Their associated file pointers */
87 static FILE *fp_dra;
88 static int fd_drb;
89 static int fd_cnb;
91 struct dr_pkg_entry {
92 char pkginst[PKGNAMESIZE + 2];
93 struct dr_pkg_entry *next;
96 static struct drinfo {
97 unsigned partial_set:1; /* 1 if a partial installation was detected. */
98 unsigned partial:1; /* 1 if a partial installation was detected. */
99 unsigned runlevel_set:1;
100 unsigned runlevel:1; /* 1 if runlevel test returned an error. */
101 unsigned pkgfiles_set:1;
102 unsigned pkgfiles:1;
103 unsigned depend_set:1;
104 unsigned depend:1;
105 unsigned space_set:1;
106 unsigned space:1;
107 unsigned conflict_set:1;
108 unsigned conflict:1;
109 unsigned setuid_set:1;
110 unsigned setuid:1;
111 unsigned priv_set:1;
112 unsigned priv:1;
113 unsigned pkgdirs_set:1;
114 unsigned pkgdirs:1;
115 unsigned reqexit_set:1;
116 unsigned checkexit_set:1;
118 int type; /* type of operation */
119 int reqexit; /* request script exit code */
120 int checkexit; /* checkinstall script exit code */
121 int exitcode; /* overall program exit code. */
123 struct dr_pkg_entry *packages; /* pointer to the list of packages */
125 int total_ext_recs; /* total extlist entries */
126 int total_fs_recs; /* total fs_tab entries */
127 int total_pkgs; /* total number of dryrun packages */
128 int do_not_continue; /* error stacking is likely */
129 } dr_info;
131 static char *exitmsg; /* the last meaningful message printed */
134 * In the event that live continue (continue from a dryrun source only)
135 * becomes a feature, it will be necessary to keep track of those events such
136 * as multiply edited files and files dependent upon multiple class action
137 * scripts that will lead to "tolerance stacking". Calling this function
138 * states that we've lost the level of precision necessary for a live
139 * continue.
141 void
142 set_continue_not_ok(void)
144 dr_info.do_not_continue = 1;
148 continue_is_ok(void)
150 return (!dr_info.do_not_continue);
153 static void
154 wr_OK(FILE *fp, char *parameter, int set, int value)
156 (void) fprintf(fp, "%s=%s\n", parameter,
157 (set ? (value ? "OK" : "NOT_OK") : "NOT_TESTED"));
160 static void
161 add_pkg_to_list(char *pkgname)
163 struct dr_pkg_entry **pkg_entry;
165 if (pkg_handle == -1) {
166 if ((pkg_handle = bl_create(MALCOUNT,
167 sizeof (struct dr_pkg_entry), "package dryrun")) == -1)
168 return;
171 pkg_entry = &(dr_info.packages);
173 while (*pkg_entry != NULL)
174 pkg_entry = &((*pkg_entry)->next);
176 /* LINTED pointer cast may result in improper alignment */
177 *pkg_entry = (struct dr_pkg_entry *)bl_next_avail(pkg_handle);
178 dr_info.total_pkgs++;
180 (void) snprintf((*pkg_entry)->pkginst, PKGNAMESIZE, "%s%s",
181 (pkgname ? pkgname : ""), ((this_exitcode == 0) ? "" : "-"));
184 static void
185 write_pkglist_ascii(void)
187 struct dr_pkg_entry *pkg_entry;
189 (void) fprintf(fp_dra, "PKG_LIST=\"");
191 pkg_entry = dr_info.packages;
192 while (pkg_entry) {
193 (void) fprintf(fp_dra, " %s", pkg_entry->pkginst);
194 pkg_entry = pkg_entry->next;
197 (void) fprintf(fp_dra, "\"\n");
200 static int
201 write_string(int fd, char *string)
203 int string_size;
205 if (string)
206 string_size = strlen(string) + 1;
207 else
208 string_size = 0;
210 if (write(fd, &string_size, sizeof (string_size)) == -1) {
211 progerr(gettext(ERR_NOWRITE), dryrun_bin);
212 return (0);
215 if (string_size > 0) {
216 if (write(fd, string, string_size) == -1) {
217 progerr(gettext(ERR_NOWRITE), dryrun_bin);
218 return (0);
222 return (1);
225 static char *
226 read_string(int fd, char *buffer)
228 size_t string_size;
230 if (read(fd, &(string_size), sizeof (string_size)) == -1) {
231 progerr(gettext(ERR_NOREAD), continue_bin);
232 return (NULL);
235 if (string_size != 0) {
236 if (read(fd, buffer, string_size) == -1) {
237 progerr(gettext(ERR_NOREAD), continue_bin);
238 return (NULL);
240 } else {
241 return (NULL);
244 return (buffer);
247 static void
248 write_dryrun_ascii()
250 int n;
251 char *fs_mntpt, *src_name;
253 if ((fp_dra = fopen(dryrun_sumasc, "wb")) == NULL) {
254 progerr(gettext(ERR_NOOPEN), dryrun_sumasc);
255 return;
258 (void) fprintf(fp_dra, "DR_TYPE=%s\n", (dr_info.type == REMOVE_TYPE ?
259 "REMOVE" : "INSTALL"));
261 (void) fprintf(fp_dra, "PKG_INSTALL_ROOT=%s\n", (((get_inst_root()) &&
262 (strcmp(get_inst_root(), "/") != 0)) ?
263 get_inst_root() : ""));
265 write_pkglist_ascii();
267 wr_OK(fp_dra, "CONTINUE", 1, !(dr_info.do_not_continue));
269 wr_OK(fp_dra, "PARTIAL", dr_info.partial_set, dr_info.partial);
271 wr_OK(fp_dra, "RUNLEVEL", dr_info.runlevel_set, dr_info.runlevel);
273 (void) fprintf(fp_dra, "REQUESTEXITCODE=%d\n", dr_info.reqexit);
275 (void) fprintf(fp_dra, "CHECKINSTALLEXITCODE=%d\n", dr_info.checkexit);
277 wr_OK(fp_dra, "PKGFILES", dr_info.pkgfiles_set, dr_info.pkgfiles);
279 wr_OK(fp_dra, "DEPEND", dr_info.depend_set, dr_info.depend);
281 wr_OK(fp_dra, "SPACE", dr_info.space_set, dr_info.space);
283 wr_OK(fp_dra, "CONFLICT", dr_info.conflict_set, dr_info.conflict);
285 wr_OK(fp_dra, "SETUID", dr_info.setuid_set, dr_info.setuid);
287 wr_OK(fp_dra, "PRIV", dr_info.priv_set, dr_info.priv);
289 wr_OK(fp_dra, "PKGDIRS", dr_info.pkgdirs_set, dr_info.pkgdirs);
291 (void) fprintf(fp_dra, "EXITCODE=%d\n", dr_info.exitcode);
293 (void) fprintf(fp_dra, "ERRORMSG=%s\n", (exitmsg ? exitmsg : "NONE"));
295 (void) fclose(fp_dra);
297 if ((fp_dra = fopen(dryrun_fsasc, "wb")) == NULL) {
298 progerr(gettext(ERR_NOOPEN), dryrun_fsasc);
299 return;
302 (void) fprintf(fp_dra, "%s\nFSUSAGE=\\\n\"\\\n", HDR_FSUSAGE);
304 for (n = 0; fs_mntpt = get_fs_name_n(n); n++) {
305 int bfree, bused;
306 bfree = get_blk_free_n(n);
307 bused = get_blk_used_n(n);
309 if (bfree || bused) {
310 (void) fprintf(fp_dra, "%s %s %s %d %d %lu %lu \\\n",
311 fs_mntpt,
312 ((src_name = get_source_name_n(n)) ?
313 src_name : "none?"),
314 (is_fs_writeable_n(n) ? "TRUE" : "FALSE"),
315 bfree,
316 bused,
317 get_inode_free_n(n),
318 get_inode_used_n(n));
322 dr_info.total_fs_recs = n;
324 (void) fprintf(fp_dra, "\"\n");
326 (void) fclose(fp_dra);
328 if ((fp_dra = fopen(dryrun_poasc, "wb")) == NULL) {
329 progerr(gettext(ERR_NOOPEN), dryrun_poasc);
330 return;
333 dr_info.total_ext_recs = 0;
335 (void) fprintf(fp_dra, "WOULD_INSTALL=\\\n\"\\\n");
337 for (n = 0; extptr && extptr[n]; n++) {
339 * Write it out if it's a successful change or it is from the
340 * prior dryrun file (meaning it was a change back then).
342 if ((this_exitcode == 0 &&
343 (extptr[n]->mstat.contchg || extptr[n]->mstat.attrchg)) ||
344 extptr[n]->mstat.preloaded) {
345 (void) fprintf(fp_dra, "%c %s \\\n",
346 extptr[n]->cf_ent.ftype,
347 extptr[n]->client_path);
349 /* Count it, if it's going into the dryrun file. */
350 if (extptr[n]->cf_ent.ftype != 'i')
351 dr_info.total_ext_recs++;
355 (void) fprintf(fp_dra, "\"\n");
357 (void) fclose(fp_dra);
361 * This writes out a dryrun file.
363 static void
364 write_dryrun_bin()
366 struct fstable *fs_entry;
367 struct pinfo *pkginfo;
368 struct dr_pkg_entry *pkg_entry;
369 int n;
370 int fsentry_size = sizeof (struct fstable);
371 int extentry_size = sizeof (struct cfextra);
372 int pinfoentry_size = sizeof (struct pinfo);
374 if ((fd_drb = open(dryrun_bin,
375 O_RDWR | O_APPEND | O_TRUNC)) == -1) {
376 progerr(gettext(ERR_NOOPEN), dryrun_bin);
377 return;
380 /* Write the dryrun info table. */
381 if (write(fd_drb, &dr_info, sizeof (struct drinfo)) == -1) {
382 progerr(gettext(ERR_NOWRITE), dryrun_bin);
383 return;
386 /* Write out the package instance list. */
387 pkg_entry = dr_info.packages;
388 while (pkg_entry) {
389 if (write(fd_drb, pkg_entry->pkginst, PKGNAMESIZE) == -1) {
390 progerr(gettext(ERR_NOWRITE), dryrun_bin);
391 return;
393 pkg_entry = pkg_entry->next;
396 /* Write out the fstable records. */
397 for (n = 0; n < dr_info.total_fs_recs; n++) {
398 fs_entry = get_fs_entry(n);
400 if (write(fd_drb, fs_entry, fsentry_size) == -1) {
401 progerr(gettext(ERR_NOWRITE), dryrun_bin);
402 return;
405 if (!write_string(fd_drb, fs_entry->name))
406 return;
408 if (!write_string(fd_drb, fs_entry->fstype))
409 return;
411 if (!write_string(fd_drb, fs_entry->remote_name))
412 return;
415 /* Write out the package objects and their attributes. */
416 for (n = 0; extptr && extptr[n]; n++) {
417 /* Don't save metafiles. */
418 if (extptr[n]->cf_ent.ftype == 'i')
419 continue;
422 * If it's a new package object (not left over from the
423 * continuation file) and it indicates no changes to the
424 * system, skip it. Only files that will change the system
425 * are stored.
427 if (extptr[n]->mstat.preloaded == 0 &&
428 !(this_exitcode == 0 &&
429 (extptr[n]->mstat.contchg || extptr[n]->mstat.attrchg)))
430 continue;
432 if (write(fd_drb, extptr[n], extentry_size) == -1) {
433 progerr(gettext(ERR_NOWRITE), dryrun_bin);
434 return;
437 if (!write_string(fd_drb, extptr[n]->cf_ent.path))
438 return;
440 if (!write_string(fd_drb, extptr[n]->cf_ent.ainfo.local))
441 return;
443 extptr[n]->cf_ent.pinfo = eptstat(&(extptr[n]->cf_ent),
444 pkginst, CONFIRM_CONT);
447 * Now all of the entries about the various packages that own
448 * this entry.
450 pkginfo = extptr[n]->cf_ent.pinfo;
452 do {
453 if (write(fd_drb, pkginfo,
454 pinfoentry_size) == -1) {
455 progerr(gettext(ERR_NOWRITE), dryrun_bin);
456 return;
458 pkginfo = pkginfo->next; /* May be several */
459 } while (pkginfo);
462 (void) close(fd_drb);
465 static void
466 init_drinfo(void) {
468 if (dr_info.partial != 0)
469 dr_info.partial_set = 0;
471 if (dr_info.runlevel != 0)
472 dr_info.runlevel_set = 0;
474 if (dr_info.pkgfiles != 0)
475 dr_info.pkgfiles_set = 0;
477 if (dr_info.depend != 0)
478 dr_info.depend_set = 0;
480 if (dr_info.space != 0)
481 dr_info.space_set = 0;
483 if (dr_info.conflict != 0)
484 dr_info.conflict_set = 0;
486 if (dr_info.setuid != 0)
487 dr_info.setuid_set = 0;
489 if (dr_info.priv != 0)
490 dr_info.priv_set = 0;
492 if (dr_info.pkgdirs != 0)
493 dr_info.pkgdirs_set = 0;
495 if (dr_info.reqexit == 0)
496 dr_info.reqexit_set = 0;
498 if (dr_info.checkexit == 0)
499 dr_info.checkexit_set = 0;
501 dr_info.packages = NULL;
502 tot_pkgs = dr_info.total_pkgs;
503 dr_info.total_pkgs = 0;
507 * This function reads in the various continuation file data in order to seed
508 * the internal data structures.
510 static boolean_t
511 read_continue_bin(void)
513 int n;
514 int fsentry_size = sizeof (struct fstable);
515 int extentry_size = sizeof (struct cfextra);
516 int pinfoentry_size = sizeof (struct pinfo);
518 pkgobjinit();
519 if (!init_pkgobjspace())
520 return (B_FALSE);
522 if ((fd_cnb = open(continue_bin, O_RDONLY)) == -1) {
523 progerr(gettext(ERR_NOOPEN), continue_bin);
524 return (B_FALSE);
527 /* Read the dryrun info structure. */
528 if (read(fd_cnb, &dr_info, sizeof (struct drinfo)) == -1) {
529 progerr(gettext(ERR_NOREAD), continue_bin);
530 return (B_FALSE);
533 init_drinfo();
535 if (this_type != dr_info.type) {
536 progerr(gettext(ERR_BADTYPE),
537 (this_type == REMOVE_TYPE) ?
538 "a remove" : "an install",
539 (dr_info.type == REMOVE_TYPE) ?
540 "a remove" : "an install");
541 return (B_FALSE);
544 /* Read in the dryrun package records. */
545 for (n = 0; n < tot_pkgs; n++) {
546 char pkg_name[PKGNAMESIZE];
548 if (read(fd_cnb, &pkg_name, PKGNAMESIZE) == -1) {
549 progerr(gettext(ERR_NOREAD), continue_bin);
550 return (B_FALSE);
553 add_pkg_to_list(pkg_name);
556 /* Read in the fstable records. */
557 for (n = 0; n < dr_info.total_fs_recs; n++) {
558 struct fstable fs_entry;
559 char name[PATH_MAX], remote_name[PATH_MAX];
560 char fstype[200];
562 if (read(fd_cnb, &fs_entry, fsentry_size) == -1) {
563 progerr(gettext(ERR_NOREAD), continue_bin);
564 return (B_FALSE);
567 if (read_string(fd_cnb, &name[0]) == NULL)
568 return (B_FALSE);
570 if (read_string(fd_cnb, &fstype[0]) == NULL)
571 return (B_FALSE);
573 if (read_string(fd_cnb, &remote_name[0]) == NULL)
574 return (B_FALSE);
576 if (load_fsentry(&fs_entry, name, fstype, remote_name)) {
577 progerr(gettext(ERR_FSFAIL));
578 return (B_FALSE);
582 /* Read in the package objects and their attributes. */
583 for (n = 0; n < dr_info.total_ext_recs; n++) {
584 struct cfextra ext_entry;
585 struct pinfo pinfo_area, *pinfo_ptr;
586 char path[PATH_MAX], local[PATH_MAX], *local_ptr;
588 if (read(fd_cnb, &ext_entry, extentry_size) == -1) {
589 progerr(gettext(ERR_NOREAD), continue_bin);
590 return (B_FALSE);
594 * If the previous dryrun replaced a directory with a
595 * non-directory and we're going into *another* dryrun, we're
596 * stacking errors and continuation should not be permitted.
598 if (ext_entry.mstat.dir2nondir && dryrun_mode)
599 dr_info.do_not_continue = 1;
602 * Since we just read this from a continuation file; it is,
603 * by definition, preloaded.
605 ext_entry.mstat.preloaded = 1;
607 if (read_string(fd_cnb, &path[0]) == NULL)
608 return (B_FALSE);
610 local_ptr = read_string(fd_cnb, &local[0]);
612 ext_entry.cf_ent.pinfo = NULL;
615 * Now all of the entries about the various packages that own
616 * this entry.
618 do {
619 if (read(fd_cnb, &pinfo_area, pinfoentry_size) == -1) {
620 progerr(gettext(ERR_NOREAD), continue_bin);
621 return (B_FALSE);
625 pinfo_ptr = eptstat(&(ext_entry.cf_ent),
626 pinfo_area.pkg, CONFIRM_CONT);
628 if (pinfo_ptr->next) {
629 pinfo_ptr = pinfo_ptr->next;
630 } else {
631 pinfo_ptr = NULL;
634 } while (pinfo_ptr);
636 seed_pkgobjmap(&ext_entry, path, local_ptr);
639 (void) close(fd_cnb);
642 * Return as reading is done, so pkginstall doesn't
643 * read the same info from the system.
646 return (B_TRUE);
650 in_dryrun_mode(void)
652 return (dryrun_mode);
655 void
656 set_dryrun_mode(void)
658 dryrun_mode = 1;
662 in_continue_mode(void)
664 return (continue_mode);
667 void
668 set_continue_mode(void)
670 continue_mode = 1;
674 * Initialize a dryrun file by assigning it a name and creating it
675 * empty.
677 static int
678 init_drfile(char **targ_ptr, char *path)
680 int n;
681 char *targ_file;
683 *targ_ptr = strdup(path);
684 targ_file = *targ_ptr;
686 if (access(targ_file, W_OK) == 0) {
687 (void) unlink(targ_file);
690 n = open(targ_file, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
691 if (n < 0) {
692 progerr(gettext(ERR_NOCREAT), targ_file);
693 return (0);
694 } else {
695 (void) close(n);
698 return (1);
702 * Initialize all required dryrun files and see that the target directory is
703 * present. If all goes well, we're in dryrun mode. If it doesn't, we're not.
705 void
706 init_dryrunfile(char *dr_dir)
708 char temp_path[PATH_MAX];
709 char *dot_pos = (temp_path+strlen(dr_dir)+7);
711 /* First create or confirm the directory. */
712 if (isdir(dr_dir) != 0) {
713 (void) mkpath(dr_dir);
716 (void) snprintf(temp_path, sizeof (temp_path), "%s/dryrun", dr_dir);
718 (void) strcpy(dot_pos, ISUMASC_SUFFIX);
720 if (!init_drfile(&dryrun_sumasc, temp_path))
721 return;
723 (void) strcpy(dot_pos, FSASC_SUFFIX);
725 if (!init_drfile(&dryrun_fsasc, temp_path))
726 return;
728 (void) strcpy(dot_pos, IPOASC_SUFFIX);
730 if (!init_drfile(&dryrun_poasc, temp_path))
731 return;
733 (void) strcpy(dot_pos, IBIN_SUFFIX);
735 if (!init_drfile(&dryrun_bin, temp_path))
736 return;
738 dryrun_initialized = 1;
741 void
742 init_contfile(char *cn_dir)
744 char temp_path[PATH_MAX];
746 /* First confirm the directory. */
747 if (isdir(cn_dir) != 0)
748 return; /* no continuation directory */
750 (void) snprintf(temp_path, sizeof (temp_path),
751 "%s/dryrun%s", cn_dir, IBIN_SUFFIX);
752 continue_bin = strdup(temp_path);
754 if (access(continue_bin, W_OK) != 0) {
755 free(continue_bin);
756 return;
759 continue_initialized = 1;
762 void
763 set_dr_exitmsg(char *value)
765 exitmsg = value;
768 void
769 set_dr_info(int type, int value)
771 switch (type) {
772 case PARTIAL:
773 if (dr_info.partial_set == 0) {
774 dr_info.partial_set = 1;
775 dr_info.partial = (value ? 1 : 0);
777 break;
779 case RUNLEVEL:
780 if (dr_info.runlevel_set == 0) {
781 dr_info.runlevel_set = 1;
782 dr_info.runlevel = (value ? 1 : 0);
784 break;
786 case PKGFILES:
787 if (dr_info.pkgfiles_set == 0) {
788 dr_info.pkgfiles_set = 1;
789 dr_info.pkgfiles = (value ? 1 : 0);
791 break;
793 case DEPEND:
794 if (dr_info.depend_set == 0) {
795 dr_info.depend_set = 1;
796 dr_info.depend = (value ? 1 : 0);
798 break;
800 case SPACE:
801 if (dr_info.space_set == 0) {
802 dr_info.space_set = 1;
803 dr_info.space = (value ? 1 : 0);
805 break;
807 case CONFLICT:
808 if (dr_info.conflict_set == 0) {
809 dr_info.conflict_set = 1;
810 dr_info.conflict = (value ? 1 : 0);
812 break;
814 case SETUID:
815 if (dr_info.setuid_set == 0) {
816 dr_info.setuid_set = 1;
817 dr_info.setuid = (value ? 1 : 0);
819 break;
821 case PRIV:
822 if (dr_info.priv_set == 0) {
823 dr_info.priv_set = 1;
824 dr_info.priv = (value ? 1 : 0);
827 break;
829 case PKGDIRS:
830 if (dr_info.pkgdirs_set == 0) {
831 dr_info.pkgdirs_set = 1;
832 dr_info.pkgdirs = (value ? 1 : 0);
835 break;
837 case REQUESTEXITCODE:
838 if (dr_info.reqexit_set == 0) {
839 dr_info.reqexit_set = 1;
840 dr_info.reqexit = value;
843 break;
845 case CHECKEXITCODE:
846 if (dr_info.checkexit_set == 0) {
847 dr_info.checkexit_set = 1;
848 dr_info.checkexit = value;
851 break;
853 case EXITCODE:
854 if (dr_info.exitcode == 0) {
855 dr_info.exitcode = value;
858 this_exitcode = value;
860 break;
862 /* default to install if the value is kookie. */
863 case DR_TYPE:
864 if (value == REMOVE_TYPE)
865 this_type = REMOVE_TYPE;
866 else
867 this_type = INSTALL_TYPE;
869 break;
873 void
874 write_dryrun_file(struct cfextra **extlist)
876 extptr = extlist;
878 if (dryrun_initialized) {
879 dr_info.type = this_type;
881 add_pkg_to_list(pkginst);
882 write_dryrun_ascii();
883 write_dryrun_bin();
885 if (dryrun_mode) {
886 free(dryrun_sumasc);
887 free(dryrun_fsasc);
888 free(dryrun_poasc);
889 free(dryrun_bin);
895 * Name: read_continuation
896 * Description: If continuation is initialised, reads the
897 * continuation binary file. The path for the
898 * same is freed, if set, as this is the last
899 * chance to do so.
900 * Sets: Error condition, through the pointer passed
901 * if read failed.
902 * Returns: B_TRUE - if the continuation binary file
903 * from previous dryrun is read successfully.
904 * B_FALSE - if either continuation is not initialised
905 * or read was not successful.
907 boolean_t
908 read_continuation(int *error)
910 boolean_t ret = B_FALSE;
911 *error = 0;
912 if (continue_initialized) {
913 if (!read_continue_bin()) {
914 continue_mode = 0;
915 free(continue_bin);
916 *error = -1;
917 return (ret);
920 if (continue_mode) {
921 free(continue_bin);
923 ret = B_TRUE;
925 return (ret);