xref: /illumos-gate/usr/src/lib/libpkg/common/pkgtrans.c (revision 20a7641f9918de8574b8b3b47dbe35c4bfc78df1)
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) 2017 Peter Tribble.
24  */
25 
26 /*
27  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
32 /* All Rights Reserved */
33 
34 
35 
36 #include <stdio.h>
37 #include <errno.h>
38 #include <stdarg.h>
39 #include <limits.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <fcntl.h>
43 #include <ctype.h>
44 #include <string.h>
45 #include <sys/types.h>
46 #include <sys/param.h>
47 #include <sys/stat.h>
48 #include <sys/statvfs.h>
49 #include <sys/sysmacros.h>
50 #include <dirent.h>
51 #include <signal.h>
52 #include <devmgmt.h>
53 #include <note.h>
54 #include "pkginfo.h"
55 #include "pkgstrct.h"
56 #include "pkgtrans.h"
57 #include "pkgdev.h"
58 #include "pkglib.h"
59 #include "pkglibmsgs.h"
60 #include "pkglocale.h"
61 
62 extern char	*pkgdir;		/* pkgparam.c */
63 
64 /* libadm.a */
65 extern char	*devattr(char *device, char *attribute);
66 extern char	*fpkginst(char *pkg, ...);
67 extern int	fpkginfo(struct pkginfo *info, char *pkginst);
68 extern int	getvol(char *device, char *label, int options, char *prompt);
69 extern int	_getvol(char *device, char *label, int options, char *prompt,
70 			char *norewind);
71 
72 /* dstream.c */
73 extern int	ds_ginit(char *device);
74 extern int	ds_close(int pkgendflg);
75 
76 #define	CPIOPROC	"/usr/bin/cpio"
77 
78 #define	CMDSIZE	512	/* command block size */
79 
80 #define	BLK_SIZE	512		/* size of logical block */
81 
82 #define	ENTRY_MAX	256 /* max size of entry for cpio cmd or header */
83 
84 #define	PKGINFO	"pkginfo"
85 #define	PKGMAP	"pkgmap"
86 #define	MAP_STAT_SIZE	60	/* 1st line of pkgmap (3 numbers & a : */
87 
88 #define	INSTALL	"install"
89 #define	RELOC	"reloc"
90 #define	ROOT	"root"
91 #define	ARCHIVE	"archive"
92 
93 static struct	pkgdev srcdev, dstdev;
94 static char	*tmpdir;
95 static char	*tmppath;
96 static char	*tmpsymdir = NULL;
97 static char	dstinst[NON_ABI_NAMELNGTH];
98 static char	*ids_name, *ods_name;
99 static int	ds_volcnt;
100 static int	ds_volno;
101 static int	compressedsize, has_comp_size;
102 
103 static void	(*sigintHandler)();
104 static void	(*sighupHandler)();
105 static void	cleanup(void);
106 static void	sigtrap(int signo);
107 static int	rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize);
108 
109 static int	cat_and_count(struct dm_buf *, char *);
110 
111 static int	ckoverwrite(char *dir, char *inst, int options);
112 static int	pkgxfer(char *srcinst, int options);
113 static int	wdsheader(struct dm_buf *, char *device, char **pkg);
114 static struct dm_buf	*genheader(char *, char **);
115 
116 extern int	ds_fd;	/* open file descriptor for data stream WHERE? */
117 
118 static char *root_names[] = {
119 	"root",
120 	"root.cpio",
121 	"root.Z",
122 	"root.cpio.Z",
123 	0
124 };
125 
126 static char *reloc_names[] = {
127 	"reloc",
128 	"reloc.cpio",
129 	"reloc.Z",
130 	"reloc.cpio.Z",
131 	0
132 };
133 
134 static int	signal_received = 0;
135 
136 char	**xpkg;		/* array of transferred packages */
137 int	nxpkg;
138 
139 static	char *allpkg[] = {
140 	"all",
141 	NULL
142 };
143 
144 static struct dm_buf hdrbuf;
145 static char *pinput, *nextpinput;
146 
147 int
148 pkghead(char *device)
149 {
150 	char	*pt;
151 	int	n;
152 
153 	cleanup();
154 
155 
156 	if (device == NULL)
157 		return (0);
158 	else if ((device[0] == '/') && !isdir(device)) {
159 		pkgdir = device;
160 		return (0);
161 	} else if ((pt = devattr(device, "pathname")) != NULL && !isdir(pt)) {
162 		pkgdir = pt;
163 		return (0);
164 	}
165 
166 	/* check for datastream */
167 	if (n = pkgtrans(device, (char *)0, allpkg, PT_SILENT|PT_INFO_ONLY)) {
168 		cleanup();
169 		return (n);
170 	}
171 		/* pkgtrans has set pkgdir */
172 	return (0);
173 }
174 
175 static char *
176 mgets(char *buf, int size)
177 {
178 	nextpinput = strchr(pinput, '\n');
179 	if (nextpinput == NULL)
180 		return (0);
181 	*nextpinput = '\0';
182 	if ((int)strlen(pinput) > size)
183 		return (0);
184 	(void) strncpy(buf, pinput, strlen(pinput));
185 	buf[strlen(pinput)] = '\0';
186 	pinput = nextpinput + 1;
187 	return (buf);
188 }
189 /*
190  * Here we construct the package size summaries for the headers. The
191  * pkgmap file associated with fp must be rewound to the beginning of the
192  * file. Note that we read three values from pkgmap first line in order
193  * to get the *actual* size if this package is compressed.
194  * This returns
195  *	0 : error
196  *	2 : not a compressed package
197  *	3 : compressed package
198  * and sets has_comp_size to indicate whether or not this is a compressed
199  * package.
200  */
201 static int
202 rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize)
203 {
204 	int n;
205 	char line_buffer[MAP_STAT_SIZE];
206 
207 	/* First read the null terminated first line */
208 	if (fgets(line_buffer, MAP_STAT_SIZE, fp) == NULL) {
209 		progerr(pkg_gt(ERR_TRANSFER));
210 		logerr(pkg_gt(MSG_NOSIZE));
211 		(void) fclose(fp);
212 		ecleanup();
213 		return (0);
214 	}
215 
216 	n = sscanf(line_buffer, ": %d %d %d", npts, maxpsz, cmpsize);
217 
218 	if (n == 3)		/* A valid compressed package entry */
219 		has_comp_size = 1;
220 	else if (n == 2)	/* A valid standard package entry */
221 		has_comp_size = 0;
222 	else {			/* invalid entry */
223 		progerr(pkg_gt(ERR_TRANSFER));
224 		logerr(pkg_gt(MSG_NOSIZE));
225 		(void) fclose(fp);
226 		ecleanup();
227 		return (0);
228 	}
229 
230 	return (n);
231 }
232 
233 /* will return 0, 1, 3, or 99 */
234 static int
235 _pkgtrans(char *device1, char *device2, char **pkg, int options)
236 {
237 	char			*src, *dst;
238 	int			errflg, i, n;
239 	struct			dm_buf *hdr;
240 
241 	if (signal_received > 0) {
242 		return (1);
243 	}
244 
245 	/* transfer spool to appropriate device */
246 	if (devtype(device1, &srcdev)) {
247 		progerr(pkg_gt(ERR_TRANSFER));
248 		logerr(pkg_gt(MSG_BADDEV), device1);
249 		return (1);
250 	}
251 	srcdev.rdonly++;
252 
253 	/* check for datastream */
254 	ids_name = NULL;
255 	if (srcdev.bdevice) {
256 		if (n = _getvol(srcdev.bdevice, NULL, 0,
257 		    pkg_gt("Insert %v into %p."), srcdev.norewind)) {
258 			cleanup();
259 			if (n == 3)
260 				return (3);
261 			progerr(pkg_gt(ERR_TRANSFER));
262 			logerr(pkg_gt(MSG_GETVOL));
263 			return (1);
264 		}
265 		if (ds_readbuf(srcdev.cdevice))
266 			ids_name = srcdev.cdevice;
267 	}
268 
269 	if (srcdev.cdevice && !srcdev.bdevice)
270 		ids_name = srcdev.cdevice;
271 	else if (srcdev.pathname) {
272 		ids_name = srcdev.pathname;
273 		if (access(ids_name, 0) == -1) {
274 			progerr(ERR_TRANSFER);
275 			logerr(pkg_gt(MSG_GETVOL));
276 			return (1);
277 		}
278 	}
279 
280 	if (!ids_name && device2 == (char *)0) {
281 		if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) {
282 			cleanup();
283 			return (n);
284 		}
285 		if (srcdev.mount && *srcdev.mount)
286 			pkgdir = strdup(srcdev.mount);
287 		return (0);
288 	}
289 
290 	if (ids_name && device2 == (char *)0) {
291 		tmppath = tmpnam(NULL);
292 		tmppath = strdup(tmppath);
293 		if (tmppath == NULL) {
294 			progerr(pkg_gt(ERR_TRANSFER));
295 			logerr(pkg_gt(MSG_MEM));
296 			return (1);
297 		}
298 		if (mkdir(tmppath, 0755)) {
299 			progerr(pkg_gt(ERR_TRANSFER));
300 			logerr(pkg_gt(MSG_MKDIR), tmppath);
301 			return (1);
302 		}
303 		device2 = tmppath;
304 	}
305 
306 	if (devtype(device2, &dstdev)) {
307 		progerr(pkg_gt(ERR_TRANSFER));
308 		logerr(pkg_gt(MSG_BADDEV), device2);
309 		return (1);
310 	}
311 
312 	if ((srcdev.cdevice && dstdev.cdevice) &&
313 	    strcmp(srcdev.cdevice, dstdev.cdevice) == 0) {
314 		progerr(pkg_gt(ERR_TRANSFER));
315 		logerr(pkg_gt(MSG_SAMEDEV));
316 		return (1);
317 	}
318 
319 	ods_name = NULL;
320 	if (dstdev.cdevice && !dstdev.bdevice || dstdev.pathname)
321 		options |= PT_ODTSTREAM;
322 
323 	if (options & PT_ODTSTREAM) {
324 		if (!((ods_name = dstdev.cdevice) != NULL ||
325 		    (ods_name = dstdev.pathname) != NULL)) {
326 			progerr(pkg_gt(ERR_TRANSFER));
327 			logerr(pkg_gt(MSG_BADDEV), device2);
328 			return (1);
329 		}
330 		if (ids_name) {
331 			progerr(pkg_gt(ERR_TRANSFER));
332 			logerr(pkg_gt(MSG_TWODSTREAM));
333 			return (1);
334 		}
335 	}
336 
337 	if ((srcdev.dirname && dstdev.dirname) &&
338 	    strcmp(srcdev.dirname, dstdev.dirname) == 0) {
339 		progerr(pkg_gt(ERR_TRANSFER));
340 		logerr(pkg_gt(MSG_SAMEDEV));
341 		return (1);
342 	}
343 
344 	if ((srcdev.pathname && dstdev.pathname) &&
345 	    strcmp(srcdev.pathname, dstdev.pathname) == 0) {
346 		progerr(pkg_gt(ERR_TRANSFER));
347 		logerr(pkg_gt(MSG_SAMEDEV));
348 		return (1);
349 	}
350 
351 	if (signal_received > 0) {
352 		return (1);
353 	}
354 
355 	if (ids_name) {
356 		if (srcdev.cdevice && !srcdev.bdevice &&
357 		    (n = _getvol(srcdev.cdevice, NULL, 0, NULL,
358 		    srcdev.norewind))) {
359 			cleanup();
360 			if (n == 3)
361 				return (3);
362 			progerr(pkg_gt(ERR_TRANSFER));
363 			logerr(pkg_gt(MSG_GETVOL));
364 			return (1);
365 		}
366 		if (srcdev.dirname = tmpnam(NULL))
367 			tmpdir = srcdev.dirname = strdup(srcdev.dirname);
368 
369 		if ((srcdev.dirname == NULL) || mkdir(srcdev.dirname, 0755) ||
370 		    chdir(srcdev.dirname)) {
371 			progerr(pkg_gt(ERR_TRANSFER));
372 			logerr(pkg_gt(MSG_NOTEMP), srcdev.dirname);
373 			cleanup();
374 			return (1);
375 		}
376 		if (ds_init(ids_name, pkg, srcdev.norewind)) {
377 			cleanup();
378 			return (1);
379 		}
380 	} else if (srcdev.mount) {
381 		if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) {
382 			cleanup();
383 			return (n);
384 		}
385 	}
386 
387 	src = srcdev.dirname;
388 	dst = dstdev.dirname;
389 
390 	if (chdir(src)) {
391 		progerr(pkg_gt(ERR_TRANSFER));
392 		logerr(pkg_gt(MSG_CHDIR), src);
393 		cleanup();
394 		return (1);
395 	}
396 
397 	if (signal_received > 0) {
398 		return (1);
399 	}
400 
401 	xpkg = pkg = gpkglist(src, pkg, NULL);
402 	if (!pkg) {
403 		progerr(pkg_gt(ERR_TRANSFER));
404 		logerr(pkg_gt(MSG_NOPKGS), src);
405 		cleanup();
406 		return (1);
407 	}
408 
409 	for (nxpkg = 0; pkg[nxpkg]; /* void */) {
410 		nxpkg++; /* count */
411 	}
412 
413 	if (ids_name) {
414 		ds_order(pkg); /* order requests */
415 	}
416 
417 	if (signal_received > 0) {
418 		return (1);
419 	}
420 
421 	if (options & PT_ODTSTREAM) {
422 		char line[128];
423 
424 		if (!dstdev.pathname &&
425 		    (n = _getvol(ods_name, NULL, DM_FORMAT, NULL,
426 		    dstdev.norewind))) {
427 			cleanup();
428 			if (n == 3)
429 				return (3);
430 			progerr(pkg_gt(ERR_TRANSFER));
431 			logerr(pkg_gt(MSG_GETVOL));
432 			return (1);
433 		}
434 		if ((hdr = genheader(src, pkg)) == NULL) {
435 			cleanup();
436 			return (1);
437 		}
438 
439 		/* write out header to stream */
440 		if (wdsheader(hdr, ods_name, pkg)) {
441 			cleanup();
442 			return (1);
443 		}
444 
445 		ds_volno = 1; /* number of volumes in datastream */
446 		pinput = hdrbuf.text_buffer;
447 		/* skip past first line in header */
448 		(void) mgets(line, 128);
449 	}
450 
451 	if (signal_received > 0) {
452 		return (1);
453 	}
454 
455 	errflg = 0;
456 
457 	for (i = 0; pkg[i]; i++) {
458 
459 		if (signal_received > 0) {
460 			return (1);
461 		}
462 
463 		if (!(options & PT_ODTSTREAM) && dstdev.mount) {
464 			if (n = pkgmount(&dstdev, NULL, 0, 0, 1)) {
465 				cleanup();
466 				return (n);
467 			}
468 		}
469 		if (errflg = pkgxfer(pkg[i], options)) {
470 			pkg[i] = NULL;
471 			if ((options & PT_ODTSTREAM) || (errflg != 2))
472 				break;
473 		} else if (strcmp(dstinst, pkg[i]))
474 			pkg[i] = strdup(dstinst);
475 	}
476 
477 	if (!(options & PT_ODTSTREAM) && dst) {
478 		pkgdir = strdup(dst);
479 	}
480 
481 	/*
482 	 * No cleanup of temporary directories created in this
483 	 * function is done here. The calling function must do
484 	 * the cleanup.
485 	 */
486 
487 	return (signal_received > 0 ? 1 : errflg);
488 }
489 
490 int
491 pkgtrans(char *device1, char *device2, char **pkg, int options)
492 {
493 	int			r;
494 	struct sigaction	nact;
495 	struct sigaction	oact;
496 
497 	/*
498 	 * setup signal handlers for SIGINT and SIGHUP and release hold
499 	 */
500 
501 	/* hold SIGINT/SIGHUP interrupts */
502 
503 	(void) sighold(SIGHUP);
504 	(void) sighold(SIGINT);
505 
506 	/* hook SIGINT to sigtrap */
507 
508 	nact.sa_handler = sigtrap;
509 	nact.sa_flags = SA_RESTART;
510 	(void) sigemptyset(&nact.sa_mask);
511 
512 	if (sigaction(SIGINT, &nact, &oact) < 0) {
513 		sigintHandler = SIG_DFL;
514 	} else {
515 		sigintHandler = oact.sa_handler;
516 	}
517 
518 	/* hook SIGHUP to sigtrap */
519 
520 	nact.sa_handler = sigtrap;
521 	nact.sa_flags = SA_RESTART;
522 	(void) sigemptyset(&nact.sa_mask);
523 
524 	if (sigaction(SIGHUP, &nact, &oact) < 0) {
525 		sighupHandler = SIG_DFL;
526 	} else {
527 		sighupHandler = oact.sa_handler;
528 	}
529 
530 	/* reset signal received count */
531 
532 	signal_received = 0;
533 
534 	/* release hold on signals */
535 
536 	(void) sigrelse(SIGHUP);
537 	(void) sigrelse(SIGINT);
538 
539 	/*
540 	 * perform the package translation
541 	 */
542 
543 	r = _pkgtrans(device1, device2, pkg, options);
544 
545 	/*
546 	 * reset signal handlers
547 	 */
548 
549 	/* hold SIGINT/SIGHUP interrupts */
550 
551 	(void) sighold(SIGHUP);
552 	(void) sighold(SIGINT);
553 
554 	/* reset SIGINT */
555 
556 	nact.sa_handler = sigintHandler;
557 	nact.sa_flags = SA_RESTART;
558 	(void) sigemptyset(&nact.sa_mask);
559 
560 	(void) sigaction(SIGINT, &nact, (struct sigaction *)NULL);
561 
562 	/* reset SIGHUP */
563 
564 	nact.sa_handler = sighupHandler;
565 	nact.sa_flags = SA_RESTART;
566 	(void) sigemptyset(&nact.sa_mask);
567 
568 	(void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL);
569 
570 	/* if signal received and pkgtrans returned error, call cleanup */
571 
572 	if (signal_received > 0) {
573 		if (r != 0) {
574 			cleanup();
575 		}
576 		(void) kill(getpid(), SIGINT);
577 	}
578 
579 	/* release hold on signals */
580 
581 	(void) sigrelse(SIGHUP);
582 	(void) sigrelse(SIGINT);
583 
584 	return (r);
585 }
586 
587 /*
588  * This function concatenates append to the text described in the buf_ctrl
589  * structure. This code modifies data in this structure and handles all
590  * allocation issues. It returns '0' if everything was successful and '1'
591  * if not.
592  */
593 static int
594 cat_and_count(struct dm_buf *buf_ctrl, char *append)
595 {
596 
597 	/* keep allocating until we have enough room to hold string */
598 	while ((buf_ctrl->offset + (int)strlen(append))
599 	    >= buf_ctrl->allocation) {
600 		/* reallocate (and maybe move) text buffer */
601 		if ((buf_ctrl->text_buffer =
602 		    (char *)realloc(buf_ctrl->text_buffer,
603 		    buf_ctrl->allocation + BLK_SIZE)) == NULL) {
604 			progerr(pkg_gt(ERR_TRANSFER));
605 			logerr(pkg_gt(MSG_MEM));
606 			free(buf_ctrl->text_buffer);
607 			return (1);
608 		}
609 
610 		/* clear the new memory */
611 		(void) memset(buf_ctrl->text_buffer +
612 		    buf_ctrl->allocation, '\0', BLK_SIZE);
613 
614 		/* adjust total allocation */
615 		buf_ctrl->allocation += BLK_SIZE;
616 	}
617 
618 	/* append new string to end of buffer */
619 	while (*append) {
620 		*(buf_ctrl->text_buffer + buf_ctrl->offset) = *append++;
621 		(buf_ctrl->offset)++;
622 	}
623 
624 	return (0);
625 }
626 
627 static struct dm_buf *
628 genheader(char *src, char **pkg)
629 {
630 
631 	FILE	*fp;
632 	char	path[MAXPATHLEN], tmp_entry[ENTRY_MAX];
633 	int	i, n, nparts, maxpsize;
634 	int	partcnt;
635 	long	totsize;
636 	struct stat statbuf;
637 
638 	if ((hdrbuf.text_buffer = (char *)malloc(BLK_SIZE)) == NULL) {
639 		progerr(pkg_gt(ERR_TRANSFER));
640 		logerr(pkg_gt(MSG_MEM));
641 		return (NULL);
642 	}
643 
644 	/* clear the new memory */
645 	(void) memset(hdrbuf.text_buffer, '\0', BLK_SIZE);
646 
647 	/* set up the buffer control structure for the header */
648 	hdrbuf.offset = 0;
649 	hdrbuf.allocation = BLK_SIZE;
650 
651 	(void) cat_and_count(&hdrbuf, HDR_PREFIX);
652 	(void) cat_and_count(&hdrbuf, "\n");
653 
654 	nparts = maxpsize = 0;
655 
656 	totsize = 0;
657 	for (i = 0; pkg[i]; i++)  {
658 		(void) snprintf(path, MAXPATHLEN, "%s/%s/%s",
659 		    src, pkg[i], PKGINFO);
660 		if (stat(path, &statbuf) < 0) {
661 			progerr(pkg_gt(ERR_TRANSFER));
662 			logerr(pkg_gt(MSG_BADPKGINFO));
663 			ecleanup();
664 			return (NULL);
665 		}
666 		totsize += statbuf.st_size/BLK_SIZE + 1;
667 	}
668 
669 	/*
670 	 * totsize contains number of blocks used by the pkginfo files
671 	 */
672 	totsize += i/4 + 1;
673 	if (dstdev.capacity && totsize > dstdev.capacity) {
674 		progerr(pkg_gt(ERR_TRANSFER));
675 		logerr(pkg_gt(MSG_NOSPACE), totsize, dstdev.capacity);
676 		ecleanup();
677 		return (NULL);
678 	}
679 
680 	ds_volcnt = 1;
681 	for (i = 0; pkg[i]; i++) {
682 		partcnt = 0;
683 		(void) snprintf(path, MAXPATHLEN, "%s/%s/%s",
684 		    src, pkg[i], PKGMAP);
685 		if ((fp = fopen(path, "r")) == NULL) {
686 			progerr(pkg_gt(ERR_TRANSFER));
687 			logerr(pkg_gt(MSG_NOPKGMAP), pkg[i]);
688 			ecleanup();
689 			return (NULL);
690 		}
691 
692 		/* Evaluate the first entry in pkgmap */
693 		n = rd_map_size(fp, &nparts, &maxpsize, &compressedsize);
694 
695 		if (n == 3)	/* It's a compressed package */
696 			/* The header needs the *real* size */
697 			maxpsize = compressedsize;
698 		else if (n == 0)	/* pkgmap is corrupt */
699 			return (NULL);
700 
701 		if (dstdev.capacity && maxpsize > dstdev.capacity) {
702 			progerr(pkg_gt(ERR_TRANSFER));
703 			logerr(pkg_gt(MSG_NOSPACE), (long)maxpsize,
704 			    dstdev.capacity);
705 			(void) fclose(fp);
706 			ecleanup();
707 			return (NULL);
708 		}
709 
710 		/* add pkg name, number of parts and the max part size */
711 		if (snprintf(tmp_entry, ENTRY_MAX, "%s %d %d",
712 		    pkg[i], nparts, maxpsize) >= ENTRY_MAX) {
713 			progerr(pkg_gt(ERR_TRANSFER));
714 			logerr(pkg_gt(ERR_MEM));
715 			(void) fclose(fp);
716 			ecleanup();
717 			return (NULL);
718 		}
719 		if (cat_and_count(&hdrbuf, tmp_entry)) {
720 			progerr(pkg_gt(ERR_TRANSFER));
721 			logerr(pkg_gt(MSG_MEM));
722 			(void) fclose(fp);
723 			ecleanup();
724 			return (NULL);
725 		}
726 
727 		totsize += nparts * maxpsize;
728 		if (dstdev.capacity && dstdev.capacity < totsize) {
729 			int lastpartcnt = 0;
730 
731 			if (totsize)
732 				totsize -= nparts * maxpsize;
733 			while (partcnt < nparts) {
734 				while (totsize <= dstdev.capacity &&
735 				    partcnt <= nparts) {
736 					totsize +=  maxpsize;
737 					partcnt++;
738 				}
739 				/* partcnt == 0 means skip to next volume */
740 				if (partcnt)
741 					partcnt--;
742 				(void) snprintf(tmp_entry, ENTRY_MAX,
743 				    " %d", partcnt - lastpartcnt);
744 				if (cat_and_count(&hdrbuf, tmp_entry)) {
745 					progerr(pkg_gt(ERR_TRANSFER));
746 					logerr(pkg_gt(MSG_MEM));
747 					(void) fclose(fp);
748 					ecleanup();
749 					return (NULL);
750 				}
751 				ds_volcnt++;
752 				totsize = 0;
753 				lastpartcnt = partcnt;
754 			}
755 			/* first parts/volume number does not count */
756 			ds_volcnt--;
757 		}
758 
759 		if (cat_and_count(&hdrbuf, "\n")) {
760 			progerr(pkg_gt(ERR_TRANSFER));
761 			logerr(pkg_gt(MSG_MEM));
762 			(void) fclose(fp);
763 			ecleanup();
764 			return (NULL);
765 		}
766 
767 		(void) fclose(fp);
768 	}
769 
770 	if (cat_and_count(&hdrbuf, HDR_SUFFIX) ||
771 	    cat_and_count(&hdrbuf, "\n")) {
772 		progerr(pkg_gt(ERR_TRANSFER));
773 		logerr(pkg_gt(MSG_MEM));
774 		(void) fclose(fp);
775 		ecleanup();
776 		return (NULL);
777 	}
778 	return (&hdrbuf);
779 }
780 
781 static int
782 wdsheader(struct dm_buf *hdr, char *device, char **pkg)
783 {
784 	char	tmp_entry[ENTRY_MAX], tmp_file[L_tmpnam+1];
785 	int	i, n;
786 	int	list_fd;
787 	int	block_cnt;
788 
789 	(void) ds_close(0);
790 	if (dstdev.pathname)
791 		ds_fd = creat(device, 0644);
792 	else
793 		ds_fd = open(device, 1);
794 
795 	if (ds_fd < 0) {
796 		progerr(pkg_gt(ERR_TRANSFER));
797 		logerr(pkg_gt(MSG_OPEN), device, errno);
798 		return (1);
799 	}
800 
801 	if (ds_ginit(device) < 0) {
802 		progerr(pkg_gt(ERR_TRANSFER));
803 		logerr(pkg_gt(MSG_OPEN), device, errno);
804 		(void) ds_close(0);
805 		return (1);
806 	}
807 
808 	/*
809 	 * The loop below assures compatibility with tapes that don't
810 	 * have a block size (e.g.: Exabyte) by forcing EOR at the end
811 	 * of each 512 bytes.
812 	 */
813 	for (block_cnt = 0; block_cnt < hdr->allocation;
814 	    block_cnt += BLK_SIZE) {
815 		(void) write(ds_fd, (hdr->text_buffer + block_cnt), BLK_SIZE);
816 	}
817 
818 	/*
819 	 * write the first cpio() archive to the datastream
820 	 * which should contain the pkginfo & pkgmap files
821 	 * for all packages
822 	 */
823 	(void) tmpnam(tmp_file);	/* temporary file name */
824 	if ((list_fd = open(tmp_file, O_RDWR | O_CREAT, 0644)) == -1) {
825 		progerr(pkg_gt(ERR_TRANSFER));
826 		logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
827 		return (1);
828 	}
829 
830 	/*
831 	 * Create a cpio-compatible list of the requisite files in
832 	 * the temporary file.
833 	 */
834 	for (i = 0; pkg[i]; i++) {
835 		register ssize_t entry_size;
836 
837 		/*
838 		 * Copy pkginfo and pkgmap filenames into the
839 		 * temporary string allowing for the first line
840 		 * as a special case.
841 		 */
842 		entry_size = sprintf(tmp_entry,
843 		    (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
844 		    pkg[i], PKGINFO, pkg[i], PKGMAP);
845 
846 		if (write(list_fd, tmp_entry,
847 		    entry_size) != entry_size) {
848 			progerr(pkg_gt(ERR_TRANSFER));
849 			logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
850 			(void) close(list_fd);
851 			ecleanup();
852 			return (1);
853 		}
854 	}
855 
856 	(void) lseek(list_fd, 0, SEEK_SET);
857 
858 	(void) snprintf(tmp_entry, sizeof (tmp_entry),
859 	    "%s -ocD -C %d", CPIOPROC, (int)BLK_SIZE);
860 
861 	if (n = esystem(tmp_entry, list_fd, ds_fd)) {
862 		rpterr();
863 		progerr(pkg_gt(ERR_TRANSFER));
864 		logerr(pkg_gt(MSG_CMDFAIL), tmp_entry, n);
865 		(void) close(list_fd);
866 		(void) unlink(tmp_file);
867 		cleanup();
868 		return (1);
869 	}
870 
871 	(void) close(list_fd);
872 	(void) unlink(tmp_file);
873 
874 	return (0);
875 }
876 
877 static int
878 ckoverwrite(char *dir, char *inst, int options)
879 {
880 	char	path[PATH_MAX];
881 
882 	(void) snprintf(path, sizeof (path), "%s/%s", dir, inst);
883 	if (access(path, 0) == 0) {
884 		if (options & PT_OVERWRITE)
885 			return (rrmdir(path));
886 		progerr(pkg_gt(ERR_TRANSFER));
887 		logerr(pkg_gt(MSG_EXISTS), path);
888 		return (1);
889 	}
890 	return (0);
891 }
892 
893 static int
894 pkgxfer(char *srcinst, int options)
895 {
896 	int	r;
897 	struct pkginfo info;
898 	FILE	*fp, *pp;
899 	char	*pt, *src, *dst;
900 	char	dstdir[PATH_MAX], temp[PATH_MAX], srcdir[PATH_MAX];
901 	char	cmd[CMDSIZE], pkgname[NON_ABI_NAMELNGTH];
902 	int	i, n, part, nparts, maxpartsize, curpartcnt, iscomp;
903 	char	volnos[128], tmpvol[128];
904 	struct	statvfs64 svfsb;
905 	longlong_t free_blocks;
906 	struct	stat	srcstat;
907 
908 	info.pkginst = NULL; /* required initialization */
909 
910 	/*
911 	 * when this routine is entered, the first part of
912 	 * the package to transfer is already available in
913 	 * the directory indicated by 'src' --- unless the
914 	 * source device is a datstream, in which case only
915 	 * the pkginfo and pkgmap files are available in 'src'
916 	 */
917 	src = srcdev.dirname;
918 	dst = dstdev.dirname;
919 
920 	if (!(options & PT_SILENT))
921 		(void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst);
922 	(void) strlcpy(dstinst, srcinst, sizeof (dstinst));
923 
924 	if (!(options & PT_ODTSTREAM)) {
925 		/* destination is a (possibly mounted) directory */
926 		(void) snprintf(dstdir, sizeof (dstdir),
927 		    "%s/%s", dst, dstinst);
928 
929 		/*
930 		 * need to check destination directory to assure
931 		 * that we will not be duplicating a package which
932 		 * already resides there (though we are allowed to
933 		 * overwrite the same version)
934 		 */
935 		pkgdir = src;
936 		if (fpkginfo(&info, srcinst)) {
937 			progerr(pkg_gt(ERR_TRANSFER));
938 			logerr(pkg_gt(MSG_NOEXISTS), srcinst);
939 			(void) fpkginfo(&info, NULL);
940 			return (1);
941 		}
942 		pkgdir = dst;
943 
944 		(void) strlcpy(temp, srcinst, sizeof (temp));
945 		if (pt = strchr(temp, '.'))
946 			*pt = '\0';
947 		(void) strlcat(temp, ".*", sizeof (temp));
948 
949 		if (pt = fpkginst(temp, info.arch, info.version)) {
950 			/*
951 			 * the same instance already exists, although
952 			 * its pkgid might be different
953 			 */
954 			if (options & PT_OVERWRITE) {
955 				(void) strlcpy(dstinst, pt, sizeof (dstinst));
956 				(void) snprintf(dstdir, sizeof (dstdir),
957 				    "%s/%s", dst, dstinst);
958 			} else {
959 				progerr(pkg_gt(ERR_TRANSFER));
960 				logerr(pkg_gt(MSG_DUPVERS), srcinst);
961 				(void) fpkginfo(&info, NULL);
962 				(void) fpkginst(NULL);
963 				return (2);
964 			}
965 		} else if (options & PT_RENAME) {
966 			/*
967 			 * find next available instance by appending numbers
968 			 * to the package abbreviation until the instance
969 			 * does not exist in the destination directory
970 			 */
971 			if (pt = strchr(temp, '.'))
972 				*pt = '\0';
973 			for (i = 2; (access(dstdir, 0) == 0); i++) {
974 				(void) snprintf(dstinst, sizeof (dstinst),
975 				    "%s.%d", temp, i);
976 				(void) snprintf(dstdir, sizeof (dstdir),
977 				    "%s/%s", dst, dstinst);
978 			}
979 		} else if (options & PT_OVERWRITE) {
980 			/*
981 			 * we're allowed to overwrite, but there seems
982 			 * to be no valid package to overwrite, and we are
983 			 * not allowed to rename the destination, so act
984 			 * as if we weren't given permission to overwrite
985 			 * --- this keeps us from removing a destination
986 			 * instance which is named the same as the source
987 			 * instance, but really reflects a different pkg!
988 			 */
989 			options &= (~PT_OVERWRITE);
990 		}
991 		(void) fpkginfo(&info, NULL);
992 		(void) fpkginst(NULL);
993 
994 		if (ckoverwrite(dst, dstinst, options))
995 			return (2);
996 
997 		if (isdir(dstdir) && mkdir(dstdir, 0755)) {
998 			progerr(pkg_gt(ERR_TRANSFER));
999 			logerr(pkg_gt(MSG_MKDIR), dstdir);
1000 			return (1);
1001 		}
1002 
1003 		(void) snprintf(srcdir, sizeof (srcdir),
1004 		    "%s/%s", src, srcinst);
1005 		if (stat(srcdir, &srcstat) != -1) {
1006 			if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) {
1007 				progerr(pkg_gt(ERR_TRANSFER));
1008 				logerr(pkg_gt(MSG_CHMODDIR), dstdir);
1009 				return (1);
1010 			}
1011 		} else {
1012 			progerr(pkg_gt(ERR_TRANSFER));
1013 			logerr(pkg_gt(MSG_STATDIR), srcdir);
1014 			return (1);
1015 		}
1016 	}
1017 
1018 	if (!(options & PT_SILENT) && strcmp(dstinst, srcinst))
1019 		(void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst);
1020 
1021 	(void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst);
1022 	if (chdir(srcdir)) {
1023 		progerr(pkg_gt(ERR_TRANSFER));
1024 		logerr(pkg_gt(MSG_CHDIR), srcdir);
1025 		return (1);
1026 	}
1027 
1028 	if (ids_name) {	/* unpack the datatstream into a directory */
1029 		/*
1030 		 * transfer pkginfo & pkgmap first
1031 		 */
1032 		(void) snprintf(cmd, sizeof (cmd),
1033 		    "%s -pudm %s", CPIOPROC, dstdir);
1034 		if ((pp = epopen(cmd, "w")) == NULL) {
1035 			rpterr();
1036 			progerr(pkg_gt(ERR_TRANSFER));
1037 			logerr(pkg_gt(MSG_POPEN), cmd, errno);
1038 			return (1);
1039 		}
1040 		(void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP);
1041 
1042 		(void) sighold(SIGINT);
1043 		(void) sighold(SIGHUP);
1044 		r = epclose(pp);
1045 		(void) sigrelse(SIGINT);
1046 		(void) sigrelse(SIGHUP);
1047 
1048 		if (r != 0) {
1049 			rpterr();
1050 			progerr(pkg_gt(ERR_TRANSFER));
1051 			logerr(pkg_gt(MSG_PCLOSE), cmd, errno);
1052 			return (1);
1053 		}
1054 
1055 		if (options & PT_INFO_ONLY)
1056 			return (0); /* don't transfer objects */
1057 
1058 		if (chdir(dstdir)) {
1059 			progerr(pkg_gt(ERR_TRANSFER));
1060 			logerr(pkg_gt(MSG_CHDIR), dstdir);
1061 			return (1);
1062 		}
1063 
1064 		/*
1065 		 * for each part of the package, use cpio() to
1066 		 * unpack the archive into the destination directory
1067 		 */
1068 		nparts = ds_findpkg(srcdev.cdevice, srcinst);
1069 		if (nparts < 0) {
1070 			progerr(pkg_gt(ERR_TRANSFER));
1071 			return (1);
1072 		}
1073 		for (part = 1; part <= nparts; /* void */) {
1074 			if (ds_getpkg(srcdev.cdevice, part, dstdir)) {
1075 				progerr(pkg_gt(ERR_TRANSFER));
1076 				return (1);
1077 			}
1078 			part++;
1079 			if (dstdev.mount) {
1080 				(void) chdir("/");
1081 				if (pkgumount(&dstdev))
1082 					return (1);
1083 				if (part <= nparts) {
1084 					if (n = pkgmount(&dstdev, NULL, part+1,
1085 					    nparts, 1))
1086 						return (n);
1087 					if (ckoverwrite(dst, dstinst, options))
1088 						return (1);
1089 					if (isdir(dstdir) &&
1090 					    mkdir(dstdir, 0755)) {
1091 						progerr(
1092 						    pkg_gt(ERR_TRANSFER));
1093 						logerr(pkg_gt(MSG_MKDIR),
1094 						    dstdir);
1095 						return (1);
1096 					}
1097 					/*
1098 					 * since volume is removable, each part
1099 					 * must contain a duplicate of the
1100 					 * pkginfo file to properly identify the
1101 					 * volume
1102 					 */
1103 					if (chdir(srcdir)) {
1104 						progerr(
1105 						    pkg_gt(ERR_TRANSFER));
1106 						logerr(pkg_gt(MSG_CHDIR),
1107 						    srcdir);
1108 						return (1);
1109 					}
1110 					if ((pp = epopen(cmd, "w")) == NULL) {
1111 						rpterr();
1112 						progerr(
1113 						    pkg_gt(ERR_TRANSFER));
1114 						logerr(pkg_gt(MSG_POPEN),
1115 						    cmd, errno);
1116 						return (1);
1117 					}
1118 					(void) fprintf(pp, "pkginfo");
1119 
1120 					(void) sighold(SIGINT);
1121 					(void) sighold(SIGHUP);
1122 					r = epclose(pp);
1123 					(void) sigrelse(SIGINT);
1124 					(void) sigrelse(SIGHUP);
1125 
1126 					if (r != 0) {
1127 						rpterr();
1128 						progerr(
1129 						    pkg_gt(ERR_TRANSFER));
1130 						logerr(pkg_gt(MSG_PCLOSE),
1131 						    cmd, errno);
1132 						return (1);
1133 					}
1134 					if (chdir(dstdir)) {
1135 						progerr(
1136 						    pkg_gt(ERR_TRANSFER));
1137 						logerr(pkg_gt(MSG_CHDIR),
1138 						    dstdir);
1139 						return (1);
1140 					}
1141 				}
1142 			}
1143 		}
1144 		return (0);
1145 	}
1146 
1147 	if ((fp = fopen(PKGMAP, "r")) == NULL) {
1148 		progerr(pkg_gt(ERR_TRANSFER));
1149 		logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
1150 		return (1);
1151 	}
1152 
1153 	nparts = 1;
1154 	if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
1155 		return (1);
1156 	else
1157 		(void) fclose(fp);
1158 
1159 	if (srcdev.mount) {
1160 		if (ckvolseq(srcdir, 1, nparts)) {
1161 			progerr(pkg_gt(ERR_TRANSFER));
1162 			logerr(pkg_gt(MSG_SEQUENCE));
1163 			return (1);
1164 		}
1165 	}
1166 
1167 	/* write each part of this package */
1168 	if (options & PT_ODTSTREAM) {
1169 		char line[128];
1170 		(void) mgets(line, 128);
1171 		curpartcnt = -1;
1172 		/* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
1173 		if (sscanf(line, "%s %d %d %[ 0-9]", pkgname, &nparts,
1174 		    &maxpartsize, volnos) == 4) {
1175 			(void) sscanf(volnos,
1176 			    "%d %[ 0-9]", &curpartcnt, tmpvol);
1177 			(void) strlcpy(volnos, tmpvol, sizeof (volnos));
1178 		}
1179 	}
1180 
1181 	for (part = 1; part <= nparts; /* void */) {
1182 		if (curpartcnt == 0 && (options & PT_ODTSTREAM)) {
1183 			char prompt[128];
1184 			int index;
1185 			ds_volno++;
1186 			(void) ds_close(0);
1187 			(void) sprintf(prompt,
1188 			    pkg_gt("Insert %%v %d of %d into %%p"),
1189 			    ds_volno, ds_volcnt);
1190 			if (n = getvol(ods_name, NULL, DM_FORMAT, prompt))
1191 				return (n);
1192 			if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) {
1193 				progerr(pkg_gt(ERR_TRANSFER));
1194 				logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
1195 				    errno);
1196 				return (1);
1197 			}
1198 			if (ds_ginit(dstdev.cdevice) < 0) {
1199 				progerr(pkg_gt(ERR_TRANSFER));
1200 				logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
1201 				    errno);
1202 				(void) ds_close(0);
1203 				return (1);
1204 			}
1205 
1206 			(void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol);
1207 			(void) strlcpy(volnos, tmpvol, sizeof (volnos));
1208 			curpartcnt += index;
1209 		}
1210 
1211 		if (options & PT_INFO_ONLY)
1212 			nparts = 0;
1213 
1214 		if (part == 1) {
1215 			(void) snprintf(cmd, sizeof (cmd),
1216 			    "find %s %s", PKGINFO, PKGMAP);
1217 			if (nparts && (isdir(INSTALL) == 0)) {
1218 				(void) strlcat(cmd, " ", sizeof (cmd));
1219 				(void) strlcat(cmd, INSTALL, sizeof (cmd));
1220 			}
1221 		} else
1222 			(void) snprintf(cmd, sizeof (cmd), "find %s", PKGINFO);
1223 
1224 		if (nparts > 1) {
1225 			(void) snprintf(temp, sizeof (temp),
1226 			    "%s.%d", RELOC, part);
1227 			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
1228 				(void) strlcat(cmd, " ", sizeof (cmd));
1229 				(void) strlcat(cmd, temp, sizeof (cmd));
1230 			}
1231 			(void) snprintf(temp, sizeof (temp),
1232 			    "%s.%d", ROOT, part);
1233 			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
1234 				(void) strlcat(cmd, " ", sizeof (cmd));
1235 				(void) strlcat(cmd, temp, sizeof (cmd));
1236 			}
1237 			(void) snprintf(temp, sizeof (temp),
1238 			    "%s.%d", ARCHIVE, part);
1239 			if (isdir(temp) == 0) {
1240 				(void) strlcat(cmd, " ", sizeof (cmd));
1241 				(void) strlcat(cmd, temp, sizeof (cmd));
1242 			}
1243 		} else if (nparts) {
1244 			for (i = 0; reloc_names[i] != NULL; i++) {
1245 				if (iscpio(reloc_names[i], &iscomp) ||
1246 				    isdir(reloc_names[i]) == 0) {
1247 					(void) strlcat(cmd, " ", sizeof (cmd));
1248 					(void) strlcat(cmd, reloc_names[i],
1249 					    sizeof (cmd));
1250 				}
1251 			}
1252 			for (i = 0; root_names[i] != NULL; i++) {
1253 				if (iscpio(root_names[i], &iscomp) ||
1254 				    isdir(root_names[i]) == 0) {
1255 					(void) strlcat(cmd, " ", sizeof (cmd));
1256 					(void) strlcat(cmd, root_names[i],
1257 					    sizeof (cmd));
1258 				}
1259 			}
1260 			if (isdir(ARCHIVE) == 0) {
1261 				(void) strlcat(cmd, " ", sizeof (cmd));
1262 				(void) strlcat(cmd, ARCHIVE, sizeof (cmd));
1263 			}
1264 		}
1265 		if (options & PT_ODTSTREAM) {
1266 			(void) snprintf(cmd + strlen(cmd),
1267 			    sizeof (cmd) - strlen(cmd),
1268 			    " -print | %s -ocD -C %d",
1269 			    CPIOPROC, (int)BLK_SIZE);
1270 		} else {
1271 			if (statvfs64(dstdir, &svfsb) == -1) {
1272 				progerr(pkg_gt(ERR_TRANSFER));
1273 				logerr(pkg_gt(MSG_STATVFS), dstdir, errno);
1274 				return (1);
1275 			}
1276 
1277 			free_blocks = (((long)svfsb.f_frsize > 0) ?
1278 			    howmany(svfsb.f_frsize, DEV_BSIZE) :
1279 			    howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail;
1280 
1281 			if ((has_comp_size ? compressedsize : maxpartsize) >
1282 			    free_blocks) {
1283 				progerr(pkg_gt(ERR_TRANSFER));
1284 				logerr(pkg_gt(MSG_NOSPACE),
1285 				    has_comp_size ?
1286 				    (long)compressedsize : (long)maxpartsize,
1287 				    free_blocks);
1288 				return (1);
1289 			}
1290 			(void) snprintf(cmd + strlen(cmd),
1291 			    sizeof (cmd) - strlen(cmd),
1292 			    " -print | %s -pdum %s",
1293 			    CPIOPROC, dstdir);
1294 		}
1295 
1296 		n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1);
1297 		if (n) {
1298 			rpterr();
1299 			progerr(pkg_gt(ERR_TRANSFER));
1300 			logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
1301 			return (1);
1302 		}
1303 
1304 		part++;
1305 		if (srcdev.mount && (nparts > 1)) {
1306 			/* unmount current source volume */
1307 			(void) chdir("/");
1308 			if (pkgumount(&srcdev))
1309 				return (1);
1310 			/* loop until volume is mounted successfully */
1311 			while (part <= nparts) {
1312 				/* read only */
1313 				n = pkgmount(&srcdev, NULL, part, nparts, 1);
1314 				if (n)
1315 					return (n);
1316 				if (chdir(srcdir)) {
1317 					progerr(pkg_gt(ERR_TRANSFER));
1318 					logerr(pkg_gt(MSG_CORRUPT));
1319 					(void) chdir("/");
1320 					(void) pkgumount(&srcdev);
1321 					continue;
1322 				}
1323 				if (ckvolseq(srcdir, part, nparts)) {
1324 					(void) chdir("/");
1325 					(void) pkgumount(&srcdev);
1326 					continue;
1327 				}
1328 				break;
1329 			}
1330 		}
1331 		if (!(options & PT_ODTSTREAM) && dstdev.mount) {
1332 			/* unmount current volume */
1333 			if (pkgumount(&dstdev))
1334 				return (1);
1335 			/* loop until next volume is mounted successfully */
1336 			while (part <= nparts) {
1337 				/* writable */
1338 				n = pkgmount(&dstdev, NULL, part, nparts, 1);
1339 				if (n)
1340 					return (n);
1341 				if (ckoverwrite(dst, dstinst, options))
1342 					continue;
1343 				if (isdir(dstdir) && mkdir(dstdir, 0755)) {
1344 					progerr(pkg_gt(ERR_TRANSFER));
1345 					logerr(pkg_gt(MSG_MKDIR), dstdir);
1346 					continue;
1347 				}
1348 				break;
1349 			}
1350 		}
1351 
1352 		if ((options & PT_ODTSTREAM) && part <= nparts) {
1353 			if (curpartcnt >= 0 && part > curpartcnt) {
1354 				char prompt[128];
1355 				int index;
1356 				ds_volno++;
1357 				if (ds_close(0))
1358 					return (1);
1359 				(void) sprintf(prompt,
1360 				    pkg_gt("Insert %%v %d of %d into %%p"),
1361 				    ds_volno, ds_volcnt);
1362 				if (n = getvol(ods_name, NULL, DM_FORMAT,
1363 				    prompt))
1364 					return (n);
1365 				if ((ds_fd = open(dstdev.cdevice, 1)) < 0) {
1366 					progerr(pkg_gt(ERR_TRANSFER));
1367 					logerr(pkg_gt(MSG_OPEN),
1368 					    dstdev.cdevice, errno);
1369 					return (1);
1370 				}
1371 				if (ds_ginit(dstdev.cdevice) < 0) {
1372 					progerr(pkg_gt(ERR_TRANSFER));
1373 					logerr(pkg_gt(MSG_OPEN),
1374 					    dstdev.cdevice, errno);
1375 					(void) ds_close(0);
1376 					return (1);
1377 				}
1378 
1379 				(void) sscanf(volnos, "%d %[ 0-9]", &index,
1380 				    tmpvol);
1381 				(void) strlcpy(volnos, tmpvol, sizeof (volnos));
1382 				curpartcnt += index;
1383 			}
1384 		}
1385 
1386 	}
1387 	return (0);
1388 }
1389 
1390 static void
1391 sigtrap(int signo)
1392 {
1393 	_NOTE(ARGUNUSED(signo));
1394 	signal_received++;
1395 }
1396 
1397 static void
1398 cleanup(void)
1399 {
1400 	(void) chdir("/");
1401 	if (tmpdir) {
1402 		(void) rrmdir(tmpdir);
1403 		free(tmpdir);
1404 		tmpdir = NULL;
1405 	}
1406 
1407 	if (tmppath) {
1408 		/* remove any previous tmppath stuff */
1409 		(void) rrmdir(tmppath);
1410 		free(tmppath);
1411 		tmppath = NULL;
1412 	}
1413 
1414 	if (tmpsymdir) {
1415 		/* remove temp symbolic links made for signed pkg */
1416 		(void) rrmdir(tmpsymdir);
1417 		free(tmpsymdir);
1418 		tmpsymdir = NULL;
1419 	}
1420 
1421 	if (srcdev.mount && !ids_name)
1422 		(void) pkgumount(&srcdev);
1423 	if (dstdev.mount && !ods_name)
1424 		(void) pkgumount(&dstdev);
1425 	(void) ds_close(1);
1426 }
1427