/* * 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); }
/* ---------- 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; }
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); }
/* * 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); }
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); }
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); }