Exemplo n.º 1
0
/*
 * Name:		BIO_dump_cmd
 * Description:	Dump the output of invoking a command
 *		to a BIO.
 *
 * Arguments:	cmd - Command to invoke
 *		bio - BIO to dump output of command to
 *		only 'stdout' is dumped.
 * Returns :   	0 - success
 *		nonzero - failure.  errors printed to screen.
 */
int
BIO_dump_cmd(char *cmd, BIO *bio)
{
	char	buf[BLK_SIZE];
	FILE	*fp;
	int	rc;

	/* start up the process */
	if ((fp = epopen(cmd, "r")) == NULL) {
		rpterr();
		return (1);
	}

	/* read output in chunks, transfer to BIO */
	while (fread(buf, BLK_SIZE, 1, fp) == 1) {
		if (BIO_write(bio, buf, BLK_SIZE) != BLK_SIZE) {
			(void) sighold(SIGINT);
			(void) sighold(SIGHUP);
			(void) epclose(fp);
			(void) sigrelse(SIGINT);
			(void) sigrelse(SIGHUP);
			rpterr();
			return (1);
		}
	}

	/* done with stream, make sure no errors were encountered */
	if (ferror(fp)) {
		(void) epclose(fp);
		rpterr();
		return (1);
	}

	/* done, close stream, report any errors */
	(void) sighold(SIGINT);
	(void) sighold(SIGHUP);
	rc = epclose(fp);
	(void) sigrelse(SIGINT);
	(void) sigrelse(SIGHUP);
	if (rc != 0) {
		rpterr();
		return (1);
	}

	return (rc);
}
Exemplo n.º 2
0
/* ---------- Creates: -------------------------------------------------
   TKWORDNUMBER
   /   \
   fval    Nil
   ---------------------------------------------------------------------- */
PslExpr psl_expr_make_word_number(char* fval)
{
  char* error;
  WordNumber_ptr number = WordNumber_from_parsed_string(fval, &error);
  PslExpr res;
  int sign;

  if (WORD_NUMBER(NULL) == number) {
    rpterr("%s", error);
  }

  res.klass = SC_WORD_EXPR;

  sign = ('s' == fval[1] ? TKSIGNEDWORDNUMBER : TKUNSIGNEDWORDNUMBER);

  res.psl_node = psl_new_node(TOK2SYM(sign),
                              (PslNode_ptr) number, PSL_NULL);
  return res;
}
Exemplo n.º 3
0
static int
wdsheader(struct dm_buf *hdr, char *src, char *device, char **pkg, PKCS7 *sig)
{
	FILE	*fp;
	char	path[PATH_MAX], tmp_entry[ENTRY_MAX],
	    tmp_file[L_tmpnam+1];
	char	srcpath[PATH_MAX];
	int	i, n;
	int	list_fd;
	int	block_cnt;
	int 	len;
	char	cwd[MAXPATHLEN + 1];
	boolean_t	making_sig = B_FALSE;

	making_sig = (sig != NULL) ? B_TRUE : B_FALSE;

	(void) ds_close(0);
	if (dstdev.pathname)
		ds_fd = creat(device, 0644);
	else
		ds_fd = open(device, 1);

	if (ds_fd < 0) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_OPEN), device, errno);
		return (1);
	}

	if (ds_ginit(device) < 0) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_OPEN), device, errno);
		(void) ds_close(0);
		return (1);
	}

	/*
	 * The loop below assures compatibility with tapes that don't
	 * have a block size (e.g.: Exabyte) by forcing EOR at the end
	 * of each 512 bytes.
	 */
	for (block_cnt = 0; block_cnt < hdr->allocation;
		block_cnt += BLK_SIZE) {
		(void) write(ds_fd, (hdr->text_buffer + block_cnt), BLK_SIZE);
	}

	/*
	 * write the first cpio() archive to the datastream
	 * which should contain the pkginfo & pkgmap files
	 * for all packages
	 */
	(void) tmpnam(tmp_file);	/* temporary file name */
	if ((list_fd = open(tmp_file, O_RDWR | O_CREAT, 0644)) == -1) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
		return (1);
	}

	/*
	 * Create a cpio-compatible list of the requisite files in
	 * the temporary file.
	 */
	if (!making_sig) {
		for (i = 0; pkg[i]; i++) {
			register ssize_t entry_size;

			/*
			 * Copy pkginfo and pkgmap filenames into the
			 * temporary string allowing for the first line
			 * as a special case.
			 */
			entry_size = sprintf(tmp_entry,
			    (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
			    pkg[i], PKGINFO, pkg[i], PKGMAP);

			if (write(list_fd, tmp_entry,
			    entry_size) != entry_size) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
				(void) close(list_fd);
				ecleanup();
				return (1);
			}
		}

	} else {
		register ssize_t entry_size;

		/*
		 * if we're making a signature, we must make a
		 * temporary area full of symlinks to the requisite
		 * files, plus an extra entry for the signature, so
		 * that cpio will put all files and signature in the
		 * same archive in a single invocation of cpio.
		 */
		tmpsymdir = xstrdup(tmpnam(NULL));

		if (mkdir(tmpsymdir,  S_IRWXU)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_MKDIR), tmpsymdir);
			return (1);
		}

		/* generate the signature */
		if (((len = snprintf(path, PATH_MAX, "%s/%s",
		    tmpsymdir, SIGNATURE_FILENAME)) >= PATH_MAX) ||
		    len < 0) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_NOTMPFIL), tmpsymdir);
			cleanup();
			return (1);
		}

		if ((fp = fopen(path, "w")) == NULL) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_NOTMPFIL), path);
			cleanup();
			return (1);
		}
		(void) PEM_write_PKCS7(fp, sig);
		(void) fclose(fp);

		for (i = 0; pkg[i]; i++) {
			(void) snprintf(path, sizeof (path),
			    "%s/%s", tmpsymdir, pkg[i]);
			if (mkdir(path, 0755)) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_MKDIR), path);
				cleanup();
				return (1);
			}
			(void) snprintf(path, sizeof (path),
			    "%s/%s/%s", tmpsymdir, pkg[i], PKGINFO);
			(void) snprintf(srcpath, sizeof (srcpath),
			    "%s/%s/%s", src, pkg[i], PKGINFO);
			if (symlink(srcpath, path) != 0) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_SYMLINK), path, srcpath);
				cleanup();
				return (1);
			}

			(void) snprintf(path, sizeof (path),
			    "%s/%s/%s", tmpsymdir, pkg[i], PKGMAP);
			(void) snprintf(srcpath, sizeof (srcpath),
			    "%s/%s/%s", src, pkg[i], PKGMAP);
			if (symlink(srcpath, path) != 0) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_SYMLINK), path, srcpath);
				cleanup();
				return (1);
			}

			/*
			 * Copy pkginfo and pkgmap filenames into the
			 * temporary string allowing for the first line
			 * as a special case.
			 */
			entry_size = snprintf(tmp_entry, sizeof (tmp_entry),
			    (i == 0) ? "%s/%s\n%s/%s" : "\n%s/%s\n%s/%s",
			    pkg[i], PKGINFO, pkg[i], PKGMAP);

			if (write(list_fd, tmp_entry,
			    entry_size) != entry_size) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
				(void) close(list_fd);
				ecleanup();
				cleanup();
				return (1);
			}
		}

		/* add signature to list of files */
		entry_size = snprintf(tmp_entry, sizeof (tmp_entry), "\n%s",
		    SIGNATURE_FILENAME);
		if (write(list_fd, tmp_entry, entry_size) != entry_size) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_NOTMPFIL), tmp_file);
			(void) close(list_fd);
			ecleanup();
			cleanup();
			return (1);
		}
	}

	(void) lseek(list_fd, 0, SEEK_SET);

	if (!making_sig) {
		(void) snprintf(tmp_entry, sizeof (tmp_entry),
		    "%s -ocD -C %d", CPIOPROC, (int)BLK_SIZE);
	} else {
		/*
		 * when making a signature, we must make sure to follow
		 * symlinks during the cpio so that we don't archive
		 * the links themselves
		 */
		(void) snprintf(tmp_entry, sizeof (tmp_entry),
		    "%s -ocDL -C %d", CPIOPROC, (int)BLK_SIZE);
	}

	if (making_sig) {
		/* save cwd and change to symlink dir for cpio invocation */
		if (getcwd(cwd, MAXPATHLEN + 1) == NULL) {
			logerr(pkg_gt(ERR_GETWD));
			progerr(pkg_gt(ERR_TRANSFER));
			cleanup();
			return (1);
		}

		if (chdir(tmpsymdir)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CHDIR), tmpsymdir);
			cleanup();
			return (1);
		}
	}

	if (n = esystem(tmp_entry, list_fd, ds_fd)) {
		rpterr();
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_CMDFAIL), tmp_entry, n);
		(void) close(list_fd);
		(void) unlink(tmp_file);
		cleanup();
		return (1);
	}

	(void) close(list_fd);
	(void) unlink(tmp_file);

	if (making_sig) {
		/* change to back to src dir for subsequent operations */
		if (chdir(cwd)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CHDIR), cwd);
			cleanup();
			return (1);
		}
	}
	return (0);
}
Exemplo n.º 4
0
/*
 * Name:		pkgdump
 * Description:	Dump a cpio archive of a package's contents to a BIO.
 *
 * Arguments:	srcinst - Name of package, which resides on the
 *		device pointed to by the static 'srcdev' variable,
 *		to dump.
 *		bio - BIO object to dump data to
 *
 * Returns :   	0 - success
 *		nonzero - failure.  errors printed to screen.
 */
static int
pkgdump(char *srcinst, BIO *bio)
{
	FILE	*fp;
	char	*src;
	char	temp[MAXPATHLEN],
		srcdir[MAXPATHLEN],
		cmd[CMDSIZE];
	int	i, n, part, nparts, maxpartsize, iscomp;

	/*
	 * when this routine is entered, the entire package
	 * is already available at 'src' - including the
	 * pkginfo/pkgmap files and the objects as well.
	 */

	/* read the pkgmap to get it's size information */
	if ((fp = fopen(PKGMAP, "r")) == NULL) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
		return (1);
	}

	nparts = 1;
	if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
		return (1);
	else
		(void) fclose(fp);

	/* make sure the first volume is available */
	if (srcdev.mount) {
		src = srcdev.dirname;
		(void) snprintf(srcdir, MAXPATHLEN, "%s/%s", src, srcinst);
		if (ckvolseq(srcdir, 1, nparts)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_SEQUENCE));
			return (1);
		}
	}

	/*
	 * form cpio command that will output the contents of all of
	 * this package's parts
	 */
	for (part = 1; part <= nparts; /* void */) {

		if (part == 1) {
			(void) snprintf(cmd, CMDSIZE, "find %s %s",
			    PKGINFO, PKGMAP);
			if (nparts && (isdir(INSTALL) == 0)) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, INSTALL, sizeof (cmd));
			}
		} else
			(void) snprintf(cmd, CMDSIZE, "find %s", PKGINFO);

		if (nparts > 1) {
			(void) snprintf(temp, MAXPATHLEN, "%s.%d", RELOC, part);
			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
				(void) strlcat(cmd, " ", CMDSIZE);
				(void) strlcat(cmd, temp, CMDSIZE);
			}
			(void) snprintf(temp, MAXPATHLEN, "%s.%d", ROOT, part);
			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
				(void) strlcat(cmd, " ", CMDSIZE);
				(void) strlcat(cmd, temp, CMDSIZE);
			}
			(void) snprintf(temp, MAXPATHLEN, "%s.%d",
			    ARCHIVE, part);
			if (isdir(temp) == 0) {
				(void) strlcat(cmd, " ", CMDSIZE);
				(void) strlcat(cmd, temp, CMDSIZE);
			}
		} else if (nparts) {
			for (i = 0; reloc_names[i] != NULL; i++) {
				if (iscpio(reloc_names[i], &iscomp) ||
				    isdir(reloc_names[i]) == 0) {
					(void) strlcat(cmd, " ", CMDSIZE);
					(void) strlcat(cmd, reloc_names[i],
					    CMDSIZE);
				}
			}
			for (i = 0; root_names[i] != NULL; i++) {
				if (iscpio(root_names[i], &iscomp) ||
				    isdir(root_names[i]) == 0) {
					(void) strlcat(cmd, " ", CMDSIZE);
					(void) strlcat(cmd, root_names[i],
					    CMDSIZE);
				}
			}
			if (isdir(ARCHIVE) == 0) {
				(void) strlcat(cmd, " ", CMDSIZE);
				(void) strlcat(cmd, ARCHIVE, CMDSIZE);
			}
		}

		(void) snprintf(cmd + strlen(cmd),
		    sizeof (cmd) - strlen(cmd),
		    " -print | %s -ocD -C %d",
		    CPIOPROC, (int)BLK_SIZE);
		/*
		 * execute the command, dumping all standard output
		 * to the BIO.
		 */
		n = BIO_dump_cmd(cmd, bio);
		if (n != 0) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
			return (1);
		}

		part++;
	}
	return (0);
}
Exemplo n.º 5
0
static int
pkgxfer(char *srcinst, int options)
{
	int	r;
	struct pkginfo info;
	FILE	*fp, *pp;
	char	*pt, *src, *dst;
	char	dstdir[PATH_MAX],
		temp[PATH_MAX],
		srcdir[PATH_MAX],
		cmd[CMDSIZE],
		pkgname[NON_ABI_NAMELNGTH];
	int	i, n, part, nparts, maxpartsize, curpartcnt, iscomp;
	char	volnos[128], tmpvol[128];
	struct	statvfs64 svfsb;
	longlong_t free_blocks;
	struct	stat	srcstat;

	info.pkginst = NULL; /* required initialization */

	/*
	 * when this routine is entered, the first part of
	 * the package to transfer is already available in
	 * the directory indicated by 'src' --- unless the
	 * source device is a datstream, in which case only
	 * the pkginfo and pkgmap files are available in 'src'
	 */
	src = srcdev.dirname;
	dst = dstdev.dirname;

	if (!(options & PT_SILENT))
		(void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst);
	(void) strlcpy(dstinst, srcinst, sizeof (dstinst));

	if (!(options & PT_ODTSTREAM)) {
		/* destination is a (possibly mounted) directory */
		(void) snprintf(dstdir, sizeof (dstdir),
		    "%s/%s", dst, dstinst);

		/*
		 * need to check destination directory to assure
		 * that we will not be duplicating a package which
		 * already resides there (though we are allowed to
		 * overwrite the same version)
		 */
		pkgdir = src;
		if (fpkginfo(&info, srcinst)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_NOEXISTS), srcinst);
			(void) fpkginfo(&info, NULL);
			return (1);
		}
		pkgdir = dst;

		(void) strlcpy(temp, srcinst, sizeof (temp));
		if (pt = strchr(temp, '.'))
			*pt = '\0';
		(void) strlcat(temp, ".*", sizeof (temp));

		if (pt = fpkginst(temp, info.arch, info.version)) {
			/*
			 * the same instance already exists, although
			 * its pkgid might be different
			 */
			if (options & PT_OVERWRITE) {
				(void) strlcpy(dstinst, pt, sizeof (dstinst));
				(void) snprintf(dstdir, sizeof (dstdir),
				    "%s/%s", dst, dstinst);
			} else {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_DUPVERS), srcinst);
				(void) fpkginfo(&info, NULL);
				(void) fpkginst(NULL);
				return (2);
			}
		} else if (options & PT_RENAME) {
			/*
			 * find next available instance by appending numbers
			 * to the package abbreviation until the instance
			 * does not exist in the destination directory
			 */
			if (pt = strchr(temp, '.'))
				*pt = '\0';
			for (i = 2; (access(dstdir, 0) == 0); i++) {
				(void) snprintf(dstinst, sizeof (dstinst),
				    "%s.%d", temp, i);
				(void) snprintf(dstdir, sizeof (dstdir),
				    "%s/%s", dst, dstinst);
			}
		} else if (options & PT_OVERWRITE) {
			/*
			 * we're allowed to overwrite, but there seems
			 * to be no valid package to overwrite, and we are
			 * not allowed to rename the destination, so act
			 * as if we weren't given permission to overwrite
			 * --- this keeps us from removing a destination
			 * instance which is named the same as the source
			 * instance, but really reflects a different pkg!
			 */
			options &= (~PT_OVERWRITE);
		}
		(void) fpkginfo(&info, NULL);
		(void) fpkginst(NULL);

		if (ckoverwrite(dst, dstinst, options))
			return (2);

		if (isdir(dstdir) && mkdir(dstdir, 0755)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_MKDIR), dstdir);
			return (1);
		}

		(void) snprintf(srcdir, sizeof (srcdir),
		    "%s/%s", src, srcinst);
		if (stat(srcdir, &srcstat) != -1) {
			if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_CHMODDIR), dstdir);
				return (1);
			}
		} else {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_STATDIR), srcdir);
			return (1);
		}
	}

	if (!(options & PT_SILENT) && strcmp(dstinst, srcinst))
		(void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst);

	(void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst);
	if (chdir(srcdir)) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_CHDIR), srcdir);
		return (1);
	}

	if (ids_name) {	/* unpack the datatstream into a directory */
		/*
		 * transfer pkginfo & pkgmap first
		 */
		(void) snprintf(cmd, sizeof (cmd),
		    "%s -pudm %s", CPIOPROC, dstdir);
		if ((pp = epopen(cmd, "w")) == NULL) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_POPEN), cmd, errno);
			return (1);
		}
		(void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP);

		(void) sighold(SIGINT);
		(void) sighold(SIGHUP);
		r = epclose(pp);
		(void) sigrelse(SIGINT);
		(void) sigrelse(SIGHUP);

		if (r != 0) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_PCLOSE), cmd, errno);
			return (1);
		}

		if (options & PT_INFO_ONLY)
			return (0); /* don't transfer objects */

		if (chdir(dstdir)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CHDIR), dstdir);
			return (1);
		}

		/*
		 * for each part of the package, use cpio() to
		 * unpack the archive into the destination directory
		 */
		nparts = ds_findpkg(srcdev.cdevice, srcinst);
		if (nparts < 0) {
			progerr(pkg_gt(ERR_TRANSFER));
			return (1);
		}
		for (part = 1; part <= nparts; /* void */) {
			if (ds_getpkg(srcdev.cdevice, part, dstdir)) {
				progerr(pkg_gt(ERR_TRANSFER));
				return (1);
			}
			part++;
			if (dstdev.mount) {
				(void) chdir("/");
				if (pkgumount(&dstdev))
					return (1);
				if (part <= nparts) {
					if (n = pkgmount(&dstdev, NULL, part+1,
					    nparts, 1))
						return (n);
					if (ckoverwrite(dst, dstinst, options))
						return (1);
					if (isdir(dstdir) &&
					    mkdir(dstdir, 0755)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_MKDIR),
						    dstdir);
						return (1);
					}
					/*
					 * since volume is removable, each part
					 * must contain a duplicate of the
					 * pkginfo file to properly identify the
					 * volume
					 */
					if (chdir(srcdir)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_CHDIR),
						    srcdir);
						return (1);
					}
					if ((pp = epopen(cmd, "w")) == NULL) {
						rpterr();
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_POPEN),
						    cmd, errno);
						return (1);
					}
					(void) fprintf(pp, "pkginfo");

					(void) sighold(SIGINT);
					(void) sighold(SIGHUP);
					r = epclose(pp);
					(void) sigrelse(SIGINT);
					(void) sigrelse(SIGHUP);

					if (r != 0) {
						rpterr();
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_PCLOSE),
						    cmd, errno);
						return (1);
					}
					if (chdir(dstdir)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_CHDIR),
						    dstdir);
						return (1);
					}
				}
			}
		}
		return (0);
	}

	if ((fp = fopen(PKGMAP, "r")) == NULL) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
		return (1);
	}

	nparts = 1;
	if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
		return (1);
	else
		(void) fclose(fp);

	if (srcdev.mount) {
		if (ckvolseq(srcdir, 1, nparts)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_SEQUENCE));
			return (1);
		}
	}

	/* write each part of this package */
	if (options & PT_ODTSTREAM) {
		char line[128];
		(void) mgets(line, 128);
		curpartcnt = -1;
		/* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
		if (sscanf(line, "%s %d %d %[ 0-9]", pkgname, &nparts,
		    &maxpartsize, volnos) == 4) {
			(void) sscanf(volnos,
			    "%d %[ 0-9]", &curpartcnt, tmpvol);
			(void) strlcpy(volnos, tmpvol, sizeof (volnos));
		}
	}

	for (part = 1; part <= nparts; /* void */) {
		if (curpartcnt == 0 && (options & PT_ODTSTREAM)) {
			char prompt[128];
			int index;
			ds_volno++;
			(void) ds_close(0);
			(void) sprintf(prompt,
			    pkg_gt("Insert %%v %d of %d into %%p"),
			    ds_volno, ds_volcnt);
			if (n = getvol(ods_name, NULL, DM_FORMAT, prompt))
				return (n);
			if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
				    errno);
				return (1);
			}
			if (ds_ginit(dstdev.cdevice) < 0) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
				    errno);
				(void) ds_close(0);
				return (1);
			}

			(void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol);
			(void) strlcpy(volnos, tmpvol, sizeof (volnos));
			curpartcnt += index;
		}

		if (options & PT_INFO_ONLY)
			nparts = 0;

		if (part == 1) {
			(void) snprintf(cmd, sizeof (cmd),
			    "find %s %s", PKGINFO, PKGMAP);
			if (nparts && (isdir(INSTALL) == 0)) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, INSTALL, sizeof (cmd));
			}
		} else
			(void) snprintf(cmd, sizeof (cmd), "find %s", PKGINFO);

		if (nparts > 1) {
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", RELOC, part);
			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", ROOT, part);
			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", ARCHIVE, part);
			if (isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
		} else if (nparts) {
			for (i = 0; reloc_names[i] != NULL; i++) {
				if (iscpio(reloc_names[i], &iscomp) ||
				    isdir(reloc_names[i]) == 0) {
					(void) strlcat(cmd, " ", sizeof (cmd));
					(void) strlcat(cmd, reloc_names[i],
					    sizeof (cmd));
				}
			}
			for (i = 0; root_names[i] != NULL; i++) {
				if (iscpio(root_names[i], &iscomp) ||
				    isdir(root_names[i]) == 0) {
					(void) strlcat(cmd, " ", sizeof (cmd));
					(void) strlcat(cmd, root_names[i],
					    sizeof (cmd));
				}
			}
			if (isdir(ARCHIVE) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, ARCHIVE, sizeof (cmd));
			}
		}
		if (options & PT_ODTSTREAM) {
			(void) snprintf(cmd + strlen(cmd),
			    sizeof (cmd) - strlen(cmd),
			    " -print | %s -ocD -C %d",
			    CPIOPROC, (int)BLK_SIZE);
		} else {
			if (statvfs64(dstdir, &svfsb) == -1) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_STATVFS), dstdir, errno);
				return (1);
			}

			free_blocks = (((long)svfsb.f_frsize > 0) ?
			    howmany(svfsb.f_frsize, DEV_BSIZE) :
			    howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail;

			if ((has_comp_size ? compressedsize : maxpartsize) >
			    free_blocks) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_NOSPACE),
				    has_comp_size ?
				    (long)compressedsize : (long)maxpartsize,
				    free_blocks);
				return (1);
			}
			(void) snprintf(cmd + strlen(cmd),
			    sizeof (cmd) - strlen(cmd),
			    " -print | %s -pdum %s",
			    CPIOPROC, dstdir);
		}

		n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1);
		if (n) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
			return (1);
		}

		part++;
		if (srcdev.mount && (nparts > 1)) {
			/* unmount current source volume */
			(void) chdir("/");
			if (pkgumount(&srcdev))
				return (1);
			/* loop until volume is mounted successfully */
			while (part <= nparts) {
				/* read only */
				n = pkgmount(&srcdev, NULL, part, nparts, 1);
				if (n)
					return (n);
				if (chdir(srcdir)) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_CORRUPT));
					(void) chdir("/");
					(void) pkgumount(&srcdev);
					continue;
				}
				if (ckvolseq(srcdir, part, nparts)) {
					(void) chdir("/");
					(void) pkgumount(&srcdev);
					continue;
				}
				break;
			}
		}
		if (!(options & PT_ODTSTREAM) && dstdev.mount) {
			/* unmount current volume */
			if (pkgumount(&dstdev))
				return (1);
			/* loop until next volume is mounted successfully */
			while (part <= nparts) {
				/* writable */
				n = pkgmount(&dstdev, NULL, part, nparts, 1);
				if (n)
					return (n);
				if (ckoverwrite(dst, dstinst, options))
					continue;
				if (isdir(dstdir) && mkdir(dstdir, 0755)) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_MKDIR), dstdir);
					continue;
				}
				break;
			}
		}

		if ((options & PT_ODTSTREAM) && part <= nparts) {
			if (curpartcnt >= 0 && part > curpartcnt) {
				char prompt[128];
				int index;
				ds_volno++;
				if (ds_close(0))
					return (1);
				(void) sprintf(prompt,
				    pkg_gt("Insert %%v %d of %d into %%p"),
				    ds_volno, ds_volcnt);
				if (n = getvol(ods_name, NULL, DM_FORMAT,
				    prompt))
					return (n);
				if ((ds_fd = open(dstdev.cdevice, 1)) < 0) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_OPEN),
					    dstdev.cdevice, errno);
					return (1);
				}
				if (ds_ginit(dstdev.cdevice) < 0) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_OPEN),
					    dstdev.cdevice, errno);
					(void) ds_close(0);
					return (1);
				}

				(void) sscanf(volnos, "%d %[ 0-9]", &index,
				    tmpvol);
				(void) strlcpy(volnos, tmpvol, sizeof (volnos));
				curpartcnt += index;
			}
		}

	}
	return (0);
}
Exemplo n.º 6
0
int
pkgmount(struct pkgdev *devp, char *pkg, int part, int nparts, int getvolflg)
{
	int	n;
	char	*pt, prompt[64], cmd[CMDSIZ];
	FILE	*pp;

	if (getuid()) {
		progerr(pkg_gt(ERR_NOTROOT));
		return (99);
	}

	if (part && nparts) {
		if (pkg) {
			(void) snprintf(prompt, sizeof (prompt),
			    pkg_gt(LABEL0), part, nparts, pkg);
		} else {
			(void) snprintf(prompt, sizeof (prompt),
			    pkg_gt(LABEL1), part, nparts);
		}
	} else if (pkg)
		(void) snprintf(prompt, sizeof (prompt), pkg_gt(LABEL2), pkg);
	else
		(void) snprintf(prompt, sizeof (prompt), pkg_gt(LABEL3));

	n = 0;
	for (;;) {
		if (!getvolflg && n)
			/*
			 * Return to caller if not prompting
			 * and error was encountered.
			 */
			return (-1);
		if (getvolflg && (n = getvol(devp->bdevice, NULL,
		    (devp->rdonly ? 0 : DM_FORMFS|DM_WLABEL), prompt))) {
			if (n == 3)
				return (3);
			if (n == 2)
				progerr(pkg_gt("unknown device <%s>"),
				    devp->bdevice);
			else
				progerr(
				    pkg_gt("unable to obtain package volume"));
			return (99);
		}

		if (devp->fstyp == NULL) {
			(void) snprintf(cmd, sizeof (cmd),
			    "%s %s", FSTYP, devp->bdevice);
			if ((pp = epopen(cmd, "r")) == NULL) {
				rpterr();
				logerr(pkg_gt(ERR_FSTYP), devp->bdevice);
				n = -1;
				continue;
			}
			cmd[0] = '\0';
			if (fgets(cmd, CMDSIZ, pp) == NULL) {
				logerr(pkg_gt(ERR_FSTYP), devp->bdevice);
				(void) pclose(pp);
				n = -1;
				continue;
			}
			if (epclose(pp)) {
				rpterr();
				logerr(pkg_gt(ERR_FSTYP), devp->bdevice);
				n = -1;
				continue;
			}
			if (pt = strpbrk(cmd, " \t\n"))
				*pt = '\0';
			if (cmd[0] == '\0') {
				logerr(pkg_gt(ERR_FSTYP), devp->bdevice);
				n = -1;
				continue;
			}
			devp->fstyp = strdup(cmd);
		}

		if (devp->rdonly) {
			n = pkgexecl(NULL, NULL, NULL, NULL, MOUNT, "-r", "-F",
			    devp->fstyp, devp->bdevice, devp->mount, NULL);
		} else {
			n = pkgexecl(NULL, NULL, NULL, NULL, MOUNT, "-F",
			    devp->fstyp, devp->bdevice, devp->mount, NULL);
		}
		if (n) {
			progerr(pkg_gt("mount of %s failed"), devp->bdevice);
			continue;
		}
		devp->mntflg++;
		break;
	}
	return (0);
}