4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2017 Peter Tribble.
27 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
32 /* All Rights Reserved */
45 #include <sys/types.h>
46 #include <sys/param.h>
48 #include <sys/statvfs.h>
49 #include <sys/sysmacros.h>
59 #include "pkglibmsgs.h"
60 #include "pkglocale.h"
62 extern char *pkgdir
; /* pkgparam.c */
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
,
73 extern int ds_ginit(char *device
);
74 extern int ds_close(int pkgendflg
);
76 #define CPIOPROC "/usr/bin/cpio"
78 #define CMDSIZE 512 /* command block size */
80 #define BLK_SIZE 512 /* size of logical block */
82 #define ENTRY_MAX 256 /* max size of entry for cpio cmd or header */
84 #define PKGINFO "pkginfo"
85 #define PKGMAP "pkgmap"
86 #define MAP_STAT_SIZE 60 /* 1st line of pkgmap (3 numbers & a : */
88 #define INSTALL "install"
91 #define ARCHIVE "archive"
93 static struct pkgdev srcdev
, dstdev
;
96 static char *tmpsymdir
= NULL
;
97 static char dstinst
[NON_ABI_NAMELNGTH
];
98 static char *ids_name
, *ods_name
;
101 static int compressedsize
, has_comp_size
;
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
);
109 static int cat_and_count(struct dm_buf
*, char *);
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 **);
116 extern int ds_fd
; /* open file descriptor for data stream WHERE? */
118 static char *root_names
[] = {
126 static char *reloc_names
[] = {
134 static int signal_received
= 0;
136 char **xpkg
; /* array of transferred packages */
139 static char *allpkg
[] = {
144 static struct dm_buf hdrbuf
;
145 static char *pinput
, *nextpinput
;
148 pkghead(char *device
)
158 else if ((device
[0] == '/') && !isdir(device
)) {
161 } else if ((pt
= devattr(device
, "pathname")) != NULL
&& !isdir(pt
)) {
166 /* check for datastream */
167 if (n
= pkgtrans(device
, (char *)0, allpkg
, PT_SILENT
|PT_INFO_ONLY
)) {
171 /* pkgtrans has set pkgdir */
176 mgets(char *buf
, int size
)
178 nextpinput
= strchr(pinput
, '\n');
179 if (nextpinput
== NULL
)
182 if ((int)strlen(pinput
) > size
)
184 (void) strncpy(buf
, pinput
, strlen(pinput
));
185 buf
[strlen(pinput
)] = '\0';
186 pinput
= nextpinput
+ 1;
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.
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
202 rd_map_size(FILE *fp
, int *npts
, int *maxpsz
, int *cmpsize
)
205 char line_buffer
[MAP_STAT_SIZE
];
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
));
216 n
= sscanf(line_buffer
, ": %d %d %d", npts
, maxpsz
, cmpsize
);
218 if (n
== 3) /* A valid compressed package entry */
220 else if (n
== 2) /* A valid standard package entry */
222 else { /* invalid entry */
223 progerr(pkg_gt(ERR_TRANSFER
));
224 logerr(pkg_gt(MSG_NOSIZE
));
233 /* will return 0, 1, 3, or 99 */
235 _pkgtrans(char *device1
, char *device2
, char **pkg
, int options
)
241 if (signal_received
> 0) {
245 /* transfer spool to appropriate device */
246 if (devtype(device1
, &srcdev
)) {
247 progerr(pkg_gt(ERR_TRANSFER
));
248 logerr(pkg_gt(MSG_BADDEV
), device1
);
253 /* check for datastream */
255 if (srcdev
.bdevice
) {
256 if (n
= _getvol(srcdev
.bdevice
, NULL
, NULL
,
257 pkg_gt("Insert %v into %p."), srcdev
.norewind
)) {
261 progerr(pkg_gt(ERR_TRANSFER
));
262 logerr(pkg_gt(MSG_GETVOL
));
265 if (ds_readbuf(srcdev
.cdevice
))
266 ids_name
= srcdev
.cdevice
;
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
));
280 if (!ids_name
&& device2
== (char *)0) {
281 if (n
= pkgmount(&srcdev
, NULL
, 1, 0, 0)) {
285 if (srcdev
.mount
&& *srcdev
.mount
)
286 pkgdir
= strdup(srcdev
.mount
);
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
));
298 if (mkdir(tmppath
, 0755)) {
299 progerr(pkg_gt(ERR_TRANSFER
));
300 logerr(pkg_gt(MSG_MKDIR
), tmppath
);
306 if (devtype(device2
, &dstdev
)) {
307 progerr(pkg_gt(ERR_TRANSFER
));
308 logerr(pkg_gt(MSG_BADDEV
), device2
);
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
));
320 if (dstdev
.cdevice
&& !dstdev
.bdevice
|| dstdev
.pathname
)
321 options
|= PT_ODTSTREAM
;
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
);
331 progerr(pkg_gt(ERR_TRANSFER
));
332 logerr(pkg_gt(MSG_TWODSTREAM
));
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
));
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
));
351 if (signal_received
> 0) {
356 if (srcdev
.cdevice
&& !srcdev
.bdevice
&&
357 (n
= _getvol(srcdev
.cdevice
, NULL
, NULL
, NULL
,
362 progerr(pkg_gt(ERR_TRANSFER
));
363 logerr(pkg_gt(MSG_GETVOL
));
366 if (srcdev
.dirname
= tmpnam(NULL
))
367 tmpdir
= srcdev
.dirname
= strdup(srcdev
.dirname
);
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
);
376 if (ds_init(ids_name
, pkg
, srcdev
.norewind
)) {
380 } else if (srcdev
.mount
) {
381 if (n
= pkgmount(&srcdev
, NULL
, 1, 0, 0)) {
387 src
= srcdev
.dirname
;
388 dst
= dstdev
.dirname
;
391 progerr(pkg_gt(ERR_TRANSFER
));
392 logerr(pkg_gt(MSG_CHDIR
), src
);
397 if (signal_received
> 0) {
401 xpkg
= pkg
= gpkglist(src
, pkg
, NULL
);
403 progerr(pkg_gt(ERR_TRANSFER
));
404 logerr(pkg_gt(MSG_NOPKGS
), src
);
409 for (nxpkg
= 0; pkg
[nxpkg
]; /* void */) {
414 ds_order(pkg
); /* order requests */
417 if (signal_received
> 0) {
421 if (options
& PT_ODTSTREAM
) {
424 if (!dstdev
.pathname
&&
425 (n
= _getvol(ods_name
, NULL
, DM_FORMAT
, NULL
,
430 progerr(pkg_gt(ERR_TRANSFER
));
431 logerr(pkg_gt(MSG_GETVOL
));
434 if ((hdr
= genheader(src
, pkg
)) == NULL
) {
439 /* write out header to stream */
440 if (wdsheader(hdr
, ods_name
, pkg
)) {
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);
451 if (signal_received
> 0) {
457 for (i
= 0; pkg
[i
]; i
++) {
459 if (signal_received
> 0) {
463 if (!(options
& PT_ODTSTREAM
) && dstdev
.mount
) {
464 if (n
= pkgmount(&dstdev
, NULL
, 0, 0, 1)) {
469 if (errflg
= pkgxfer(pkg
[i
], options
)) {
471 if ((options
& PT_ODTSTREAM
) || (errflg
!= 2))
473 } else if (strcmp(dstinst
, pkg
[i
]))
474 pkg
[i
] = strdup(dstinst
);
477 if (!(options
& PT_ODTSTREAM
) && dst
) {
478 pkgdir
= strdup(dst
);
482 * No cleanup of temporary directories created in this
483 * function is done here. The calling function must do
487 return (signal_received
> 0 ? 1 : errflg
);
491 pkgtrans(char *device1
, char *device2
, char **pkg
, int options
)
494 struct sigaction nact
;
495 struct sigaction oact
;
498 * setup signal handlers for SIGINT and SIGHUP and release hold
501 /* hold SIGINT/SIGHUP interrupts */
503 (void) sighold(SIGHUP
);
504 (void) sighold(SIGINT
);
506 /* hook SIGINT to sigtrap */
508 nact
.sa_handler
= sigtrap
;
509 nact
.sa_flags
= SA_RESTART
;
510 (void) sigemptyset(&nact
.sa_mask
);
512 if (sigaction(SIGINT
, &nact
, &oact
) < 0) {
513 sigintHandler
= SIG_DFL
;
515 sigintHandler
= oact
.sa_handler
;
518 /* hook SIGHUP to sigtrap */
520 nact
.sa_handler
= sigtrap
;
521 nact
.sa_flags
= SA_RESTART
;
522 (void) sigemptyset(&nact
.sa_mask
);
524 if (sigaction(SIGHUP
, &nact
, &oact
) < 0) {
525 sighupHandler
= SIG_DFL
;
527 sighupHandler
= oact
.sa_handler
;
530 /* reset signal received count */
534 /* release hold on signals */
536 (void) sigrelse(SIGHUP
);
537 (void) sigrelse(SIGINT
);
540 * perform the package translation
543 r
= _pkgtrans(device1
, device2
, pkg
, options
);
546 * reset signal handlers
549 /* hold SIGINT/SIGHUP interrupts */
551 (void) sighold(SIGHUP
);
552 (void) sighold(SIGINT
);
556 nact
.sa_handler
= sigintHandler
;
557 nact
.sa_flags
= SA_RESTART
;
558 (void) sigemptyset(&nact
.sa_mask
);
560 (void) sigaction(SIGINT
, &nact
, (struct sigaction
*)NULL
);
564 nact
.sa_handler
= sighupHandler
;
565 nact
.sa_flags
= SA_RESTART
;
566 (void) sigemptyset(&nact
.sa_mask
);
568 (void) sigaction(SIGHUP
, &nact
, (struct sigaction
*)NULL
);
570 /* if signal received and pkgtrans returned error, call cleanup */
572 if (signal_received
> 0) {
576 (void) kill(getpid(), SIGINT
);
579 /* release hold on signals */
581 (void) sigrelse(SIGHUP
);
582 (void) sigrelse(SIGINT
);
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'
594 cat_and_count(struct dm_buf
*buf_ctrl
, char *append
)
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
);
610 /* clear the new memory */
611 (void) memset(buf_ctrl
->text_buffer
+
612 buf_ctrl
->allocation
, '\0', BLK_SIZE
);
614 /* adjust total allocation */
615 buf_ctrl
->allocation
+= BLK_SIZE
;
618 /* append new string to end of buffer */
620 *(buf_ctrl
->text_buffer
+ buf_ctrl
->offset
) = *append
++;
621 (buf_ctrl
->offset
)++;
627 static struct dm_buf
*
628 genheader(char *src
, char **pkg
)
632 char path
[MAXPATHLEN
], tmp_entry
[ENTRY_MAX
];
633 int i
, n
, nparts
, maxpsize
;
638 if ((hdrbuf
.text_buffer
= (char *)malloc(BLK_SIZE
)) == NULL
) {
639 progerr(pkg_gt(ERR_TRANSFER
));
640 logerr(pkg_gt(MSG_MEM
));
644 /* clear the new memory */
645 (void) memset(hdrbuf
.text_buffer
, '\0', BLK_SIZE
);
647 /* set up the buffer control structure for the header */
649 hdrbuf
.allocation
= BLK_SIZE
;
651 (void) cat_and_count(&hdrbuf
, HDR_PREFIX
);
652 (void) cat_and_count(&hdrbuf
, "\n");
654 nparts
= maxpsize
= 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
));
666 totsize
+= statbuf
.st_size
/BLK_SIZE
+ 1;
670 * totsize contains number of blocks used by the pkginfo files
673 if (dstdev
.capacity
&& totsize
> dstdev
.capacity
) {
674 progerr(pkg_gt(ERR_TRANSFER
));
675 logerr(pkg_gt(MSG_NOSPACE
), totsize
, dstdev
.capacity
);
681 for (i
= 0; pkg
[i
]; i
++) {
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
]);
692 /* Evaluate the first entry in pkgmap */
693 n
= rd_map_size(fp
, &nparts
, &maxpsize
, &compressedsize
);
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 */
701 if (dstdev
.capacity
&& maxpsize
> dstdev
.capacity
) {
702 progerr(pkg_gt(ERR_TRANSFER
));
703 logerr(pkg_gt(MSG_NOSPACE
), (long)maxpsize
,
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
));
719 if (cat_and_count(&hdrbuf
, tmp_entry
)) {
720 progerr(pkg_gt(ERR_TRANSFER
));
721 logerr(pkg_gt(MSG_MEM
));
727 totsize
+= nparts
* maxpsize
;
728 if (dstdev
.capacity
&& dstdev
.capacity
< totsize
) {
732 totsize
-= nparts
* maxpsize
;
733 while (partcnt
< nparts
) {
734 while (totsize
<= dstdev
.capacity
&&
739 /* partcnt == 0 means skip to next volume */
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
));
753 lastpartcnt
= partcnt
;
755 /* first parts/volume number does not count */
759 if (cat_and_count(&hdrbuf
, "\n")) {
760 progerr(pkg_gt(ERR_TRANSFER
));
761 logerr(pkg_gt(MSG_MEM
));
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
));
782 wdsheader(struct dm_buf
*hdr
, char *device
, char **pkg
)
784 char tmp_entry
[ENTRY_MAX
], tmp_file
[L_tmpnam
+1];
791 ds_fd
= creat(device
, 0644);
793 ds_fd
= open(device
, 1);
796 progerr(pkg_gt(ERR_TRANSFER
));
797 logerr(pkg_gt(MSG_OPEN
), device
, errno
);
801 if (ds_ginit(device
) < 0) {
802 progerr(pkg_gt(ERR_TRANSFER
));
803 logerr(pkg_gt(MSG_OPEN
), device
, errno
);
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
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
);
819 * write the first cpio() archive to the datastream
820 * which should contain the pkginfo & pkgmap files
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
);
831 * Create a cpio-compatible list of the requisite files in
832 * the temporary file.
834 for (i
= 0; pkg
[i
]; i
++) {
835 register ssize_t entry_size
;
838 * Copy pkginfo and pkgmap filenames into the
839 * temporary string allowing for the first line
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
);
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
);
856 (void) lseek(list_fd
, 0, SEEK_SET
);
858 (void) snprintf(tmp_entry
, sizeof (tmp_entry
),
859 "%s -ocD -C %d", CPIOPROC
, (int)BLK_SIZE
);
861 if (n
= esystem(tmp_entry
, list_fd
, ds_fd
)) {
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
);
871 (void) close(list_fd
);
872 (void) unlink(tmp_file
);
878 ckoverwrite(char *dir
, char *inst
, int options
)
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
);
894 pkgxfer(char *srcinst
, int options
)
899 char *pt
, *src
, *dst
;
900 char dstdir
[PATH_MAX
],
904 pkgname
[NON_ABI_NAMELNGTH
];
905 int i
, n
, part
, nparts
, maxpartsize
, curpartcnt
, iscomp
;
906 char volnos
[128], tmpvol
[128];
907 struct statvfs64 svfsb
;
908 longlong_t free_blocks
;
911 info
.pkginst
= NULL
; /* required initialization */
914 * when this routine is entered, the first part of
915 * the package to transfer is already available in
916 * the directory indicated by 'src' --- unless the
917 * source device is a datstream, in which case only
918 * the pkginfo and pkgmap files are available in 'src'
920 src
= srcdev
.dirname
;
921 dst
= dstdev
.dirname
;
923 if (!(options
& PT_SILENT
))
924 (void) fprintf(stderr
, pkg_gt(MSG_TRANSFER
), srcinst
);
925 (void) strlcpy(dstinst
, srcinst
, sizeof (dstinst
));
927 if (!(options
& PT_ODTSTREAM
)) {
928 /* destination is a (possibly mounted) directory */
929 (void) snprintf(dstdir
, sizeof (dstdir
),
930 "%s/%s", dst
, dstinst
);
933 * need to check destination directory to assure
934 * that we will not be duplicating a package which
935 * already resides there (though we are allowed to
936 * overwrite the same version)
939 if (fpkginfo(&info
, srcinst
)) {
940 progerr(pkg_gt(ERR_TRANSFER
));
941 logerr(pkg_gt(MSG_NOEXISTS
), srcinst
);
942 (void) fpkginfo(&info
, NULL
);
947 (void) strlcpy(temp
, srcinst
, sizeof (temp
));
948 if (pt
= strchr(temp
, '.'))
950 (void) strlcat(temp
, ".*", sizeof (temp
));
952 if (pt
= fpkginst(temp
, info
.arch
, info
.version
)) {
954 * the same instance already exists, although
955 * its pkgid might be different
957 if (options
& PT_OVERWRITE
) {
958 (void) strlcpy(dstinst
, pt
, sizeof (dstinst
));
959 (void) snprintf(dstdir
, sizeof (dstdir
),
960 "%s/%s", dst
, dstinst
);
962 progerr(pkg_gt(ERR_TRANSFER
));
963 logerr(pkg_gt(MSG_DUPVERS
), srcinst
);
964 (void) fpkginfo(&info
, NULL
);
965 (void) fpkginst(NULL
);
968 } else if (options
& PT_RENAME
) {
970 * find next available instance by appending numbers
971 * to the package abbreviation until the instance
972 * does not exist in the destination directory
974 if (pt
= strchr(temp
, '.'))
976 for (i
= 2; (access(dstdir
, 0) == 0); i
++) {
977 (void) snprintf(dstinst
, sizeof (dstinst
),
979 (void) snprintf(dstdir
, sizeof (dstdir
),
980 "%s/%s", dst
, dstinst
);
982 } else if (options
& PT_OVERWRITE
) {
984 * we're allowed to overwrite, but there seems
985 * to be no valid package to overwrite, and we are
986 * not allowed to rename the destination, so act
987 * as if we weren't given permission to overwrite
988 * --- this keeps us from removing a destination
989 * instance which is named the same as the source
990 * instance, but really reflects a different pkg!
992 options
&= (~PT_OVERWRITE
);
994 (void) fpkginfo(&info
, NULL
);
995 (void) fpkginst(NULL
);
997 if (ckoverwrite(dst
, dstinst
, options
))
1000 if (isdir(dstdir
) && mkdir(dstdir
, 0755)) {
1001 progerr(pkg_gt(ERR_TRANSFER
));
1002 logerr(pkg_gt(MSG_MKDIR
), dstdir
);
1006 (void) snprintf(srcdir
, sizeof (srcdir
),
1007 "%s/%s", src
, srcinst
);
1008 if (stat(srcdir
, &srcstat
) != -1) {
1009 if (chmod(dstdir
, (srcstat
.st_mode
& S_IAMB
)) == -1) {
1010 progerr(pkg_gt(ERR_TRANSFER
));
1011 logerr(pkg_gt(MSG_CHMODDIR
), dstdir
);
1015 progerr(pkg_gt(ERR_TRANSFER
));
1016 logerr(pkg_gt(MSG_STATDIR
), srcdir
);
1021 if (!(options
& PT_SILENT
) && strcmp(dstinst
, srcinst
))
1022 (void) fprintf(stderr
, pkg_gt(MSG_RENAME
), dstinst
);
1024 (void) snprintf(srcdir
, sizeof (srcdir
), "%s/%s", src
, srcinst
);
1025 if (chdir(srcdir
)) {
1026 progerr(pkg_gt(ERR_TRANSFER
));
1027 logerr(pkg_gt(MSG_CHDIR
), srcdir
);
1031 if (ids_name
) { /* unpack the datatstream into a directory */
1033 * transfer pkginfo & pkgmap first
1035 (void) snprintf(cmd
, sizeof (cmd
),
1036 "%s -pudm %s", CPIOPROC
, dstdir
);
1037 if ((pp
= epopen(cmd
, "w")) == NULL
) {
1039 progerr(pkg_gt(ERR_TRANSFER
));
1040 logerr(pkg_gt(MSG_POPEN
), cmd
, errno
);
1043 (void) fprintf(pp
, "%s\n%s\n", PKGINFO
, PKGMAP
);
1045 (void) sighold(SIGINT
);
1046 (void) sighold(SIGHUP
);
1048 (void) sigrelse(SIGINT
);
1049 (void) sigrelse(SIGHUP
);
1053 progerr(pkg_gt(ERR_TRANSFER
));
1054 logerr(pkg_gt(MSG_PCLOSE
), cmd
, errno
);
1058 if (options
& PT_INFO_ONLY
)
1059 return (0); /* don't transfer objects */
1061 if (chdir(dstdir
)) {
1062 progerr(pkg_gt(ERR_TRANSFER
));
1063 logerr(pkg_gt(MSG_CHDIR
), dstdir
);
1068 * for each part of the package, use cpio() to
1069 * unpack the archive into the destination directory
1071 nparts
= ds_findpkg(srcdev
.cdevice
, srcinst
);
1073 progerr(pkg_gt(ERR_TRANSFER
));
1076 for (part
= 1; part
<= nparts
; /* void */) {
1077 if (ds_getpkg(srcdev
.cdevice
, part
, dstdir
)) {
1078 progerr(pkg_gt(ERR_TRANSFER
));
1084 if (pkgumount(&dstdev
))
1086 if (part
<= nparts
) {
1087 if (n
= pkgmount(&dstdev
, NULL
, part
+1,
1090 if (ckoverwrite(dst
, dstinst
, options
))
1092 if (isdir(dstdir
) &&
1093 mkdir(dstdir
, 0755)) {
1095 pkg_gt(ERR_TRANSFER
));
1096 logerr(pkg_gt(MSG_MKDIR
),
1101 * since volume is removable, each part
1102 * must contain a duplicate of the
1103 * pkginfo file to properly identify the
1106 if (chdir(srcdir
)) {
1108 pkg_gt(ERR_TRANSFER
));
1109 logerr(pkg_gt(MSG_CHDIR
),
1113 if ((pp
= epopen(cmd
, "w")) == NULL
) {
1116 pkg_gt(ERR_TRANSFER
));
1117 logerr(pkg_gt(MSG_POPEN
),
1121 (void) fprintf(pp
, "pkginfo");
1123 (void) sighold(SIGINT
);
1124 (void) sighold(SIGHUP
);
1126 (void) sigrelse(SIGINT
);
1127 (void) sigrelse(SIGHUP
);
1132 pkg_gt(ERR_TRANSFER
));
1133 logerr(pkg_gt(MSG_PCLOSE
),
1137 if (chdir(dstdir
)) {
1139 pkg_gt(ERR_TRANSFER
));
1140 logerr(pkg_gt(MSG_CHDIR
),
1150 if ((fp
= fopen(PKGMAP
, "r")) == NULL
) {
1151 progerr(pkg_gt(ERR_TRANSFER
));
1152 logerr(pkg_gt(MSG_NOPKGMAP
), srcinst
);
1157 if (!rd_map_size(fp
, &nparts
, &maxpartsize
, &compressedsize
))
1163 if (ckvolseq(srcdir
, 1, nparts
)) {
1164 progerr(pkg_gt(ERR_TRANSFER
));
1165 logerr(pkg_gt(MSG_SEQUENCE
));
1170 /* write each part of this package */
1171 if (options
& PT_ODTSTREAM
) {
1173 (void) mgets(line
, 128);
1175 /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
1176 if (sscanf(line
, "%s %d %d %[ 0-9]", pkgname
, &nparts
,
1177 &maxpartsize
, volnos
) == 4) {
1178 (void) sscanf(volnos
,
1179 "%d %[ 0-9]", &curpartcnt
, tmpvol
);
1180 (void) strlcpy(volnos
, tmpvol
, sizeof (volnos
));
1184 for (part
= 1; part
<= nparts
; /* void */) {
1185 if (curpartcnt
== 0 && (options
& PT_ODTSTREAM
)) {
1190 (void) sprintf(prompt
,
1191 pkg_gt("Insert %%v %d of %d into %%p"),
1192 ds_volno
, ds_volcnt
);
1193 if (n
= getvol(ods_name
, NULL
, DM_FORMAT
, prompt
))
1195 if ((ds_fd
= open(dstdev
.cdevice
, O_WRONLY
)) < 0) {
1196 progerr(pkg_gt(ERR_TRANSFER
));
1197 logerr(pkg_gt(MSG_OPEN
), dstdev
.cdevice
,
1201 if (ds_ginit(dstdev
.cdevice
) < 0) {
1202 progerr(pkg_gt(ERR_TRANSFER
));
1203 logerr(pkg_gt(MSG_OPEN
), dstdev
.cdevice
,
1209 (void) sscanf(volnos
, "%d %[ 0-9]", &index
, tmpvol
);
1210 (void) strlcpy(volnos
, tmpvol
, sizeof (volnos
));
1211 curpartcnt
+= index
;
1214 if (options
& PT_INFO_ONLY
)
1218 (void) snprintf(cmd
, sizeof (cmd
),
1219 "find %s %s", PKGINFO
, PKGMAP
);
1220 if (nparts
&& (isdir(INSTALL
) == 0)) {
1221 (void) strlcat(cmd
, " ", sizeof (cmd
));
1222 (void) strlcat(cmd
, INSTALL
, sizeof (cmd
));
1225 (void) snprintf(cmd
, sizeof (cmd
), "find %s", PKGINFO
);
1228 (void) snprintf(temp
, sizeof (temp
),
1229 "%s.%d", RELOC
, part
);
1230 if (iscpio(temp
, &iscomp
) || isdir(temp
) == 0) {
1231 (void) strlcat(cmd
, " ", sizeof (cmd
));
1232 (void) strlcat(cmd
, temp
, sizeof (cmd
));
1234 (void) snprintf(temp
, sizeof (temp
),
1235 "%s.%d", ROOT
, part
);
1236 if (iscpio(temp
, &iscomp
) || isdir(temp
) == 0) {
1237 (void) strlcat(cmd
, " ", sizeof (cmd
));
1238 (void) strlcat(cmd
, temp
, sizeof (cmd
));
1240 (void) snprintf(temp
, sizeof (temp
),
1241 "%s.%d", ARCHIVE
, part
);
1242 if (isdir(temp
) == 0) {
1243 (void) strlcat(cmd
, " ", sizeof (cmd
));
1244 (void) strlcat(cmd
, temp
, sizeof (cmd
));
1246 } else if (nparts
) {
1247 for (i
= 0; reloc_names
[i
] != NULL
; i
++) {
1248 if (iscpio(reloc_names
[i
], &iscomp
) ||
1249 isdir(reloc_names
[i
]) == 0) {
1250 (void) strlcat(cmd
, " ", sizeof (cmd
));
1251 (void) strlcat(cmd
, reloc_names
[i
],
1255 for (i
= 0; root_names
[i
] != NULL
; i
++) {
1256 if (iscpio(root_names
[i
], &iscomp
) ||
1257 isdir(root_names
[i
]) == 0) {
1258 (void) strlcat(cmd
, " ", sizeof (cmd
));
1259 (void) strlcat(cmd
, root_names
[i
],
1263 if (isdir(ARCHIVE
) == 0) {
1264 (void) strlcat(cmd
, " ", sizeof (cmd
));
1265 (void) strlcat(cmd
, ARCHIVE
, sizeof (cmd
));
1268 if (options
& PT_ODTSTREAM
) {
1269 (void) snprintf(cmd
+ strlen(cmd
),
1270 sizeof (cmd
) - strlen(cmd
),
1271 " -print | %s -ocD -C %d",
1272 CPIOPROC
, (int)BLK_SIZE
);
1274 if (statvfs64(dstdir
, &svfsb
) == -1) {
1275 progerr(pkg_gt(ERR_TRANSFER
));
1276 logerr(pkg_gt(MSG_STATVFS
), dstdir
, errno
);
1280 free_blocks
= (((long)svfsb
.f_frsize
> 0) ?
1281 howmany(svfsb
.f_frsize
, DEV_BSIZE
) :
1282 howmany(svfsb
.f_bsize
, DEV_BSIZE
)) * svfsb
.f_bavail
;
1284 if ((has_comp_size
? compressedsize
: maxpartsize
) >
1286 progerr(pkg_gt(ERR_TRANSFER
));
1287 logerr(pkg_gt(MSG_NOSPACE
),
1289 (long)compressedsize
: (long)maxpartsize
,
1293 (void) snprintf(cmd
+ strlen(cmd
),
1294 sizeof (cmd
) - strlen(cmd
),
1295 " -print | %s -pdum %s",
1299 n
= esystem(cmd
, -1, (options
& PT_ODTSTREAM
) ? ds_fd
: -1);
1302 progerr(pkg_gt(ERR_TRANSFER
));
1303 logerr(pkg_gt(MSG_CMDFAIL
), cmd
, n
);
1308 if (srcdev
.mount
&& (nparts
> 1)) {
1309 /* unmount current source volume */
1311 if (pkgumount(&srcdev
))
1313 /* loop until volume is mounted successfully */
1314 while (part
<= nparts
) {
1316 n
= pkgmount(&srcdev
, NULL
, part
, nparts
, 1);
1319 if (chdir(srcdir
)) {
1320 progerr(pkg_gt(ERR_TRANSFER
));
1321 logerr(pkg_gt(MSG_CORRUPT
));
1323 (void) pkgumount(&srcdev
);
1326 if (ckvolseq(srcdir
, part
, nparts
)) {
1328 (void) pkgumount(&srcdev
);
1334 if (!(options
& PT_ODTSTREAM
) && dstdev
.mount
) {
1335 /* unmount current volume */
1336 if (pkgumount(&dstdev
))
1338 /* loop until next volume is mounted successfully */
1339 while (part
<= nparts
) {
1341 n
= pkgmount(&dstdev
, NULL
, part
, nparts
, 1);
1344 if (ckoverwrite(dst
, dstinst
, options
))
1346 if (isdir(dstdir
) && mkdir(dstdir
, 0755)) {
1347 progerr(pkg_gt(ERR_TRANSFER
));
1348 logerr(pkg_gt(MSG_MKDIR
), dstdir
);
1355 if ((options
& PT_ODTSTREAM
) && part
<= nparts
) {
1356 if (curpartcnt
>= 0 && part
> curpartcnt
) {
1362 (void) sprintf(prompt
,
1363 pkg_gt("Insert %%v %d of %d into %%p"),
1364 ds_volno
, ds_volcnt
);
1365 if (n
= getvol(ods_name
, NULL
, DM_FORMAT
,
1368 if ((ds_fd
= open(dstdev
.cdevice
, 1)) < 0) {
1369 progerr(pkg_gt(ERR_TRANSFER
));
1370 logerr(pkg_gt(MSG_OPEN
),
1371 dstdev
.cdevice
, errno
);
1374 if (ds_ginit(dstdev
.cdevice
) < 0) {
1375 progerr(pkg_gt(ERR_TRANSFER
));
1376 logerr(pkg_gt(MSG_OPEN
),
1377 dstdev
.cdevice
, errno
);
1382 (void) sscanf(volnos
, "%d %[ 0-9]", &index
,
1384 (void) strlcpy(volnos
, tmpvol
, sizeof (volnos
));
1385 curpartcnt
+= index
;
1396 _NOTE(ARGUNUSED(signo
));
1405 (void) rrmdir(tmpdir
);
1411 /* remove any previous tmppath stuff */
1412 (void) rrmdir(tmppath
);
1418 /* remove temp symbolic links made for signed pkg */
1419 (void) rrmdir(tmpsymdir
);
1424 if (srcdev
.mount
&& !ids_name
)
1425 (void) pkgumount(&srcdev
);
1426 if (dstdev
.mount
&& !ods_name
)
1427 (void) pkgumount(&dstdev
);