15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland * CDDL HEADER START
35c51f124SMoriah Waterland *
45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland *
85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland * See the License for the specific language governing permissions
115c51f124SMoriah Waterland * and limitations under the License.
125c51f124SMoriah Waterland *
135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland *
195c51f124SMoriah Waterland * CDDL HEADER END
205c51f124SMoriah Waterland */
215c51f124SMoriah Waterland
225c51f124SMoriah Waterland /*
2332991bedSPeter Tribble * Copyright (c) 2017 Peter Tribble.
2432991bedSPeter Tribble */
2532991bedSPeter Tribble
2632991bedSPeter Tribble /*
275c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
285c51f124SMoriah Waterland * Use is subject to license terms.
295c51f124SMoriah Waterland */
305c51f124SMoriah Waterland
315c51f124SMoriah Waterland /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
325c51f124SMoriah Waterland /* All Rights Reserved */
335c51f124SMoriah Waterland
345c51f124SMoriah Waterland
355c51f124SMoriah Waterland
365c51f124SMoriah Waterland #include <stdio.h>
375c51f124SMoriah Waterland #include <errno.h>
385c51f124SMoriah Waterland #include <stdarg.h>
395c51f124SMoriah Waterland #include <limits.h>
405c51f124SMoriah Waterland #include <stdlib.h>
415c51f124SMoriah Waterland #include <unistd.h>
425c51f124SMoriah Waterland #include <fcntl.h>
435c51f124SMoriah Waterland #include <ctype.h>
445c51f124SMoriah Waterland #include <string.h>
455c51f124SMoriah Waterland #include <sys/types.h>
465c51f124SMoriah Waterland #include <sys/param.h>
475c51f124SMoriah Waterland #include <sys/stat.h>
485c51f124SMoriah Waterland #include <sys/statvfs.h>
495c51f124SMoriah Waterland #include <sys/sysmacros.h>
505c51f124SMoriah Waterland #include <dirent.h>
515c51f124SMoriah Waterland #include <signal.h>
525c51f124SMoriah Waterland #include <devmgmt.h>
534656d474SGarrett D'Amore #include <note.h>
545c51f124SMoriah Waterland #include "pkginfo.h"
555c51f124SMoriah Waterland #include "pkgstrct.h"
565c51f124SMoriah Waterland #include "pkgtrans.h"
575c51f124SMoriah Waterland #include "pkgdev.h"
585c51f124SMoriah Waterland #include "pkglib.h"
595c51f124SMoriah Waterland #include "pkglibmsgs.h"
605c51f124SMoriah Waterland #include "pkglocale.h"
615c51f124SMoriah Waterland
625c51f124SMoriah Waterland extern char *pkgdir; /* pkgparam.c */
635c51f124SMoriah Waterland
645c51f124SMoriah Waterland /* libadm.a */
655c51f124SMoriah Waterland extern char *devattr(char *device, char *attribute);
665c51f124SMoriah Waterland extern char *fpkginst(char *pkg, ...);
675c51f124SMoriah Waterland extern int fpkginfo(struct pkginfo *info, char *pkginst);
685c51f124SMoriah Waterland extern int getvol(char *device, char *label, int options, char *prompt);
695c51f124SMoriah Waterland extern int _getvol(char *device, char *label, int options, char *prompt,
705c51f124SMoriah Waterland char *norewind);
715c51f124SMoriah Waterland
725c51f124SMoriah Waterland /* dstream.c */
735c51f124SMoriah Waterland extern int ds_ginit(char *device);
745c51f124SMoriah Waterland extern int ds_close(int pkgendflg);
755c51f124SMoriah Waterland
765c51f124SMoriah Waterland #define CPIOPROC "/usr/bin/cpio"
775c51f124SMoriah Waterland
785c51f124SMoriah Waterland #define CMDSIZE 512 /* command block size */
795c51f124SMoriah Waterland
805c51f124SMoriah Waterland #define BLK_SIZE 512 /* size of logical block */
815c51f124SMoriah Waterland
825c51f124SMoriah Waterland #define ENTRY_MAX 256 /* max size of entry for cpio cmd or header */
835c51f124SMoriah Waterland
845c51f124SMoriah Waterland #define PKGINFO "pkginfo"
855c51f124SMoriah Waterland #define PKGMAP "pkgmap"
865c51f124SMoriah Waterland #define MAP_STAT_SIZE 60 /* 1st line of pkgmap (3 numbers & a : */
875c51f124SMoriah Waterland
885c51f124SMoriah Waterland #define INSTALL "install"
895c51f124SMoriah Waterland #define RELOC "reloc"
905c51f124SMoriah Waterland #define ROOT "root"
915c51f124SMoriah Waterland #define ARCHIVE "archive"
925c51f124SMoriah Waterland
935c51f124SMoriah Waterland static struct pkgdev srcdev, dstdev;
945c51f124SMoriah Waterland static char *tmpdir;
955c51f124SMoriah Waterland static char *tmppath;
965c51f124SMoriah Waterland static char *tmpsymdir = NULL;
975c51f124SMoriah Waterland static char dstinst[NON_ABI_NAMELNGTH];
985c51f124SMoriah Waterland static char *ids_name, *ods_name;
995c51f124SMoriah Waterland static int ds_volcnt;
1005c51f124SMoriah Waterland static int ds_volno;
1015c51f124SMoriah Waterland static int compressedsize, has_comp_size;
1025c51f124SMoriah Waterland
1035c51f124SMoriah Waterland static void (*sigintHandler)();
1045c51f124SMoriah Waterland static void (*sighupHandler)();
1055c51f124SMoriah Waterland static void cleanup(void);
1065c51f124SMoriah Waterland static void sigtrap(int signo);
1075c51f124SMoriah Waterland static int rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize);
1085c51f124SMoriah Waterland
1095c51f124SMoriah Waterland static int cat_and_count(struct dm_buf *, char *);
1105c51f124SMoriah Waterland
1115c51f124SMoriah Waterland static int ckoverwrite(char *dir, char *inst, int options);
1125c51f124SMoriah Waterland static int pkgxfer(char *srcinst, int options);
11332991bedSPeter Tribble static int wdsheader(struct dm_buf *, char *device, char **pkg);
1144656d474SGarrett D'Amore static struct dm_buf *genheader(char *, char **);
1155c51f124SMoriah Waterland
1165c51f124SMoriah Waterland extern int ds_fd; /* open file descriptor for data stream WHERE? */
1175c51f124SMoriah Waterland
1185c51f124SMoriah Waterland static char *root_names[] = {
1195c51f124SMoriah Waterland "root",
1205c51f124SMoriah Waterland "root.cpio",
1215c51f124SMoriah Waterland "root.Z",
1225c51f124SMoriah Waterland "root.cpio.Z",
1235c51f124SMoriah Waterland 0
1245c51f124SMoriah Waterland };
1255c51f124SMoriah Waterland
1265c51f124SMoriah Waterland static char *reloc_names[] = {
1275c51f124SMoriah Waterland "reloc",
1285c51f124SMoriah Waterland "reloc.cpio",
1295c51f124SMoriah Waterland "reloc.Z",
1305c51f124SMoriah Waterland "reloc.cpio.Z",
1315c51f124SMoriah Waterland 0
1325c51f124SMoriah Waterland };
1335c51f124SMoriah Waterland
1345c51f124SMoriah Waterland static int signal_received = 0;
1355c51f124SMoriah Waterland
1365c51f124SMoriah Waterland char **xpkg; /* array of transferred packages */
1375c51f124SMoriah Waterland int nxpkg;
1385c51f124SMoriah Waterland
1395c51f124SMoriah Waterland static char *allpkg[] = {
1405c51f124SMoriah Waterland "all",
1415c51f124SMoriah Waterland NULL
1425c51f124SMoriah Waterland };
1435c51f124SMoriah Waterland
1445c51f124SMoriah Waterland static struct dm_buf hdrbuf;
1455c51f124SMoriah Waterland static char *pinput, *nextpinput;
1465c51f124SMoriah Waterland
1475c51f124SMoriah Waterland int
pkghead(char * device)1485c51f124SMoriah Waterland pkghead(char *device)
1495c51f124SMoriah Waterland {
1505c51f124SMoriah Waterland char *pt;
1515c51f124SMoriah Waterland int n;
1525c51f124SMoriah Waterland
1535c51f124SMoriah Waterland cleanup();
1545c51f124SMoriah Waterland
1555c51f124SMoriah Waterland
1565c51f124SMoriah Waterland if (device == NULL)
1575c51f124SMoriah Waterland return (0);
1585c51f124SMoriah Waterland else if ((device[0] == '/') && !isdir(device)) {
1595c51f124SMoriah Waterland pkgdir = device;
1605c51f124SMoriah Waterland return (0);
1615c51f124SMoriah Waterland } else if ((pt = devattr(device, "pathname")) != NULL && !isdir(pt)) {
1625c51f124SMoriah Waterland pkgdir = pt;
1635c51f124SMoriah Waterland return (0);
1645c51f124SMoriah Waterland }
1655c51f124SMoriah Waterland
1665c51f124SMoriah Waterland /* check for datastream */
16732991bedSPeter Tribble if (n = pkgtrans(device, (char *)0, allpkg, PT_SILENT|PT_INFO_ONLY)) {
1685c51f124SMoriah Waterland cleanup();
1695c51f124SMoriah Waterland return (n);
1705c51f124SMoriah Waterland }
1715c51f124SMoriah Waterland /* pkgtrans has set pkgdir */
1725c51f124SMoriah Waterland return (0);
1735c51f124SMoriah Waterland }
1745c51f124SMoriah Waterland
1755c51f124SMoriah Waterland static char *
mgets(char * buf,int size)1765c51f124SMoriah Waterland mgets(char *buf, int size)
1775c51f124SMoriah Waterland {
1785c51f124SMoriah Waterland nextpinput = strchr(pinput, '\n');
1795c51f124SMoriah Waterland if (nextpinput == NULL)
1805c51f124SMoriah Waterland return (0);
1815c51f124SMoriah Waterland *nextpinput = '\0';
1825c51f124SMoriah Waterland if ((int)strlen(pinput) > size)
1835c51f124SMoriah Waterland return (0);
1845c51f124SMoriah Waterland (void) strncpy(buf, pinput, strlen(pinput));
1855c51f124SMoriah Waterland buf[strlen(pinput)] = '\0';
1865c51f124SMoriah Waterland pinput = nextpinput + 1;
1875c51f124SMoriah Waterland return (buf);
1885c51f124SMoriah Waterland }
1895c51f124SMoriah Waterland /*
1905c51f124SMoriah Waterland * Here we construct the package size summaries for the headers. The
1915c51f124SMoriah Waterland * pkgmap file associated with fp must be rewound to the beginning of the
1925c51f124SMoriah Waterland * file. Note that we read three values from pkgmap first line in order
1935c51f124SMoriah Waterland * to get the *actual* size if this package is compressed.
1945c51f124SMoriah Waterland * This returns
1955c51f124SMoriah Waterland * 0 : error
1965c51f124SMoriah Waterland * 2 : not a compressed package
1975c51f124SMoriah Waterland * 3 : compressed package
1985c51f124SMoriah Waterland * and sets has_comp_size to indicate whether or not this is a compressed
1995c51f124SMoriah Waterland * package.
2005c51f124SMoriah Waterland */
2015c51f124SMoriah Waterland static int
rd_map_size(FILE * fp,int * npts,int * maxpsz,int * cmpsize)2025c51f124SMoriah Waterland rd_map_size(FILE *fp, int *npts, int *maxpsz, int *cmpsize)
2035c51f124SMoriah Waterland {
2045c51f124SMoriah Waterland int n;
2055c51f124SMoriah Waterland char line_buffer[MAP_STAT_SIZE];
2065c51f124SMoriah Waterland
2075c51f124SMoriah Waterland /* First read the null terminated first line */
2085c51f124SMoriah Waterland if (fgets(line_buffer, MAP_STAT_SIZE, fp) == NULL) {
2095c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
2105c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOSIZE));
2115c51f124SMoriah Waterland (void) fclose(fp);
2125c51f124SMoriah Waterland ecleanup();
2135c51f124SMoriah Waterland return (0);
2145c51f124SMoriah Waterland }
2155c51f124SMoriah Waterland
2165c51f124SMoriah Waterland n = sscanf(line_buffer, ": %d %d %d", npts, maxpsz, cmpsize);
2175c51f124SMoriah Waterland
2185c51f124SMoriah Waterland if (n == 3) /* A valid compressed package entry */
2195c51f124SMoriah Waterland has_comp_size = 1;
2205c51f124SMoriah Waterland else if (n == 2) /* A valid standard package entry */
2215c51f124SMoriah Waterland has_comp_size = 0;
2225c51f124SMoriah Waterland else { /* invalid entry */
2235c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
2245c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOSIZE));
2255c51f124SMoriah Waterland (void) fclose(fp);
2265c51f124SMoriah Waterland ecleanup();
2275c51f124SMoriah Waterland return (0);
2285c51f124SMoriah Waterland }
2295c51f124SMoriah Waterland
2305c51f124SMoriah Waterland return (n);
2315c51f124SMoriah Waterland }
2325c51f124SMoriah Waterland
2335c51f124SMoriah Waterland /* will return 0, 1, 3, or 99 */
2345c51f124SMoriah Waterland static int
_pkgtrans(char * device1,char * device2,char ** pkg,int options)23532991bedSPeter Tribble _pkgtrans(char *device1, char *device2, char **pkg, int options)
2365c51f124SMoriah Waterland {
2375c51f124SMoriah Waterland char *src, *dst;
2385c51f124SMoriah Waterland int errflg, i, n;
2395c51f124SMoriah Waterland struct dm_buf *hdr;
2405c51f124SMoriah Waterland
2415c51f124SMoriah Waterland if (signal_received > 0) {
2425c51f124SMoriah Waterland return (1);
2435c51f124SMoriah Waterland }
2445c51f124SMoriah Waterland
2455c51f124SMoriah Waterland /* transfer spool to appropriate device */
2465c51f124SMoriah Waterland if (devtype(device1, &srcdev)) {
2475c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
2485c51f124SMoriah Waterland logerr(pkg_gt(MSG_BADDEV), device1);
2495c51f124SMoriah Waterland return (1);
2505c51f124SMoriah Waterland }
2515c51f124SMoriah Waterland srcdev.rdonly++;
2525c51f124SMoriah Waterland
2535c51f124SMoriah Waterland /* check for datastream */
2545c51f124SMoriah Waterland ids_name = NULL;
2555c51f124SMoriah Waterland if (srcdev.bdevice) {
256*3970c098SToomas Soome if (n = _getvol(srcdev.bdevice, NULL, 0,
2575c51f124SMoriah Waterland pkg_gt("Insert %v into %p."), srcdev.norewind)) {
2585c51f124SMoriah Waterland cleanup();
2595c51f124SMoriah Waterland if (n == 3)
2605c51f124SMoriah Waterland return (3);
2615c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
2625c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL));
2635c51f124SMoriah Waterland return (1);
2645c51f124SMoriah Waterland }
2655c51f124SMoriah Waterland if (ds_readbuf(srcdev.cdevice))
2665c51f124SMoriah Waterland ids_name = srcdev.cdevice;
2675c51f124SMoriah Waterland }
2685c51f124SMoriah Waterland
2695c51f124SMoriah Waterland if (srcdev.cdevice && !srcdev.bdevice)
2705c51f124SMoriah Waterland ids_name = srcdev.cdevice;
2715c51f124SMoriah Waterland else if (srcdev.pathname) {
2725c51f124SMoriah Waterland ids_name = srcdev.pathname;
2735c51f124SMoriah Waterland if (access(ids_name, 0) == -1) {
2745c51f124SMoriah Waterland progerr(ERR_TRANSFER);
2755c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL));
2765c51f124SMoriah Waterland return (1);
2775c51f124SMoriah Waterland }
2785c51f124SMoriah Waterland }
2795c51f124SMoriah Waterland
2805c51f124SMoriah Waterland if (!ids_name && device2 == (char *)0) {
2815c51f124SMoriah Waterland if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) {
2825c51f124SMoriah Waterland cleanup();
2835c51f124SMoriah Waterland return (n);
2845c51f124SMoriah Waterland }
2855c51f124SMoriah Waterland if (srcdev.mount && *srcdev.mount)
2865c51f124SMoriah Waterland pkgdir = strdup(srcdev.mount);
2875c51f124SMoriah Waterland return (0);
2885c51f124SMoriah Waterland }
2895c51f124SMoriah Waterland
2905c51f124SMoriah Waterland if (ids_name && device2 == (char *)0) {
2915c51f124SMoriah Waterland tmppath = tmpnam(NULL);
2925c51f124SMoriah Waterland tmppath = strdup(tmppath);
2935c51f124SMoriah Waterland if (tmppath == NULL) {
2945c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
2955c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
2965c51f124SMoriah Waterland return (1);
2975c51f124SMoriah Waterland }
2985c51f124SMoriah Waterland if (mkdir(tmppath, 0755)) {
2995c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3005c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), tmppath);
3015c51f124SMoriah Waterland return (1);
3025c51f124SMoriah Waterland }
3035c51f124SMoriah Waterland device2 = tmppath;
3045c51f124SMoriah Waterland }
3055c51f124SMoriah Waterland
3065c51f124SMoriah Waterland if (devtype(device2, &dstdev)) {
3075c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3085c51f124SMoriah Waterland logerr(pkg_gt(MSG_BADDEV), device2);
3095c51f124SMoriah Waterland return (1);
3105c51f124SMoriah Waterland }
3115c51f124SMoriah Waterland
3125c51f124SMoriah Waterland if ((srcdev.cdevice && dstdev.cdevice) &&
3135c51f124SMoriah Waterland strcmp(srcdev.cdevice, dstdev.cdevice) == 0) {
3145c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3155c51f124SMoriah Waterland logerr(pkg_gt(MSG_SAMEDEV));
3165c51f124SMoriah Waterland return (1);
3175c51f124SMoriah Waterland }
3185c51f124SMoriah Waterland
3195c51f124SMoriah Waterland ods_name = NULL;
3205c51f124SMoriah Waterland if (dstdev.cdevice && !dstdev.bdevice || dstdev.pathname)
3215c51f124SMoriah Waterland options |= PT_ODTSTREAM;
3225c51f124SMoriah Waterland
3235c51f124SMoriah Waterland if (options & PT_ODTSTREAM) {
3245c51f124SMoriah Waterland if (!((ods_name = dstdev.cdevice) != NULL ||
3255c51f124SMoriah Waterland (ods_name = dstdev.pathname) != NULL)) {
3265c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3275c51f124SMoriah Waterland logerr(pkg_gt(MSG_BADDEV), device2);
3285c51f124SMoriah Waterland return (1);
3295c51f124SMoriah Waterland }
3305c51f124SMoriah Waterland if (ids_name) {
3315c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3325c51f124SMoriah Waterland logerr(pkg_gt(MSG_TWODSTREAM));
3335c51f124SMoriah Waterland return (1);
3345c51f124SMoriah Waterland }
3355c51f124SMoriah Waterland }
3365c51f124SMoriah Waterland
3375c51f124SMoriah Waterland if ((srcdev.dirname && dstdev.dirname) &&
3385c51f124SMoriah Waterland strcmp(srcdev.dirname, dstdev.dirname) == 0) {
3395c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3405c51f124SMoriah Waterland logerr(pkg_gt(MSG_SAMEDEV));
3415c51f124SMoriah Waterland return (1);
3425c51f124SMoriah Waterland }
3435c51f124SMoriah Waterland
3445c51f124SMoriah Waterland if ((srcdev.pathname && dstdev.pathname) &&
3455c51f124SMoriah Waterland strcmp(srcdev.pathname, dstdev.pathname) == 0) {
3465c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3475c51f124SMoriah Waterland logerr(pkg_gt(MSG_SAMEDEV));
3485c51f124SMoriah Waterland return (1);
3495c51f124SMoriah Waterland }
3505c51f124SMoriah Waterland
3515c51f124SMoriah Waterland if (signal_received > 0) {
3525c51f124SMoriah Waterland return (1);
3535c51f124SMoriah Waterland }
3545c51f124SMoriah Waterland
3555c51f124SMoriah Waterland if (ids_name) {
3565c51f124SMoriah Waterland if (srcdev.cdevice && !srcdev.bdevice &&
357*3970c098SToomas Soome (n = _getvol(srcdev.cdevice, NULL, 0, NULL,
3585c51f124SMoriah Waterland srcdev.norewind))) {
3595c51f124SMoriah Waterland cleanup();
3605c51f124SMoriah Waterland if (n == 3)
3615c51f124SMoriah Waterland return (3);
3625c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3635c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL));
3645c51f124SMoriah Waterland return (1);
3655c51f124SMoriah Waterland }
3665c51f124SMoriah Waterland if (srcdev.dirname = tmpnam(NULL))
3675c51f124SMoriah Waterland tmpdir = srcdev.dirname = strdup(srcdev.dirname);
3685c51f124SMoriah Waterland
3695c51f124SMoriah Waterland if ((srcdev.dirname == NULL) || mkdir(srcdev.dirname, 0755) ||
3705c51f124SMoriah Waterland chdir(srcdev.dirname)) {
3715c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3725c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOTEMP), srcdev.dirname);
3735c51f124SMoriah Waterland cleanup();
3745c51f124SMoriah Waterland return (1);
3755c51f124SMoriah Waterland }
3765c51f124SMoriah Waterland if (ds_init(ids_name, pkg, srcdev.norewind)) {
3775c51f124SMoriah Waterland cleanup();
3785c51f124SMoriah Waterland return (1);
3795c51f124SMoriah Waterland }
3805c51f124SMoriah Waterland } else if (srcdev.mount) {
3815c51f124SMoriah Waterland if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) {
3825c51f124SMoriah Waterland cleanup();
3835c51f124SMoriah Waterland return (n);
3845c51f124SMoriah Waterland }
3855c51f124SMoriah Waterland }
3865c51f124SMoriah Waterland
3875c51f124SMoriah Waterland src = srcdev.dirname;
3885c51f124SMoriah Waterland dst = dstdev.dirname;
3895c51f124SMoriah Waterland
3905c51f124SMoriah Waterland if (chdir(src)) {
3915c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
3925c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), src);
3935c51f124SMoriah Waterland cleanup();
3945c51f124SMoriah Waterland return (1);
3955c51f124SMoriah Waterland }
3965c51f124SMoriah Waterland
3975c51f124SMoriah Waterland if (signal_received > 0) {
3985c51f124SMoriah Waterland return (1);
3995c51f124SMoriah Waterland }
4005c51f124SMoriah Waterland
4015c51f124SMoriah Waterland xpkg = pkg = gpkglist(src, pkg, NULL);
4025c51f124SMoriah Waterland if (!pkg) {
4035c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
4045c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOPKGS), src);
4055c51f124SMoriah Waterland cleanup();
4065c51f124SMoriah Waterland return (1);
4075c51f124SMoriah Waterland }
4085c51f124SMoriah Waterland
4095c51f124SMoriah Waterland for (nxpkg = 0; pkg[nxpkg]; /* void */) {
4105c51f124SMoriah Waterland nxpkg++; /* count */
4115c51f124SMoriah Waterland }
4125c51f124SMoriah Waterland
4135c51f124SMoriah Waterland if (ids_name) {
4145c51f124SMoriah Waterland ds_order(pkg); /* order requests */
4155c51f124SMoriah Waterland }
4165c51f124SMoriah Waterland
4175c51f124SMoriah Waterland if (signal_received > 0) {
4185c51f124SMoriah Waterland return (1);
4195c51f124SMoriah Waterland }
4205c51f124SMoriah Waterland
4215c51f124SMoriah Waterland if (options & PT_ODTSTREAM) {
4225c51f124SMoriah Waterland char line[128];
4235c51f124SMoriah Waterland
4245c51f124SMoriah Waterland if (!dstdev.pathname &&
4255c51f124SMoriah Waterland (n = _getvol(ods_name, NULL, DM_FORMAT, NULL,
4265c51f124SMoriah Waterland dstdev.norewind))) {
4275c51f124SMoriah Waterland cleanup();
4285c51f124SMoriah Waterland if (n == 3)
4295c51f124SMoriah Waterland return (3);
4305c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
4315c51f124SMoriah Waterland logerr(pkg_gt(MSG_GETVOL));
4325c51f124SMoriah Waterland return (1);
4335c51f124SMoriah Waterland }
4344656d474SGarrett D'Amore if ((hdr = genheader(src, pkg)) == NULL) {
4355c51f124SMoriah Waterland cleanup();
4365c51f124SMoriah Waterland return (1);
4375c51f124SMoriah Waterland }
4385c51f124SMoriah Waterland
43932991bedSPeter Tribble /* write out header to stream */
44032991bedSPeter Tribble if (wdsheader(hdr, ods_name, pkg)) {
4415c51f124SMoriah Waterland cleanup();
4425c51f124SMoriah Waterland return (1);
4435c51f124SMoriah Waterland }
4445c51f124SMoriah Waterland
4455c51f124SMoriah Waterland ds_volno = 1; /* number of volumes in datastream */
4465c51f124SMoriah Waterland pinput = hdrbuf.text_buffer;
4475c51f124SMoriah Waterland /* skip past first line in header */
4485c51f124SMoriah Waterland (void) mgets(line, 128);
4495c51f124SMoriah Waterland }
4505c51f124SMoriah Waterland
4515c51f124SMoriah Waterland if (signal_received > 0) {
4525c51f124SMoriah Waterland return (1);
4535c51f124SMoriah Waterland }
4545c51f124SMoriah Waterland
4555c51f124SMoriah Waterland errflg = 0;
4565c51f124SMoriah Waterland
4575c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) {
4585c51f124SMoriah Waterland
4595c51f124SMoriah Waterland if (signal_received > 0) {
4605c51f124SMoriah Waterland return (1);
4615c51f124SMoriah Waterland }
4625c51f124SMoriah Waterland
4635c51f124SMoriah Waterland if (!(options & PT_ODTSTREAM) && dstdev.mount) {
4645c51f124SMoriah Waterland if (n = pkgmount(&dstdev, NULL, 0, 0, 1)) {
4655c51f124SMoriah Waterland cleanup();
4665c51f124SMoriah Waterland return (n);
4675c51f124SMoriah Waterland }
4685c51f124SMoriah Waterland }
4695c51f124SMoriah Waterland if (errflg = pkgxfer(pkg[i], options)) {
4705c51f124SMoriah Waterland pkg[i] = NULL;
4715c51f124SMoriah Waterland if ((options & PT_ODTSTREAM) || (errflg != 2))
4725c51f124SMoriah Waterland break;
4735c51f124SMoriah Waterland } else if (strcmp(dstinst, pkg[i]))
4745c51f124SMoriah Waterland pkg[i] = strdup(dstinst);
4755c51f124SMoriah Waterland }
4765c51f124SMoriah Waterland
4775c51f124SMoriah Waterland if (!(options & PT_ODTSTREAM) && dst) {
4785c51f124SMoriah Waterland pkgdir = strdup(dst);
4795c51f124SMoriah Waterland }
4805c51f124SMoriah Waterland
4815c51f124SMoriah Waterland /*
4825c51f124SMoriah Waterland * No cleanup of temporary directories created in this
4835c51f124SMoriah Waterland * function is done here. The calling function must do
4845c51f124SMoriah Waterland * the cleanup.
4855c51f124SMoriah Waterland */
4865c51f124SMoriah Waterland
4875c51f124SMoriah Waterland return (signal_received > 0 ? 1 : errflg);
4885c51f124SMoriah Waterland }
4895c51f124SMoriah Waterland
4905c51f124SMoriah Waterland int
pkgtrans(char * device1,char * device2,char ** pkg,int options)49132991bedSPeter Tribble pkgtrans(char *device1, char *device2, char **pkg, int options)
4925c51f124SMoriah Waterland {
4935c51f124SMoriah Waterland int r;
4945c51f124SMoriah Waterland struct sigaction nact;
4955c51f124SMoriah Waterland struct sigaction oact;
4965c51f124SMoriah Waterland
4975c51f124SMoriah Waterland /*
4985c51f124SMoriah Waterland * setup signal handlers for SIGINT and SIGHUP and release hold
4995c51f124SMoriah Waterland */
5005c51f124SMoriah Waterland
5015c51f124SMoriah Waterland /* hold SIGINT/SIGHUP interrupts */
5025c51f124SMoriah Waterland
5035c51f124SMoriah Waterland (void) sighold(SIGHUP);
5045c51f124SMoriah Waterland (void) sighold(SIGINT);
5055c51f124SMoriah Waterland
5065c51f124SMoriah Waterland /* hook SIGINT to sigtrap */
5075c51f124SMoriah Waterland
5085c51f124SMoriah Waterland nact.sa_handler = sigtrap;
5095c51f124SMoriah Waterland nact.sa_flags = SA_RESTART;
5105c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask);
5115c51f124SMoriah Waterland
5125c51f124SMoriah Waterland if (sigaction(SIGINT, &nact, &oact) < 0) {
5135c51f124SMoriah Waterland sigintHandler = SIG_DFL;
5145c51f124SMoriah Waterland } else {
5155c51f124SMoriah Waterland sigintHandler = oact.sa_handler;
5165c51f124SMoriah Waterland }
5175c51f124SMoriah Waterland
5185c51f124SMoriah Waterland /* hook SIGHUP to sigtrap */
5195c51f124SMoriah Waterland
5205c51f124SMoriah Waterland nact.sa_handler = sigtrap;
5215c51f124SMoriah Waterland nact.sa_flags = SA_RESTART;
5225c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask);
5235c51f124SMoriah Waterland
5245c51f124SMoriah Waterland if (sigaction(SIGHUP, &nact, &oact) < 0) {
5255c51f124SMoriah Waterland sighupHandler = SIG_DFL;
5265c51f124SMoriah Waterland } else {
5275c51f124SMoriah Waterland sighupHandler = oact.sa_handler;
5285c51f124SMoriah Waterland }
5295c51f124SMoriah Waterland
5305c51f124SMoriah Waterland /* reset signal received count */
5315c51f124SMoriah Waterland
5325c51f124SMoriah Waterland signal_received = 0;
5335c51f124SMoriah Waterland
5345c51f124SMoriah Waterland /* release hold on signals */
5355c51f124SMoriah Waterland
5365c51f124SMoriah Waterland (void) sigrelse(SIGHUP);
5375c51f124SMoriah Waterland (void) sigrelse(SIGINT);
5385c51f124SMoriah Waterland
5395c51f124SMoriah Waterland /*
5405c51f124SMoriah Waterland * perform the package translation
5415c51f124SMoriah Waterland */
5425c51f124SMoriah Waterland
54332991bedSPeter Tribble r = _pkgtrans(device1, device2, pkg, options);
5445c51f124SMoriah Waterland
5455c51f124SMoriah Waterland /*
5465c51f124SMoriah Waterland * reset signal handlers
5475c51f124SMoriah Waterland */
5485c51f124SMoriah Waterland
5495c51f124SMoriah Waterland /* hold SIGINT/SIGHUP interrupts */
5505c51f124SMoriah Waterland
5515c51f124SMoriah Waterland (void) sighold(SIGHUP);
5525c51f124SMoriah Waterland (void) sighold(SIGINT);
5535c51f124SMoriah Waterland
5545c51f124SMoriah Waterland /* reset SIGINT */
5555c51f124SMoriah Waterland
5565c51f124SMoriah Waterland nact.sa_handler = sigintHandler;
5575c51f124SMoriah Waterland nact.sa_flags = SA_RESTART;
5585c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask);
5595c51f124SMoriah Waterland
5605c51f124SMoriah Waterland (void) sigaction(SIGINT, &nact, (struct sigaction *)NULL);
5615c51f124SMoriah Waterland
5625c51f124SMoriah Waterland /* reset SIGHUP */
5635c51f124SMoriah Waterland
5645c51f124SMoriah Waterland nact.sa_handler = sighupHandler;
5655c51f124SMoriah Waterland nact.sa_flags = SA_RESTART;
5665c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask);
5675c51f124SMoriah Waterland
5685c51f124SMoriah Waterland (void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL);
5695c51f124SMoriah Waterland
5705c51f124SMoriah Waterland /* if signal received and pkgtrans returned error, call cleanup */
5715c51f124SMoriah Waterland
5725c51f124SMoriah Waterland if (signal_received > 0) {
5735c51f124SMoriah Waterland if (r != 0) {
5745c51f124SMoriah Waterland cleanup();
5755c51f124SMoriah Waterland }
5765c51f124SMoriah Waterland (void) kill(getpid(), SIGINT);
5775c51f124SMoriah Waterland }
5785c51f124SMoriah Waterland
5795c51f124SMoriah Waterland /* release hold on signals */
5805c51f124SMoriah Waterland
5815c51f124SMoriah Waterland (void) sigrelse(SIGHUP);
5825c51f124SMoriah Waterland (void) sigrelse(SIGINT);
5835c51f124SMoriah Waterland
5845c51f124SMoriah Waterland return (r);
5855c51f124SMoriah Waterland }
5865c51f124SMoriah Waterland
5875c51f124SMoriah Waterland /*
5885c51f124SMoriah Waterland * This function concatenates append to the text described in the buf_ctrl
5895c51f124SMoriah Waterland * structure. This code modifies data in this structure and handles all
5905c51f124SMoriah Waterland * allocation issues. It returns '0' if everything was successful and '1'
5915c51f124SMoriah Waterland * if not.
5925c51f124SMoriah Waterland */
5935c51f124SMoriah Waterland static int
cat_and_count(struct dm_buf * buf_ctrl,char * append)5945c51f124SMoriah Waterland cat_and_count(struct dm_buf *buf_ctrl, char *append)
5955c51f124SMoriah Waterland {
5965c51f124SMoriah Waterland
5975c51f124SMoriah Waterland /* keep allocating until we have enough room to hold string */
5985c51f124SMoriah Waterland while ((buf_ctrl->offset + (int)strlen(append))
5995c51f124SMoriah Waterland >= buf_ctrl->allocation) {
6005c51f124SMoriah Waterland /* reallocate (and maybe move) text buffer */
6015c51f124SMoriah Waterland if ((buf_ctrl->text_buffer =
6025c51f124SMoriah Waterland (char *)realloc(buf_ctrl->text_buffer,
6035c51f124SMoriah Waterland buf_ctrl->allocation + BLK_SIZE)) == NULL) {
6045c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
6055c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
6065c51f124SMoriah Waterland free(buf_ctrl->text_buffer);
6075c51f124SMoriah Waterland return (1);
6085c51f124SMoriah Waterland }
6095c51f124SMoriah Waterland
6105c51f124SMoriah Waterland /* clear the new memory */
6115c51f124SMoriah Waterland (void) memset(buf_ctrl->text_buffer +
6125c51f124SMoriah Waterland buf_ctrl->allocation, '\0', BLK_SIZE);
6135c51f124SMoriah Waterland
6145c51f124SMoriah Waterland /* adjust total allocation */
6155c51f124SMoriah Waterland buf_ctrl->allocation += BLK_SIZE;
6165c51f124SMoriah Waterland }
6175c51f124SMoriah Waterland
6185c51f124SMoriah Waterland /* append new string to end of buffer */
6195c51f124SMoriah Waterland while (*append) {
6205c51f124SMoriah Waterland *(buf_ctrl->text_buffer + buf_ctrl->offset) = *append++;
6215c51f124SMoriah Waterland (buf_ctrl->offset)++;
6225c51f124SMoriah Waterland }
6235c51f124SMoriah Waterland
6245c51f124SMoriah Waterland return (0);
6255c51f124SMoriah Waterland }
6265c51f124SMoriah Waterland
6275c51f124SMoriah Waterland static struct dm_buf *
genheader(char * src,char ** pkg)6284656d474SGarrett D'Amore genheader(char *src, char **pkg)
6295c51f124SMoriah Waterland {
6305c51f124SMoriah Waterland
6315c51f124SMoriah Waterland FILE *fp;
6325c51f124SMoriah Waterland char path[MAXPATHLEN], tmp_entry[ENTRY_MAX];
6335c51f124SMoriah Waterland int i, n, nparts, maxpsize;
6344656d474SGarrett D'Amore int partcnt;
6354656d474SGarrett D'Amore long totsize;
6365c51f124SMoriah Waterland struct stat statbuf;
6375c51f124SMoriah Waterland
6385c51f124SMoriah Waterland if ((hdrbuf.text_buffer = (char *)malloc(BLK_SIZE)) == NULL) {
6395c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
6405c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
6415c51f124SMoriah Waterland return (NULL);
6425c51f124SMoriah Waterland }
6435c51f124SMoriah Waterland
6445c51f124SMoriah Waterland /* clear the new memory */
6455c51f124SMoriah Waterland (void) memset(hdrbuf.text_buffer, '\0', BLK_SIZE);
6465c51f124SMoriah Waterland
6475c51f124SMoriah Waterland /* set up the buffer control structure for the header */
6485c51f124SMoriah Waterland hdrbuf.offset = 0;
6495c51f124SMoriah Waterland hdrbuf.allocation = BLK_SIZE;
6505c51f124SMoriah Waterland
6515c51f124SMoriah Waterland (void) cat_and_count(&hdrbuf, HDR_PREFIX);
6525c51f124SMoriah Waterland (void) cat_and_count(&hdrbuf, "\n");
6535c51f124SMoriah Waterland
6545c51f124SMoriah Waterland nparts = maxpsize = 0;
6555c51f124SMoriah Waterland
6565c51f124SMoriah Waterland totsize = 0;
6575c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) {
6585c51f124SMoriah Waterland (void) snprintf(path, MAXPATHLEN, "%s/%s/%s",
6595c51f124SMoriah Waterland src, pkg[i], PKGINFO);
6605c51f124SMoriah Waterland if (stat(path, &statbuf) < 0) {
6615c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
6625c51f124SMoriah Waterland logerr(pkg_gt(MSG_BADPKGINFO));
6635c51f124SMoriah Waterland ecleanup();
6645c51f124SMoriah Waterland return (NULL);
6655c51f124SMoriah Waterland }
6665c51f124SMoriah Waterland totsize += statbuf.st_size/BLK_SIZE + 1;
6675c51f124SMoriah Waterland }
6685c51f124SMoriah Waterland
6695c51f124SMoriah Waterland /*
6705c51f124SMoriah Waterland * totsize contains number of blocks used by the pkginfo files
6715c51f124SMoriah Waterland */
6725c51f124SMoriah Waterland totsize += i/4 + 1;
6735c51f124SMoriah Waterland if (dstdev.capacity && totsize > dstdev.capacity) {
6745c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
6755c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOSPACE), totsize, dstdev.capacity);
6765c51f124SMoriah Waterland ecleanup();
6775c51f124SMoriah Waterland return (NULL);
6785c51f124SMoriah Waterland }
6795c51f124SMoriah Waterland
6805c51f124SMoriah Waterland ds_volcnt = 1;
6815c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) {
6825c51f124SMoriah Waterland partcnt = 0;
6835c51f124SMoriah Waterland (void) snprintf(path, MAXPATHLEN, "%s/%s/%s",
6845c51f124SMoriah Waterland src, pkg[i], PKGMAP);
6855c51f124SMoriah Waterland if ((fp = fopen(path, "r")) == NULL) {
6865c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
6875c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOPKGMAP), pkg[i]);
6885c51f124SMoriah Waterland ecleanup();
6895c51f124SMoriah Waterland return (NULL);
6905c51f124SMoriah Waterland }
6915c51f124SMoriah Waterland
6925c51f124SMoriah Waterland /* Evaluate the first entry in pkgmap */
6935c51f124SMoriah Waterland n = rd_map_size(fp, &nparts, &maxpsize, &compressedsize);
6945c51f124SMoriah Waterland
6955c51f124SMoriah Waterland if (n == 3) /* It's a compressed package */
6965c51f124SMoriah Waterland /* The header needs the *real* size */
6975c51f124SMoriah Waterland maxpsize = compressedsize;
6985c51f124SMoriah Waterland else if (n == 0) /* pkgmap is corrupt */
6995c51f124SMoriah Waterland return (NULL);
7005c51f124SMoriah Waterland
7015c51f124SMoriah Waterland if (dstdev.capacity && maxpsize > dstdev.capacity) {
7025c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
7034656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOSPACE), (long)maxpsize,
7044656d474SGarrett D'Amore dstdev.capacity);
7055c51f124SMoriah Waterland (void) fclose(fp);
7065c51f124SMoriah Waterland ecleanup();
7075c51f124SMoriah Waterland return (NULL);
7085c51f124SMoriah Waterland }
7095c51f124SMoriah Waterland
7105c51f124SMoriah Waterland /* add pkg name, number of parts and the max part size */
7115c51f124SMoriah Waterland if (snprintf(tmp_entry, ENTRY_MAX, "%s %d %d",
7125c51f124SMoriah Waterland pkg[i], nparts, maxpsize) >= ENTRY_MAX) {
7135c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
7145c51f124SMoriah Waterland logerr(pkg_gt(ERR_MEM));
7155c51f124SMoriah Waterland (void) fclose(fp);
7165c51f124SMoriah Waterland ecleanup();
7175c51f124SMoriah Waterland return (NULL);
7185c51f124SMoriah Waterland }
7195c51f124SMoriah Waterland if (cat_and_count(&hdrbuf, tmp_entry)) {
7205c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
7215c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
7225c51f124SMoriah Waterland (void) fclose(fp);
7235c51f124SMoriah Waterland ecleanup();
7245c51f124SMoriah Waterland return (NULL);
7255c51f124SMoriah Waterland }
7265c51f124SMoriah Waterland
7275c51f124SMoriah Waterland totsize += nparts * maxpsize;
7285c51f124SMoriah Waterland if (dstdev.capacity && dstdev.capacity < totsize) {
7295c51f124SMoriah Waterland int lastpartcnt = 0;
7305c51f124SMoriah Waterland
7315c51f124SMoriah Waterland if (totsize)
7325c51f124SMoriah Waterland totsize -= nparts * maxpsize;
7335c51f124SMoriah Waterland while (partcnt < nparts) {
7345c51f124SMoriah Waterland while (totsize <= dstdev.capacity &&
7355c51f124SMoriah Waterland partcnt <= nparts) {
7365c51f124SMoriah Waterland totsize += maxpsize;
7375c51f124SMoriah Waterland partcnt++;
7385c51f124SMoriah Waterland }
7395c51f124SMoriah Waterland /* partcnt == 0 means skip to next volume */
7405c51f124SMoriah Waterland if (partcnt)
7415c51f124SMoriah Waterland partcnt--;
7425c51f124SMoriah Waterland (void) snprintf(tmp_entry, ENTRY_MAX,
7435c51f124SMoriah Waterland " %d", partcnt - lastpartcnt);
7445c51f124SMoriah Waterland if (cat_and_count(&hdrbuf, tmp_entry)) {
7455c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
7465c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
7475c51f124SMoriah Waterland (void) fclose(fp);
7485c51f124SMoriah Waterland ecleanup();
7495c51f124SMoriah Waterland return (NULL);
7505c51f124SMoriah Waterland }
7515c51f124SMoriah Waterland ds_volcnt++;
7525c51f124SMoriah Waterland totsize = 0;
7535c51f124SMoriah Waterland lastpartcnt = partcnt;
7545c51f124SMoriah Waterland }
7555c51f124SMoriah Waterland /* first parts/volume number does not count */
7565c51f124SMoriah Waterland ds_volcnt--;
7575c51f124SMoriah Waterland }
7585c51f124SMoriah Waterland
7595c51f124SMoriah Waterland if (cat_and_count(&hdrbuf, "\n")) {
7605c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
7615c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
7625c51f124SMoriah Waterland (void) fclose(fp);
7635c51f124SMoriah Waterland ecleanup();
7645c51f124SMoriah Waterland return (NULL);
7655c51f124SMoriah Waterland }
7665c51f124SMoriah Waterland
7675c51f124SMoriah Waterland (void) fclose(fp);
7685c51f124SMoriah Waterland }
7695c51f124SMoriah Waterland
7705c51f124SMoriah Waterland if (cat_and_count(&hdrbuf, HDR_SUFFIX) ||
7715c51f124SMoriah Waterland cat_and_count(&hdrbuf, "\n")) {
7725c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
7735c51f124SMoriah Waterland logerr(pkg_gt(MSG_MEM));
7745c51f124SMoriah Waterland (void) fclose(fp);
7755c51f124SMoriah Waterland ecleanup();
7765c51f124SMoriah Waterland return (NULL);
7775c51f124SMoriah Waterland }
7785c51f124SMoriah Waterland return (&hdrbuf);
7795c51f124SMoriah Waterland }
7805c51f124SMoriah Waterland
7815c51f124SMoriah Waterland static int
wdsheader(struct dm_buf * hdr,char * device,char ** pkg)78232991bedSPeter Tribble wdsheader(struct dm_buf *hdr, char *device, char **pkg)
7835c51f124SMoriah Waterland {
78432991bedSPeter Tribble char tmp_entry[ENTRY_MAX], tmp_file[L_tmpnam+1];
7855c51f124SMoriah Waterland int i, n;
7865c51f124SMoriah Waterland int list_fd;
7875c51f124SMoriah Waterland int block_cnt;
7885c51f124SMoriah Waterland
7895c51f124SMoriah Waterland (void) ds_close(0);
7905c51f124SMoriah Waterland if (dstdev.pathname)
7915c51f124SMoriah Waterland ds_fd = creat(device, 0644);
7925c51f124SMoriah Waterland else
7935c51f124SMoriah Waterland ds_fd = open(device, 1);
7945c51f124SMoriah Waterland
7955c51f124SMoriah Waterland if (ds_fd < 0) {
7965c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
7975c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
7985c51f124SMoriah Waterland return (1);
7995c51f124SMoriah Waterland }
8005c51f124SMoriah Waterland
8015c51f124SMoriah Waterland if (ds_ginit(device) < 0) {
8025c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
8035c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), device, errno);
8045c51f124SMoriah Waterland (void) ds_close(0);
8055c51f124SMoriah Waterland return (1);
8065c51f124SMoriah Waterland }
8075c51f124SMoriah Waterland
8085c51f124SMoriah Waterland /*
8095c51f124SMoriah Waterland * The loop below assures compatibility with tapes that don't
8105c51f124SMoriah Waterland * have a block size (e.g.: Exabyte) by forcing EOR at the end
8115c51f124SMoriah Waterland * of each 512 bytes.
8125c51f124SMoriah Waterland */
8135c51f124SMoriah Waterland for (block_cnt = 0; block_cnt < hdr->allocation;
8145c51f124SMoriah Waterland block_cnt += BLK_SIZE) {
8154656d474SGarrett D'Amore (void) write(ds_fd, (hdr->text_buffer + block_cnt), BLK_SIZE);
8165c51f124SMoriah Waterland }
8175c51f124SMoriah Waterland
8185c51f124SMoriah Waterland /*
8195c51f124SMoriah Waterland * write the first cpio() archive to the datastream
8205c51f124SMoriah Waterland * which should contain the pkginfo & pkgmap files
8215c51f124SMoriah Waterland * for all packages
8225c51f124SMoriah Waterland */
8235c51f124SMoriah Waterland (void) tmpnam(tmp_file); /* temporary file name */
8244656d474SGarrett D'Amore if ((list_fd = open(tmp_file, O_RDWR | O_CREAT, 0644)) == -1) {
8255c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
8264656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
8275c51f124SMoriah Waterland return (1);
8285c51f124SMoriah Waterland }
8295c51f124SMoriah Waterland
8305c51f124SMoriah Waterland /*
8315c51f124SMoriah Waterland * Create a cpio-compatible list of the requisite files in
8325c51f124SMoriah Waterland * the temporary file.
8335c51f124SMoriah Waterland */
8345c51f124SMoriah Waterland for (i = 0; pkg[i]; i++) {
8355c51f124SMoriah Waterland register ssize_t entry_size;
8365c51f124SMoriah Waterland
8375c51f124SMoriah Waterland /*
8385c51f124SMoriah Waterland * Copy pkginfo and pkgmap filenames into the
8395c51f124SMoriah Waterland * temporary string allowing for the first line
8405c51f124SMoriah Waterland * as a special case.
8415c51f124SMoriah Waterland */
8425c51f124SMoriah Waterland entry_size = sprintf(tmp_entry,
8435c51f124SMoriah Waterland (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
8445c51f124SMoriah Waterland pkg[i], PKGINFO, pkg[i], PKGMAP);
8455c51f124SMoriah Waterland
8465c51f124SMoriah Waterland if (write(list_fd, tmp_entry,
8475c51f124SMoriah Waterland entry_size) != entry_size) {
8485c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
8494656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
8505c51f124SMoriah Waterland (void) close(list_fd);
8515c51f124SMoriah Waterland ecleanup();
8525c51f124SMoriah Waterland return (1);
8535c51f124SMoriah Waterland }
8545c51f124SMoriah Waterland }
8555c51f124SMoriah Waterland
8565c51f124SMoriah Waterland (void) lseek(list_fd, 0, SEEK_SET);
8575c51f124SMoriah Waterland
8584656d474SGarrett D'Amore (void) snprintf(tmp_entry, sizeof (tmp_entry),
8594656d474SGarrett D'Amore "%s -ocD -C %d", CPIOPROC, (int)BLK_SIZE);
8605c51f124SMoriah Waterland
8615c51f124SMoriah Waterland if (n = esystem(tmp_entry, list_fd, ds_fd)) {
8625c51f124SMoriah Waterland rpterr();
8635c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
8645c51f124SMoriah Waterland logerr(pkg_gt(MSG_CMDFAIL), tmp_entry, n);
8655c51f124SMoriah Waterland (void) close(list_fd);
8665c51f124SMoriah Waterland (void) unlink(tmp_file);
8675c51f124SMoriah Waterland cleanup();
8685c51f124SMoriah Waterland return (1);
8695c51f124SMoriah Waterland }
8705c51f124SMoriah Waterland
8715c51f124SMoriah Waterland (void) close(list_fd);
8725c51f124SMoriah Waterland (void) unlink(tmp_file);
8735c51f124SMoriah Waterland
8745c51f124SMoriah Waterland return (0);
8755c51f124SMoriah Waterland }
8765c51f124SMoriah Waterland
8775c51f124SMoriah Waterland static int
ckoverwrite(char * dir,char * inst,int options)8785c51f124SMoriah Waterland ckoverwrite(char *dir, char *inst, int options)
8795c51f124SMoriah Waterland {
8805c51f124SMoriah Waterland char path[PATH_MAX];
8815c51f124SMoriah Waterland
8824656d474SGarrett D'Amore (void) snprintf(path, sizeof (path), "%s/%s", dir, inst);
8835c51f124SMoriah Waterland if (access(path, 0) == 0) {
8845c51f124SMoriah Waterland if (options & PT_OVERWRITE)
8855c51f124SMoriah Waterland return (rrmdir(path));
8865c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
8875c51f124SMoriah Waterland logerr(pkg_gt(MSG_EXISTS), path);
8885c51f124SMoriah Waterland return (1);
8895c51f124SMoriah Waterland }
8905c51f124SMoriah Waterland return (0);
8915c51f124SMoriah Waterland }
8925c51f124SMoriah Waterland
8935c51f124SMoriah Waterland static int
pkgxfer(char * srcinst,int options)8945c51f124SMoriah Waterland pkgxfer(char *srcinst, int options)
8955c51f124SMoriah Waterland {
8965c51f124SMoriah Waterland int r;
8975c51f124SMoriah Waterland struct pkginfo info;
8985c51f124SMoriah Waterland FILE *fp, *pp;
8995c51f124SMoriah Waterland char *pt, *src, *dst;
900*3970c098SToomas Soome char dstdir[PATH_MAX], temp[PATH_MAX], srcdir[PATH_MAX];
901*3970c098SToomas Soome char cmd[CMDSIZE], pkgname[NON_ABI_NAMELNGTH];
9025c51f124SMoriah Waterland int i, n, part, nparts, maxpartsize, curpartcnt, iscomp;
9035c51f124SMoriah Waterland char volnos[128], tmpvol[128];
9045c51f124SMoriah Waterland struct statvfs64 svfsb;
9055c51f124SMoriah Waterland longlong_t free_blocks;
9065c51f124SMoriah Waterland struct stat srcstat;
9075c51f124SMoriah Waterland
9085c51f124SMoriah Waterland info.pkginst = NULL; /* required initialization */
9095c51f124SMoriah Waterland
9105c51f124SMoriah Waterland /*
9115c51f124SMoriah Waterland * when this routine is entered, the first part of
9125c51f124SMoriah Waterland * the package to transfer is already available in
9135c51f124SMoriah Waterland * the directory indicated by 'src' --- unless the
9145c51f124SMoriah Waterland * source device is a datstream, in which case only
9155c51f124SMoriah Waterland * the pkginfo and pkgmap files are available in 'src'
9165c51f124SMoriah Waterland */
9175c51f124SMoriah Waterland src = srcdev.dirname;
9185c51f124SMoriah Waterland dst = dstdev.dirname;
9195c51f124SMoriah Waterland
9205c51f124SMoriah Waterland if (!(options & PT_SILENT))
9215c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst);
9224656d474SGarrett D'Amore (void) strlcpy(dstinst, srcinst, sizeof (dstinst));
9235c51f124SMoriah Waterland
9245c51f124SMoriah Waterland if (!(options & PT_ODTSTREAM)) {
9255c51f124SMoriah Waterland /* destination is a (possibly mounted) directory */
9264656d474SGarrett D'Amore (void) snprintf(dstdir, sizeof (dstdir),
9274656d474SGarrett D'Amore "%s/%s", dst, dstinst);
9285c51f124SMoriah Waterland
9295c51f124SMoriah Waterland /*
9305c51f124SMoriah Waterland * need to check destination directory to assure
9315c51f124SMoriah Waterland * that we will not be duplicating a package which
9325c51f124SMoriah Waterland * already resides there (though we are allowed to
9335c51f124SMoriah Waterland * overwrite the same version)
9345c51f124SMoriah Waterland */
9355c51f124SMoriah Waterland pkgdir = src;
9365c51f124SMoriah Waterland if (fpkginfo(&info, srcinst)) {
9375c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
9385c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOEXISTS), srcinst);
9395c51f124SMoriah Waterland (void) fpkginfo(&info, NULL);
9405c51f124SMoriah Waterland return (1);
9415c51f124SMoriah Waterland }
9425c51f124SMoriah Waterland pkgdir = dst;
9435c51f124SMoriah Waterland
9444656d474SGarrett D'Amore (void) strlcpy(temp, srcinst, sizeof (temp));
9455c51f124SMoriah Waterland if (pt = strchr(temp, '.'))
9465c51f124SMoriah Waterland *pt = '\0';
9474656d474SGarrett D'Amore (void) strlcat(temp, ".*", sizeof (temp));
9485c51f124SMoriah Waterland
9495c51f124SMoriah Waterland if (pt = fpkginst(temp, info.arch, info.version)) {
9505c51f124SMoriah Waterland /*
9515c51f124SMoriah Waterland * the same instance already exists, although
9525c51f124SMoriah Waterland * its pkgid might be different
9535c51f124SMoriah Waterland */
9545c51f124SMoriah Waterland if (options & PT_OVERWRITE) {
9554656d474SGarrett D'Amore (void) strlcpy(dstinst, pt, sizeof (dstinst));
9564656d474SGarrett D'Amore (void) snprintf(dstdir, sizeof (dstdir),
9574656d474SGarrett D'Amore "%s/%s", dst, dstinst);
9585c51f124SMoriah Waterland } else {
9595c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
9605c51f124SMoriah Waterland logerr(pkg_gt(MSG_DUPVERS), srcinst);
9615c51f124SMoriah Waterland (void) fpkginfo(&info, NULL);
9625c51f124SMoriah Waterland (void) fpkginst(NULL);
9635c51f124SMoriah Waterland return (2);
9645c51f124SMoriah Waterland }
9655c51f124SMoriah Waterland } else if (options & PT_RENAME) {
9665c51f124SMoriah Waterland /*
9675c51f124SMoriah Waterland * find next available instance by appending numbers
9685c51f124SMoriah Waterland * to the package abbreviation until the instance
9695c51f124SMoriah Waterland * does not exist in the destination directory
9705c51f124SMoriah Waterland */
9715c51f124SMoriah Waterland if (pt = strchr(temp, '.'))
9725c51f124SMoriah Waterland *pt = '\0';
9735c51f124SMoriah Waterland for (i = 2; (access(dstdir, 0) == 0); i++) {
9744656d474SGarrett D'Amore (void) snprintf(dstinst, sizeof (dstinst),
9754656d474SGarrett D'Amore "%s.%d", temp, i);
9764656d474SGarrett D'Amore (void) snprintf(dstdir, sizeof (dstdir),
9774656d474SGarrett D'Amore "%s/%s", dst, dstinst);
9785c51f124SMoriah Waterland }
9795c51f124SMoriah Waterland } else if (options & PT_OVERWRITE) {
9805c51f124SMoriah Waterland /*
9815c51f124SMoriah Waterland * we're allowed to overwrite, but there seems
9825c51f124SMoriah Waterland * to be no valid package to overwrite, and we are
9835c51f124SMoriah Waterland * not allowed to rename the destination, so act
9845c51f124SMoriah Waterland * as if we weren't given permission to overwrite
9855c51f124SMoriah Waterland * --- this keeps us from removing a destination
9865c51f124SMoriah Waterland * instance which is named the same as the source
9875c51f124SMoriah Waterland * instance, but really reflects a different pkg!
9885c51f124SMoriah Waterland */
9895c51f124SMoriah Waterland options &= (~PT_OVERWRITE);
9905c51f124SMoriah Waterland }
9915c51f124SMoriah Waterland (void) fpkginfo(&info, NULL);
9925c51f124SMoriah Waterland (void) fpkginst(NULL);
9935c51f124SMoriah Waterland
9945c51f124SMoriah Waterland if (ckoverwrite(dst, dstinst, options))
9955c51f124SMoriah Waterland return (2);
9965c51f124SMoriah Waterland
9975c51f124SMoriah Waterland if (isdir(dstdir) && mkdir(dstdir, 0755)) {
9985c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
9995c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), dstdir);
10005c51f124SMoriah Waterland return (1);
10015c51f124SMoriah Waterland }
10025c51f124SMoriah Waterland
10034656d474SGarrett D'Amore (void) snprintf(srcdir, sizeof (srcdir),
10044656d474SGarrett D'Amore "%s/%s", src, srcinst);
10055c51f124SMoriah Waterland if (stat(srcdir, &srcstat) != -1) {
10065c51f124SMoriah Waterland if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) {
10075c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
10085c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHMODDIR), dstdir);
10095c51f124SMoriah Waterland return (1);
10105c51f124SMoriah Waterland }
10115c51f124SMoriah Waterland } else {
10125c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
10135c51f124SMoriah Waterland logerr(pkg_gt(MSG_STATDIR), srcdir);
10145c51f124SMoriah Waterland return (1);
10155c51f124SMoriah Waterland }
10165c51f124SMoriah Waterland }
10175c51f124SMoriah Waterland
10185c51f124SMoriah Waterland if (!(options & PT_SILENT) && strcmp(dstinst, srcinst))
10195c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst);
10205c51f124SMoriah Waterland
10214656d474SGarrett D'Amore (void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst);
10225c51f124SMoriah Waterland if (chdir(srcdir)) {
10235c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
10245c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), srcdir);
10255c51f124SMoriah Waterland return (1);
10265c51f124SMoriah Waterland }
10275c51f124SMoriah Waterland
10285c51f124SMoriah Waterland if (ids_name) { /* unpack the datatstream into a directory */
10295c51f124SMoriah Waterland /*
10305c51f124SMoriah Waterland * transfer pkginfo & pkgmap first
10315c51f124SMoriah Waterland */
10324656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd),
10334656d474SGarrett D'Amore "%s -pudm %s", CPIOPROC, dstdir);
10345c51f124SMoriah Waterland if ((pp = epopen(cmd, "w")) == NULL) {
10355c51f124SMoriah Waterland rpterr();
10365c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
10375c51f124SMoriah Waterland logerr(pkg_gt(MSG_POPEN), cmd, errno);
10385c51f124SMoriah Waterland return (1);
10395c51f124SMoriah Waterland }
10405c51f124SMoriah Waterland (void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP);
10415c51f124SMoriah Waterland
10424656d474SGarrett D'Amore (void) sighold(SIGINT);
10434656d474SGarrett D'Amore (void) sighold(SIGHUP);
10445c51f124SMoriah Waterland r = epclose(pp);
10454656d474SGarrett D'Amore (void) sigrelse(SIGINT);
10464656d474SGarrett D'Amore (void) sigrelse(SIGHUP);
10475c51f124SMoriah Waterland
10485c51f124SMoriah Waterland if (r != 0) {
10495c51f124SMoriah Waterland rpterr();
10505c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
10515c51f124SMoriah Waterland logerr(pkg_gt(MSG_PCLOSE), cmd, errno);
10525c51f124SMoriah Waterland return (1);
10535c51f124SMoriah Waterland }
10545c51f124SMoriah Waterland
10555c51f124SMoriah Waterland if (options & PT_INFO_ONLY)
10565c51f124SMoriah Waterland return (0); /* don't transfer objects */
10575c51f124SMoriah Waterland
10585c51f124SMoriah Waterland if (chdir(dstdir)) {
10595c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
10605c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR), dstdir);
10615c51f124SMoriah Waterland return (1);
10625c51f124SMoriah Waterland }
10635c51f124SMoriah Waterland
10645c51f124SMoriah Waterland /*
10655c51f124SMoriah Waterland * for each part of the package, use cpio() to
10665c51f124SMoriah Waterland * unpack the archive into the destination directory
10675c51f124SMoriah Waterland */
10685c51f124SMoriah Waterland nparts = ds_findpkg(srcdev.cdevice, srcinst);
10695c51f124SMoriah Waterland if (nparts < 0) {
10705c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
10715c51f124SMoriah Waterland return (1);
10725c51f124SMoriah Waterland }
10735c51f124SMoriah Waterland for (part = 1; part <= nparts; /* void */) {
10745c51f124SMoriah Waterland if (ds_getpkg(srcdev.cdevice, part, dstdir)) {
10755c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
10765c51f124SMoriah Waterland return (1);
10775c51f124SMoriah Waterland }
10785c51f124SMoriah Waterland part++;
10795c51f124SMoriah Waterland if (dstdev.mount) {
10805c51f124SMoriah Waterland (void) chdir("/");
10815c51f124SMoriah Waterland if (pkgumount(&dstdev))
10825c51f124SMoriah Waterland return (1);
10835c51f124SMoriah Waterland if (part <= nparts) {
10845c51f124SMoriah Waterland if (n = pkgmount(&dstdev, NULL, part+1,
10855c51f124SMoriah Waterland nparts, 1))
10865c51f124SMoriah Waterland return (n);
10875c51f124SMoriah Waterland if (ckoverwrite(dst, dstinst, options))
10885c51f124SMoriah Waterland return (1);
10895c51f124SMoriah Waterland if (isdir(dstdir) &&
10905c51f124SMoriah Waterland mkdir(dstdir, 0755)) {
10915c51f124SMoriah Waterland progerr(
10925c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER));
10935c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR),
10945c51f124SMoriah Waterland dstdir);
10955c51f124SMoriah Waterland return (1);
10965c51f124SMoriah Waterland }
10975c51f124SMoriah Waterland /*
10985c51f124SMoriah Waterland * since volume is removable, each part
10995c51f124SMoriah Waterland * must contain a duplicate of the
11005c51f124SMoriah Waterland * pkginfo file to properly identify the
11015c51f124SMoriah Waterland * volume
11025c51f124SMoriah Waterland */
11035c51f124SMoriah Waterland if (chdir(srcdir)) {
11045c51f124SMoriah Waterland progerr(
11055c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER));
11065c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR),
11075c51f124SMoriah Waterland srcdir);
11085c51f124SMoriah Waterland return (1);
11095c51f124SMoriah Waterland }
11105c51f124SMoriah Waterland if ((pp = epopen(cmd, "w")) == NULL) {
11115c51f124SMoriah Waterland rpterr();
11125c51f124SMoriah Waterland progerr(
11135c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER));
11145c51f124SMoriah Waterland logerr(pkg_gt(MSG_POPEN),
11155c51f124SMoriah Waterland cmd, errno);
11165c51f124SMoriah Waterland return (1);
11175c51f124SMoriah Waterland }
11185c51f124SMoriah Waterland (void) fprintf(pp, "pkginfo");
11195c51f124SMoriah Waterland
11204656d474SGarrett D'Amore (void) sighold(SIGINT);
11214656d474SGarrett D'Amore (void) sighold(SIGHUP);
11225c51f124SMoriah Waterland r = epclose(pp);
11234656d474SGarrett D'Amore (void) sigrelse(SIGINT);
11244656d474SGarrett D'Amore (void) sigrelse(SIGHUP);
11255c51f124SMoriah Waterland
11265c51f124SMoriah Waterland if (r != 0) {
11275c51f124SMoriah Waterland rpterr();
11285c51f124SMoriah Waterland progerr(
11295c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER));
11305c51f124SMoriah Waterland logerr(pkg_gt(MSG_PCLOSE),
11315c51f124SMoriah Waterland cmd, errno);
11325c51f124SMoriah Waterland return (1);
11335c51f124SMoriah Waterland }
11345c51f124SMoriah Waterland if (chdir(dstdir)) {
11355c51f124SMoriah Waterland progerr(
11365c51f124SMoriah Waterland pkg_gt(ERR_TRANSFER));
11375c51f124SMoriah Waterland logerr(pkg_gt(MSG_CHDIR),
11385c51f124SMoriah Waterland dstdir);
11395c51f124SMoriah Waterland return (1);
11405c51f124SMoriah Waterland }
11415c51f124SMoriah Waterland }
11425c51f124SMoriah Waterland }
11435c51f124SMoriah Waterland }
11445c51f124SMoriah Waterland return (0);
11455c51f124SMoriah Waterland }
11465c51f124SMoriah Waterland
11475c51f124SMoriah Waterland if ((fp = fopen(PKGMAP, "r")) == NULL) {
11485c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
11495c51f124SMoriah Waterland logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
11505c51f124SMoriah Waterland return (1);
11515c51f124SMoriah Waterland }
11525c51f124SMoriah Waterland
11535c51f124SMoriah Waterland nparts = 1;
11545c51f124SMoriah Waterland if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
11555c51f124SMoriah Waterland return (1);
11565c51f124SMoriah Waterland else
11575c51f124SMoriah Waterland (void) fclose(fp);
11585c51f124SMoriah Waterland
11595c51f124SMoriah Waterland if (srcdev.mount) {
11605c51f124SMoriah Waterland if (ckvolseq(srcdir, 1, nparts)) {
11615c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
11625c51f124SMoriah Waterland logerr(pkg_gt(MSG_SEQUENCE));
11635c51f124SMoriah Waterland return (1);
11645c51f124SMoriah Waterland }
11655c51f124SMoriah Waterland }
11665c51f124SMoriah Waterland
11675c51f124SMoriah Waterland /* write each part of this package */
11685c51f124SMoriah Waterland if (options & PT_ODTSTREAM) {
11695c51f124SMoriah Waterland char line[128];
11705c51f124SMoriah Waterland (void) mgets(line, 128);
11715c51f124SMoriah Waterland curpartcnt = -1;
11724656d474SGarrett D'Amore /* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
11734656d474SGarrett D'Amore if (sscanf(line, "%s %d %d %[ 0-9]", pkgname, &nparts,
11745c51f124SMoriah Waterland &maxpartsize, volnos) == 4) {
11754656d474SGarrett D'Amore (void) sscanf(volnos,
11764656d474SGarrett D'Amore "%d %[ 0-9]", &curpartcnt, tmpvol);
11774656d474SGarrett D'Amore (void) strlcpy(volnos, tmpvol, sizeof (volnos));
11785c51f124SMoriah Waterland }
11795c51f124SMoriah Waterland }
11805c51f124SMoriah Waterland
11815c51f124SMoriah Waterland for (part = 1; part <= nparts; /* void */) {
11825c51f124SMoriah Waterland if (curpartcnt == 0 && (options & PT_ODTSTREAM)) {
11835c51f124SMoriah Waterland char prompt[128];
11845c51f124SMoriah Waterland int index;
11855c51f124SMoriah Waterland ds_volno++;
11865c51f124SMoriah Waterland (void) ds_close(0);
11875c51f124SMoriah Waterland (void) sprintf(prompt,
11885c51f124SMoriah Waterland pkg_gt("Insert %%v %d of %d into %%p"),
11895c51f124SMoriah Waterland ds_volno, ds_volcnt);
11905c51f124SMoriah Waterland if (n = getvol(ods_name, NULL, DM_FORMAT, prompt))
11915c51f124SMoriah Waterland return (n);
11925c51f124SMoriah Waterland if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) {
11935c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
11945c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
11955c51f124SMoriah Waterland errno);
11965c51f124SMoriah Waterland return (1);
11975c51f124SMoriah Waterland }
11985c51f124SMoriah Waterland if (ds_ginit(dstdev.cdevice) < 0) {
11995c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
12005c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
12015c51f124SMoriah Waterland errno);
12025c51f124SMoriah Waterland (void) ds_close(0);
12035c51f124SMoriah Waterland return (1);
12045c51f124SMoriah Waterland }
12055c51f124SMoriah Waterland
12065c51f124SMoriah Waterland (void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol);
12074656d474SGarrett D'Amore (void) strlcpy(volnos, tmpvol, sizeof (volnos));
12085c51f124SMoriah Waterland curpartcnt += index;
12095c51f124SMoriah Waterland }
12105c51f124SMoriah Waterland
12115c51f124SMoriah Waterland if (options & PT_INFO_ONLY)
12125c51f124SMoriah Waterland nparts = 0;
12135c51f124SMoriah Waterland
12145c51f124SMoriah Waterland if (part == 1) {
12154656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd),
12164656d474SGarrett D'Amore "find %s %s", PKGINFO, PKGMAP);
12175c51f124SMoriah Waterland if (nparts && (isdir(INSTALL) == 0)) {
12184656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd));
12194656d474SGarrett D'Amore (void) strlcat(cmd, INSTALL, sizeof (cmd));
12205c51f124SMoriah Waterland }
12215c51f124SMoriah Waterland } else
12224656d474SGarrett D'Amore (void) snprintf(cmd, sizeof (cmd), "find %s", PKGINFO);
12235c51f124SMoriah Waterland
12245c51f124SMoriah Waterland if (nparts > 1) {
12254656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp),
12264656d474SGarrett D'Amore "%s.%d", RELOC, part);
12275c51f124SMoriah Waterland if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
12284656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd));
12294656d474SGarrett D'Amore (void) strlcat(cmd, temp, sizeof (cmd));
12305c51f124SMoriah Waterland }
12314656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp),
12324656d474SGarrett D'Amore "%s.%d", ROOT, part);
12335c51f124SMoriah Waterland if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
12344656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd));
12354656d474SGarrett D'Amore (void) strlcat(cmd, temp, sizeof (cmd));
12365c51f124SMoriah Waterland }
12374656d474SGarrett D'Amore (void) snprintf(temp, sizeof (temp),
12384656d474SGarrett D'Amore "%s.%d", ARCHIVE, part);
12395c51f124SMoriah Waterland if (isdir(temp) == 0) {
12404656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd));
12414656d474SGarrett D'Amore (void) strlcat(cmd, temp, sizeof (cmd));
12425c51f124SMoriah Waterland }
12435c51f124SMoriah Waterland } else if (nparts) {
12445c51f124SMoriah Waterland for (i = 0; reloc_names[i] != NULL; i++) {
12455c51f124SMoriah Waterland if (iscpio(reloc_names[i], &iscomp) ||
12465c51f124SMoriah Waterland isdir(reloc_names[i]) == 0) {
12474656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd));
12484656d474SGarrett D'Amore (void) strlcat(cmd, reloc_names[i],
12494656d474SGarrett D'Amore sizeof (cmd));
12505c51f124SMoriah Waterland }
12515c51f124SMoriah Waterland }
12525c51f124SMoriah Waterland for (i = 0; root_names[i] != NULL; i++) {
12535c51f124SMoriah Waterland if (iscpio(root_names[i], &iscomp) ||
12545c51f124SMoriah Waterland isdir(root_names[i]) == 0) {
12554656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd));
12564656d474SGarrett D'Amore (void) strlcat(cmd, root_names[i],
12574656d474SGarrett D'Amore sizeof (cmd));
12585c51f124SMoriah Waterland }
12595c51f124SMoriah Waterland }
12605c51f124SMoriah Waterland if (isdir(ARCHIVE) == 0) {
12614656d474SGarrett D'Amore (void) strlcat(cmd, " ", sizeof (cmd));
12624656d474SGarrett D'Amore (void) strlcat(cmd, ARCHIVE, sizeof (cmd));
12635c51f124SMoriah Waterland }
12645c51f124SMoriah Waterland }
12655c51f124SMoriah Waterland if (options & PT_ODTSTREAM) {
12664656d474SGarrett D'Amore (void) snprintf(cmd + strlen(cmd),
12674656d474SGarrett D'Amore sizeof (cmd) - strlen(cmd),
12685c51f124SMoriah Waterland " -print | %s -ocD -C %d",
12695c51f124SMoriah Waterland CPIOPROC, (int)BLK_SIZE);
12705c51f124SMoriah Waterland } else {
12715c51f124SMoriah Waterland if (statvfs64(dstdir, &svfsb) == -1) {
12725c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
12735c51f124SMoriah Waterland logerr(pkg_gt(MSG_STATVFS), dstdir, errno);
12745c51f124SMoriah Waterland return (1);
12755c51f124SMoriah Waterland }
12765c51f124SMoriah Waterland
12775c51f124SMoriah Waterland free_blocks = (((long)svfsb.f_frsize > 0) ?
12785c51f124SMoriah Waterland howmany(svfsb.f_frsize, DEV_BSIZE) :
12795c51f124SMoriah Waterland howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail;
12805c51f124SMoriah Waterland
12815c51f124SMoriah Waterland if ((has_comp_size ? compressedsize : maxpartsize) >
12825c51f124SMoriah Waterland free_blocks) {
12835c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
12844656d474SGarrett D'Amore logerr(pkg_gt(MSG_NOSPACE),
12854656d474SGarrett D'Amore has_comp_size ?
12864656d474SGarrett D'Amore (long)compressedsize : (long)maxpartsize,
12874656d474SGarrett D'Amore free_blocks);
12885c51f124SMoriah Waterland return (1);
12895c51f124SMoriah Waterland }
12904656d474SGarrett D'Amore (void) snprintf(cmd + strlen(cmd),
12914656d474SGarrett D'Amore sizeof (cmd) - strlen(cmd),
12924656d474SGarrett D'Amore " -print | %s -pdum %s",
12935c51f124SMoriah Waterland CPIOPROC, dstdir);
12945c51f124SMoriah Waterland }
12955c51f124SMoriah Waterland
12965c51f124SMoriah Waterland n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1);
12975c51f124SMoriah Waterland if (n) {
12985c51f124SMoriah Waterland rpterr();
12995c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
13005c51f124SMoriah Waterland logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
13015c51f124SMoriah Waterland return (1);
13025c51f124SMoriah Waterland }
13035c51f124SMoriah Waterland
13045c51f124SMoriah Waterland part++;
13055c51f124SMoriah Waterland if (srcdev.mount && (nparts > 1)) {
13065c51f124SMoriah Waterland /* unmount current source volume */
13075c51f124SMoriah Waterland (void) chdir("/");
13085c51f124SMoriah Waterland if (pkgumount(&srcdev))
13095c51f124SMoriah Waterland return (1);
13105c51f124SMoriah Waterland /* loop until volume is mounted successfully */
13115c51f124SMoriah Waterland while (part <= nparts) {
13125c51f124SMoriah Waterland /* read only */
13135c51f124SMoriah Waterland n = pkgmount(&srcdev, NULL, part, nparts, 1);
13145c51f124SMoriah Waterland if (n)
13155c51f124SMoriah Waterland return (n);
13165c51f124SMoriah Waterland if (chdir(srcdir)) {
13175c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
13184656d474SGarrett D'Amore logerr(pkg_gt(MSG_CORRUPT));
13195c51f124SMoriah Waterland (void) chdir("/");
13204656d474SGarrett D'Amore (void) pkgumount(&srcdev);
13215c51f124SMoriah Waterland continue;
13225c51f124SMoriah Waterland }
13235c51f124SMoriah Waterland if (ckvolseq(srcdir, part, nparts)) {
13245c51f124SMoriah Waterland (void) chdir("/");
13254656d474SGarrett D'Amore (void) pkgumount(&srcdev);
13265c51f124SMoriah Waterland continue;
13275c51f124SMoriah Waterland }
13285c51f124SMoriah Waterland break;
13295c51f124SMoriah Waterland }
13305c51f124SMoriah Waterland }
13315c51f124SMoriah Waterland if (!(options & PT_ODTSTREAM) && dstdev.mount) {
13325c51f124SMoriah Waterland /* unmount current volume */
13335c51f124SMoriah Waterland if (pkgumount(&dstdev))
13345c51f124SMoriah Waterland return (1);
13355c51f124SMoriah Waterland /* loop until next volume is mounted successfully */
13365c51f124SMoriah Waterland while (part <= nparts) {
13375c51f124SMoriah Waterland /* writable */
13385c51f124SMoriah Waterland n = pkgmount(&dstdev, NULL, part, nparts, 1);
13395c51f124SMoriah Waterland if (n)
13405c51f124SMoriah Waterland return (n);
13415c51f124SMoriah Waterland if (ckoverwrite(dst, dstinst, options))
13425c51f124SMoriah Waterland continue;
13435c51f124SMoriah Waterland if (isdir(dstdir) && mkdir(dstdir, 0755)) {
13445c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
13455c51f124SMoriah Waterland logerr(pkg_gt(MSG_MKDIR), dstdir);
13465c51f124SMoriah Waterland continue;
13475c51f124SMoriah Waterland }
13485c51f124SMoriah Waterland break;
13495c51f124SMoriah Waterland }
13505c51f124SMoriah Waterland }
13515c51f124SMoriah Waterland
13525c51f124SMoriah Waterland if ((options & PT_ODTSTREAM) && part <= nparts) {
13535c51f124SMoriah Waterland if (curpartcnt >= 0 && part > curpartcnt) {
13545c51f124SMoriah Waterland char prompt[128];
13555c51f124SMoriah Waterland int index;
13565c51f124SMoriah Waterland ds_volno++;
13575c51f124SMoriah Waterland if (ds_close(0))
13585c51f124SMoriah Waterland return (1);
13595c51f124SMoriah Waterland (void) sprintf(prompt,
13605c51f124SMoriah Waterland pkg_gt("Insert %%v %d of %d into %%p"),
13615c51f124SMoriah Waterland ds_volno, ds_volcnt);
13625c51f124SMoriah Waterland if (n = getvol(ods_name, NULL, DM_FORMAT,
13635c51f124SMoriah Waterland prompt))
13645c51f124SMoriah Waterland return (n);
13655c51f124SMoriah Waterland if ((ds_fd = open(dstdev.cdevice, 1)) < 0) {
13665c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
13675c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN),
13685c51f124SMoriah Waterland dstdev.cdevice, errno);
13695c51f124SMoriah Waterland return (1);
13705c51f124SMoriah Waterland }
13715c51f124SMoriah Waterland if (ds_ginit(dstdev.cdevice) < 0) {
13725c51f124SMoriah Waterland progerr(pkg_gt(ERR_TRANSFER));
13735c51f124SMoriah Waterland logerr(pkg_gt(MSG_OPEN),
13745c51f124SMoriah Waterland dstdev.cdevice, errno);
13755c51f124SMoriah Waterland (void) ds_close(0);
13765c51f124SMoriah Waterland return (1);
13775c51f124SMoriah Waterland }
13785c51f124SMoriah Waterland
13795c51f124SMoriah Waterland (void) sscanf(volnos, "%d %[ 0-9]", &index,
13805c51f124SMoriah Waterland tmpvol);
13814656d474SGarrett D'Amore (void) strlcpy(volnos, tmpvol, sizeof (volnos));
13825c51f124SMoriah Waterland curpartcnt += index;
13835c51f124SMoriah Waterland }
13845c51f124SMoriah Waterland }
13855c51f124SMoriah Waterland
13865c51f124SMoriah Waterland }
13875c51f124SMoriah Waterland return (0);
13885c51f124SMoriah Waterland }
13895c51f124SMoriah Waterland
13905c51f124SMoriah Waterland static void
sigtrap(int signo)13915c51f124SMoriah Waterland sigtrap(int signo)
13925c51f124SMoriah Waterland {
13934656d474SGarrett D'Amore _NOTE(ARGUNUSED(signo));
13945c51f124SMoriah Waterland signal_received++;
13955c51f124SMoriah Waterland }
13965c51f124SMoriah Waterland
13975c51f124SMoriah Waterland static void
cleanup(void)13985c51f124SMoriah Waterland cleanup(void)
13995c51f124SMoriah Waterland {
14004656d474SGarrett D'Amore (void) chdir("/");
14015c51f124SMoriah Waterland if (tmpdir) {
14024656d474SGarrett D'Amore (void) rrmdir(tmpdir);
14035c51f124SMoriah Waterland free(tmpdir);
14045c51f124SMoriah Waterland tmpdir = NULL;
14055c51f124SMoriah Waterland }
14065c51f124SMoriah Waterland
14075c51f124SMoriah Waterland if (tmppath) {
14085c51f124SMoriah Waterland /* remove any previous tmppath stuff */
14094656d474SGarrett D'Amore (void) rrmdir(tmppath);
14105c51f124SMoriah Waterland free(tmppath);
14115c51f124SMoriah Waterland tmppath = NULL;
14125c51f124SMoriah Waterland }
14135c51f124SMoriah Waterland
14145c51f124SMoriah Waterland if (tmpsymdir) {
14155c51f124SMoriah Waterland /* remove temp symbolic links made for signed pkg */
14164656d474SGarrett D'Amore (void) rrmdir(tmpsymdir);
14175c51f124SMoriah Waterland free(tmpsymdir);
14185c51f124SMoriah Waterland tmpsymdir = NULL;
14195c51f124SMoriah Waterland }
14205c51f124SMoriah Waterland
14215c51f124SMoriah Waterland if (srcdev.mount && !ids_name)
14224656d474SGarrett D'Amore (void) pkgumount(&srcdev);
14235c51f124SMoriah Waterland if (dstdev.mount && !ods_name)
14244656d474SGarrett D'Amore (void) pkgumount(&dstdev);
14255c51f124SMoriah Waterland (void) ds_close(1);
14265c51f124SMoriah Waterland }
1427