int pkghead(char *device) { char *pt; int n; cleanup(); if (device == NULL) return (0); else if ((device[0] == '/') && !isdir(device)) { pkgdir = device; return (0); } else if ((pt = devattr(device, "pathname")) != NULL && !isdir(pt)) { pkgdir = pt; return (0); } /* check for datastream */ if (n = pkgtrans(device, (char *)0, allpkg, PT_SILENT|PT_INFO_ONLY, NULL, NULL)) { cleanup(); return (n); } /* pkgtrans has set pkgdir */ return (0); }
int _getvol(char *device, char *label, int options, char *prompt, char *norewind) { FILE *tmp; char *advice, *pt; int n, override; cdevice = devattr(device, "cdevice"); if ((cdevice == NULL) || !cdevice[0]) { cdevice = devattr(device, "pathname"); if ((cdevice == NULL) || !cdevice) return (2); /* bad device */ } pname = devattr(device, "desc"); if (pname == NULL) { pname = devattr(device, "alias"); if (!pname) pname = device; } volume = devattr(device, "volume"); if (label) { (void) strncpy(origfsname, label, LABELSIZ); origfsname[LABELSIZ] = '\0'; if (pt = strchr(origfsname, ',')) { *pt = '\0'; } if (pt = strchr(label, ',')) { (void) strncpy(origvolname, pt+1, LABELSIZ); origvolname[LABELSIZ] = '\0'; } else origvolname[0] = '\0'; } override = 0;
static char * islocked(char *device) { /* Automatic data */ char *alias; /* Alias of "device" */ struct devlks *plk; /* Ptr to locking info */ int locked; /* TRUE if device in locked list */ int i; /* Temp counter */ /* Get the device's alias */ if (alias = devattr(device, DTAB_ALIAS)) { /* * Look through the device locks to see if this device alias * is locked */ locked = FALSE; plk = locklist; for (i = 0; !locked && (i < lockcount); i++) { if (strncmp(alias, plk->lk_alias, DTAB_MXALIASLN) == 0) locked = TRUE; else plk++; } if (locked) { free(alias); alias = NULL; errno = EAGAIN; } } /* devattr() failed, no such device? */ /* Return pointer to the device */ return (alias); }
int unreserv(int key, char *device) { /* Automatics */ char *srchalias; /* Device alias to search table with */ char *alias; /* Device's alias (from devattr()) */ struct devlks *plk; /* Pointer to a device lock */ int locked; /* TRUE if device currently locked */ int noerr; /* TRUE if all's well */ int olderrno; /* Entry value of "errno" */ int i; /* Counter of locks */ /* Initializations */ noerr = TRUE; /* * Get the device alias. If none can be found, try to free * whatever it is that was given to us (the possibility exists * that the device has been removed from the device table since * it was reserved, so the device not being in the table shouldn't * pose too much of a problem with us...) */ olderrno = errno; if (alias = devattr(device, DTAB_ALIAS)) srchalias = alias; else { errno = olderrno; srchalias = device; } /* Loop through the locked-device list looking for what we've got... */ locked = FALSE; plk = locklist; for (i = 0; !locked && (i < lockcount); i++) { if (strcmp(srchalias, plk->lk_alias) == 0) locked = TRUE; else plk++; } /* Free the alias string (if any), we don't need it anymore */ if (alias) free(alias); /* If the device is locked ... */ if (locked) { /* * If it's locked on the key we've been given, free it. * Otherwise, don't free it and set errno to EPERM */ if (plk->lk_key == key) { plk->lk_alias[0] = '\0'; } else { noerr = FALSE; errno = EPERM; } } else { /* The device isn't locked. Set errno to EINVAL */ noerr = FALSE; errno = EINVAL; } /* Finished. Return an indication of our success */ return (noerr); }
int main(int argc, char *argv[]) { int pkgfmt = 0; /* Makes more sense as a pointer, but */ /* 18N is compromised. */ char file[PATH_MAX+1], *abi_sym_ptr, *vfstab_file = NULL; char *all_pkgs[4] = {"all", NULL}; char **category = NULL; char *catg_arg = NULL; int c; int n = 0; char *prog, *Rvalue = NULL, *dvalue = NULL; int dbcreate = 0; int pathtype; /* initialize locale mechanism */ #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); /* determine program name */ prog = set_prog_name(argv[0]); /* establish installation root directory */ if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) { progerr(gettext(ERR_ROOT_SET)); quit(1); } /* check if not ABI compliant mode */ abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS"); if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) { set_nonABI_symlinks(); } /* bugId 4012147 */ if ((uniTmp = getenv("PKG_NO_UNIFIED")) != NULL) map_client = 0; while ((c = getopt(argc, argv, "Y:R:e:p:d:nLli:vaV:Mm:cqxfQP:?")) != EOF) { switch (c) { case 'p': pathlist[npaths] = strtok(optarg, " , "); if (pathlist[npaths++] == NULL) { progerr(gettext(ERR_POPTION)); quit(1); } while (pathlist[npaths] = strtok(NULL, " , ")) { if (npaths++ >= MAXPATHS) { progerr(gettext(ERR_MAXPATHS), MAXPATHS); quit(1); } } break; case 'd': dvalue = optarg; dflag = 1; break; case 'n': nflag++; break; case 'M': map_client = 0; break; /* * Allow admin to establish the client filesystem using a * vfstab-like file of stable format. */ case 'V': vfstab_file = flex_device(optarg, 2); map_client = 1; break; case 'f': #if 0 if (getuid()) { progerr(gettext(ERR_NOTROOT), prog); quit(1); } #endif fflag++; break; case 'i': setpathlist(optarg); break; case 'v': vflag++; break; case 'l': lflag++; break; case 'L': Lflag++; break; case 'x': if (aflag < 0) aflag = 0; if (cflag < 0) cflag = 0; xflag++; break; case 'q': qflag++; break; case 'a': if (cflag < 0) cflag = 0; aflag = 1; break; case 'c': if (aflag < 0) aflag = 0; cflag = 1; break; case 'e': envfile = optarg; break; case 'm': mapfile = optarg; break; case 'R': Rvalue = optarg; Rflag = 1; break; case 'Y': catg_arg = strdup(optarg); if ((category = get_categories(catg_arg)) == NULL) { progerr(gettext(ERR_CAT_INV), catg_arg); quit(1); } else if (is_not_valid_length(category)) { progerr(gettext(ERR_CAT_LNGTH)); quit(1); } break; case 'Q': dbcreate++; break; case 'P': ppathlist[npaths] = strtok(optarg, " , "); if ((ppathlist[npaths] == NULL) || (ppathlist[npaths][0] == '-')) { progerr(gettext(ERR_PARTIAL_POPTION)); quit(1); } npaths++; while (ppathlist[npaths] = strtok(NULL, " , ")) { if (npaths++ >= MAXPATHS) { progerr(gettext(ERR_MAXPATHS), MAXPATHS); quit(1); } } break; default: usage(); } } /* Check for incompatible options */ if (dflag && Rflag) usage(); /* Check for root dir and device dir if set */ if (Rflag) { if (!set_inst_root(Rvalue)) { progerr(gettext(ERR_ROOT_CMD)); quit(1); } } if (dflag) device = flex_device(dvalue, 1); if (lflag || Lflag) { /* we're only supposed to list information */ if ((cflag >= 0) || (aflag >= 0) || qflag || xflag || fflag || nflag || vflag) usage(); } set_PKGpaths(get_inst_root()); if (catg_arg != NULL && device == NULL) { if (argc - optind) { usage(); } pkg = gpkglist(pkgdir, all_pkgs, category); if (pkg == NULL) { progerr(gettext(ERR_CAT_FND), catg_arg); quit(1); } else { for (pkgcnt = 0; pkg[pkgcnt] != NULL; pkgcnt++); } } else if (catg_arg != NULL && optind < argc) { usage(); } else { pkg = &argv[optind]; pkgcnt = (argc - optind); } environ = NULL; /* Sever the parent environment. */ if (vcfile() == 0) { quit(99); } errflg = 0; if (mapfile) { /* check for incompatible options */ if (device || pkgcnt) usage(); put_path_params(); /* Restore what's needed. */ /* send pathtype if partial path */ pathtype = (ppathlist[0] != NULL) ? 1 : 0; if (checkmap(0, (device != NULL), mapfile, envfile, NULL, NULL, pathtype)) errflg++; } else if (device) { /* check for incompatible options */ if ((cflag >= 0) || (aflag >= 0)) usage(); if (qflag || xflag || nflag || envfile) usage(); tmpdir = NULL; if ((spooldir = devattr(device, "pathname")) == NULL) spooldir = device; if (isdir(spooldir)) { char template[] = "/var/tmp/spoolXXXXXX"; close(mkstemp(template));
/* * Try to detect the real device(s) used for the system console * /dev/console if but only if /dev/console is used. On Linux * this can be more than one device, e.g. a serial line as well * as a virtual console as well as a simple printer. * * Returns 1 if stdout and stderr should be reconnected and 0 * otherwise. */ int detect_consoles(const char *device, int fallback) { int fd, ret = 0; #ifdef __linux__ char *attrib, *cmdline; FILE *fc; #endif if (!device || *device == '\0') fd = dup(fallback); else { fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); ret = 1; } if (fd >= 0) { DIR *dir; char *name; struct stat st; #ifdef TIOCGDEV unsigned int devnum; #endif if (fstat(fd, &st) < 0) { close(fd); goto fallback; } comparedev = st.st_rdev; if (ret && (fstat(fallback, &st) < 0 || comparedev != st.st_rdev)) dup2(fd, fallback); #ifdef __linux__ /* * Check if the device detection for Linux system console should be used. */ if (comparedev == makedev(TTYAUX_MAJOR, 0)) { /* /dev/tty */ close(fd); device = "/dev/tty"; goto fallback; } if (comparedev == makedev(TTYAUX_MAJOR, 1)) { /* /dev/console */ close(fd); goto console; } if (comparedev == makedev(TTYAUX_MAJOR, 2)) { /* /dev/ptmx */ close(fd); device = "/dev/tty"; goto fallback; } if (comparedev == makedev(TTY_MAJOR, 0)) { /* /dev/tty0 */ struct vt_stat vt; if (ioctl(fd, VT_GETSTATE, &vt) < 0) { close(fd); goto fallback; } comparedev = makedev(TTY_MAJOR, (int)vt.v_active); } #endif #ifdef TIOCGDEV if (ioctl (fd, TIOCGDEV, &devnum) < 0) { close(fd); goto fallback; } comparedev = (dev_t)devnum; #endif close(fd); dir = opendir("/dev"); if (!dir) goto fallback; name = scandev(dir); if (name) consalloc(name); closedir(dir); if (!consoles) goto fallback; return ret; } #ifdef __linux__ console: /* * Detection of devices used for Linux system consolei using * the /proc/consoles API with kernel 2.6.38 and higher. */ if ((fc = fopen("/proc/consoles", "re"))) { char fbuf[16]; int maj, min; DIR *dir; dir = opendir("/dev"); if (!dir) { fclose(fc); goto fallback; } while ((fscanf(fc, "%*s %*s (%[^)]) %d:%d", &fbuf[0], &maj, &min) == 3)) { char * name; if (!strchr(fbuf, 'E')) continue; comparedev = makedev(maj, min); name = scandev(dir); if (!name) continue; consalloc(name); } closedir(dir); fclose(fc); return ret; } /* * Detection of devices used for Linux system console using * the sysfs /sys/class/tty/ API with kernel 2.6.37 and higher. */ if ((attrib = actattr("console"))) { char *words = attrib, *token; DIR *dir; dir = opendir("/dev"); if (!dir) { free(attrib); goto fallback; } while ((token = strsep(&words, " \t\r\n"))) { char * name; if (*token == '\0') continue; comparedev = devattr(token); if (comparedev == makedev(TTY_MAJOR, 0)) { char *tmp = actattr(token); if (!tmp) continue; comparedev = devattr(tmp); free(tmp); } name = scandev(dir); if (!name) continue; consalloc(name); } closedir(dir); free(attrib); if (!consoles) goto fallback; return ret; } /* * Detection of devices used for Linux system console using * kernel parameter on the kernels command line. */ if ((cmdline = oneline("/proc/cmdline"))) { char *words= cmdline, *token; DIR *dir; dir = opendir("/dev"); if (!dir) { free(cmdline); goto fallback; } while ((token = strsep(&words, " \t\r\n"))) { #ifdef TIOCGDEV unsigned int devnum; #else struct vt_stat vt; struct stat st; #endif char *colon, *name; if (*token != 'c') continue; if (strncmp(token, "console=", 8) != 0) continue; token += 8; if (strcmp(token, "brl") == 0) token += 4; if ((colon = strchr(token, ','))) *colon = '\0'; if (asprintf(&name, "/dev/%s", token) < 0) continue; if ((fd = open(name, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC)) < 0) { free(name); continue; } free(name); #ifdef TIOCGDEV if (ioctl (fd, TIOCGDEV, &devnum) < 0) { close(fd); continue; } comparedev = (dev_t)devnum; #else if (fstat(fd, &st) < 0) { close(fd); continue; } comparedev = st.st_rdev; if (comparedev == makedev(TTY_MAJOR, 0)) { if (ioctl(fd, VT_GETSTATE, &vt) < 0) { close(fd); continue; } comparedev = makedev(TTY_MAJOR, (int)vt.v_active); } #endif close(fd); name = scandev(dir); if (!name) continue; consalloc(name); } closedir(dir); free(cmdline); /* * Detection of the device used for Linux system console using * the ioctl TIOCGDEV if available (e.g. official 2.6.38). */ if (!consoles) { #ifdef TIOCGDEV unsigned int devnum; const char *name; if (!device || *device == '\0') fd = dup(fallback); else fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); if (fd < 0) goto fallback; if (ioctl (fd, TIOCGDEV, &devnum) < 0) { close(fd); goto fallback; } comparedev = (dev_t)devnum; close(fd); if (device && *device != '\0') name = device; else name = ttyname(fallback); if (!name) name = "/dev/tty1"; consalloc(strdup(name)); if (consoles) { if (!device || *device == '\0') consoles->fd = fallback; return ret; } #endif goto fallback; } return ret; } #endif /* __linux __ */ fallback: if (fallback >= 0) { const char *name; if (device && *device != '\0') name = device; else name = ttyname(fallback); if (!name) name = "/dev/tty"; consalloc(strdup(name)); if (consoles) consoles->fd = fallback; } return ret; }
int main(int argc, char *argv[]) { struct utsname utsbuf; struct statvfs64 svfsb; struct cfent **eptlist; FILE *fp; VFP_T *vfp; int i, c, n, eptnum, found, part, nparts, npkgs, objects; char buf[MAX_PKG_PARAM_LENGTH]; char temp[MAX_PKG_PARAM_LENGTH]; char param[MAX_PKG_PARAM_LENGTH]; char *pt, *value, *pkginst, *tmpdir, *abi_sym_ptr, **cmdparam; char *pkgname; char *pkgvers; char *pkgarch; char *pkgcat; void (*func)(); time_t clock; fsblkcnt_t bsize = 0; fsblkcnt_t frsize = 0; struct cl_attr **allclass = NULL; struct cl_attr **order; /* initialize locale environment */ (void) setlocale(LC_ALL, ""); #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" #endif (void) textdomain(TEXT_DOMAIN); /* initialize program name */ (void) set_prog_name(argv[0]); /* tell spmi zones interface how to access package output functions */ z_set_output_functions(echo, echoDebug, progerr); func = sigset(SIGINT, trap); if (func != SIG_DFL) func = sigset(SIGINT, func); func = sigset(SIGHUP, trap); setmapmode(MAPBUILD); /* variable binding */ if (func != SIG_DFL) func = sigset(SIGHUP, func); environ = NULL; while ((c = getopt(argc, argv, "osnp:l:r:b:d:f:a:v:?")) != EOF) { switch (c) { case 'n': nflag++; break; case 's': sflag++; break; case 'o': overwrite++; break; case 'p': putparam("PSTAMP", optarg); break; case 'l': llimit = atol(optarg); break; case 'r': pt = strtok(optarg, " \t\n, "); n = 0; do { rootlist[n++] = flex_device(pt, 0); if (n >= NROOT) { progerr(gettext(ERR_NROOT), NROOT); quit(1); } } while (pt = strtok(NULL, " \t\n, ")); rootlist[n] = NULL; break; case 'b': basedir = optarg; break; case 'f': protofile = optarg; break; case 'd': device = flex_device(optarg, 1); break; case 'a': putparam("ARCH", optarg); break; case 'v': putparam("VERSION", optarg); break; default: usage(); } } /* * Store command line variable assignments for later * incorporation into the environment. */ cmdparam = &argv[optind]; /* Skip past equates. */ while (argv[optind] && strchr(argv[optind], '=')) optind++; /* Confirm that the instance name is valid */ if ((pkginst = argv[optind]) != NULL) { if (pkgnmchk(pkginst, "all", 0)) { progerr(gettext(ERR_PKGINST), pkginst); quit(1); } argv[optind++] = NULL; } if (optind != argc) usage(); tmpdir = getenv("TMPDIR"); if (tmpdir == NULL) tmpdir = P_tmpdir; /* bug id 4244631, not ABI compliant */ abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS"); if (abi_sym_ptr && (strncasecmp(abi_sym_ptr, "TRUE", 4) == 0)) { set_nonABI_symlinks(); } if (device == NULL) { device = devattr(SPOOLDEV, "pathname"); if (device == NULL) { progerr(gettext(ERR_DEVICE), SPOOLDEV); exit(99); } } if (protofile == NULL) { if (access("prototype", 0) == 0) protofile = "prototype"; else if (access("Prototype", 0) == 0) protofile = "Prototype"; else { progerr(gettext(ERR_PROTOTYPE)); quit(1); } } if (devtype(device, &pkgdev)) { progerr(gettext(ERR_BADDEV), device); quit(1); } if (pkgdev.norewind) { /* initialize datastream */ progerr(gettext(ERR_DSTREAM), device); quit(1); } if (pkgdev.mount) { if (n = pkgmount(&pkgdev, NULL, 0, 0, 1)) quit(n); } /* * convert prototype file to a pkgmap, while locating * package objects in the current environment */ t_pkgmap = tempnam(tmpdir, "tmpmap"); if (t_pkgmap == NULL) { progerr(gettext(ERR_TEMP), errno); exit(99); } (void) fprintf(stderr, gettext(MSG_PROTOTYPE)); if (n = mkpkgmap(t_pkgmap, protofile, cmdparam)) { progerr(gettext(ERR_BUILD)); quit(1); } setmapmode(MAPNONE); /* All appropriate variables are now bound */ if (vfpOpen(&vfp, t_pkgmap, "r", VFP_NEEDNOW) != 0) { progerr(gettext(ERR_TEMP), errno); quit(99); } eptlist = procmap(vfp, 0, NULL); if (eptlist == NULL) { quit(1); } (void) vfpClose(&vfp); /* Validate the zone attributes in pkginfo, before creation */ if (!valid_zone_attr(eptlist)) { progerr(ERR_PKGINFO_INVALID_OPTION_COMB); quit(1); } (void) fprintf(stderr, gettext(MSG_PKGINFO)); pt = NULL; for (i = 0; eptlist[i]; i++) { ckmissing(eptlist[i]->path, eptlist[i]->ftype); if (eptlist[i]->ftype != 'i') continue; if (strcmp(eptlist[i]->path, "pkginfo") == 0) svept = eptlist[i]; } if (svept == NULL) { progerr(gettext(ERR_NOPKGINFO)); quit(99); } eptnum = i; /* * process all parameters from the pkginfo file * and place them in the execution environment */ if ((fp = fopen(svept->ainfo.local, "r")) == NULL) { progerr(gettext(ERR_RDPKGINFO), svept->ainfo.local); quit(99); } param[0] = '\0'; while (value = fpkgparam(fp, param)) { if (getenv(param) == NULL) putparam(param, value); free((void *)value); param[0] = '\0'; } (void) fclose(fp); /* add command line variables */ while (*cmdparam && (value = strchr(*cmdparam, '=')) != NULL) { *value = NULL; /* terminate the parameter */ value++; /* value is now the value (not '=') */ putparam(*cmdparam++, value); /* store it in environ */ } /* make sure parameters are valid */ (void) time(&clock); if (pt = getenv("PKG")) { if (pkgnmchk(pt, NULL, 0) || strchr(pt, '.')) { progerr(gettext(ERR_PKGABRV), pt); quit(1); } if (pkginst == NULL) pkginst = pt; } else { progerr(gettext(ERR_NOPARAM), "PKG", svept->path); quit(1); } /* * verify consistency between PKG parameter and pkginst */ (void) snprintf(param, sizeof (param), "%s.*", pt); if (pkgnmchk(pkginst, param, 0)) { progerr(gettext(ERR_PKGMTCH), pt, pkginst); quit(1); } /* * ********************************************************************* * this feature is removed starting with Solaris 10 - there is no built * in list of packages that should be run "the old way" * ********************************************************************* */ #ifdef ALLOW_EXCEPTION_PKG_LIST /* Until 2.9, set it from the execption list */ if (exception_pkg(pkginst, LINK)) set_nonABI_symlinks(); #endif if ((pkgname = getenv("NAME")) == NULL) { progerr(gettext(ERR_NOPARAM), "NAME", svept->path); quit(1); } if (ckparam("NAME", pkgname)) quit(1); if ((pkgvers = getenv("VERSION")) == NULL) { /* XXX - I18n */ /* LINTED do not use cftime(); use strftime instead */ (void) cftime(buf, "\045m/\045d/\045Y", &clock); (void) snprintf(temp, sizeof (temp), gettext("Dev Release %s"), buf); putparam("VERSION", temp); pkgvers = getenv("VERSION"); logerr(gettext(WRN_SETPARAM), "VERSION", temp); } if (ckparam("VERSION", pkgvers)) quit(1); if ((pkgarch = getenv("ARCH")) == NULL) { (void) uname(&utsbuf); putparam("ARCH", utsbuf.machine); pkgarch = getenv("ARCH"); logerr(gettext(WRN_SETPARAM), "ARCH", utsbuf.machine); } if (ckparam("ARCH", pkgarch)) quit(1); if (getenv("PSTAMP") == NULL) { /* use octal value of '%' to fight sccs expansion */ /* XXX - I18n */ /* LINTED do not use cftime(); use strftime instead */ (void) cftime(buf, "\045Y\045m\045d\045H\045M\045S", &clock); (void) uname(&utsbuf); (void) snprintf(temp, sizeof (temp), "%s%s", utsbuf.nodename, buf); putparam("PSTAMP", temp); logerr(gettext(WRN_SETPARAM), "PSTAMP", temp); } if ((pkgcat = getenv("CATEGORY")) == NULL) { progerr(gettext(ERR_NOPARAM), "CATEGORY", svept->path); quit(1); } if (ckparam("CATEGORY", pkgcat)) quit(1); /* * warn user of classes listed in package which do * not appear in CLASSES variable in pkginfo file */ objects = 0; for (i = 0; eptlist[i]; i++) { if (eptlist[i]->ftype != 'i') { objects++; addlist(&allclass, eptlist[i]->pkg_class); } } if ((pt = getenv("CLASSES")) == NULL) { if (allclass && *allclass) { cl_setl(allclass); cl_putl("CLASSES", allclass); logerr(gettext(WRN_SETPARAM), "CLASSES", getenv("CLASSES")); } } else { cl_sets(qstrdup(pt)); if (allclass && *allclass) { for (i = 0; allclass[i]; i++) { found = 0; if (cl_idx(allclass[i]->name) != -1) { found++; break; } if (!found) { logerr(gettext(WRN_CLASSES), (char *)allclass[i]); } } } } (void) fprintf(stderr, gettext(MSG_VOLUMIZE), objects); order = (struct cl_attr **)0; if (pt = getenv("ORDER")) { pt = qstrdup(pt); (void) setlist(&order, pt); cl_putl("ORDER", order); } /* stat the intended output filesystem to get blocking information */ if (pkgdev.dirname == NULL) { progerr(gettext(ERR_WHATVFS), device); quit(99); } if (statvfs64(pkgdev.dirname, &svfsb)) { progerr(gettext(ERR_STATVFS), pkgdev.dirname); quit(99); } if (bsize == 0) { bsize = svfsb.f_bsize; } if (frsize == 0) { frsize = svfsb.f_frsize; } if (limit == 0) /* * bavail is in terms of fragment size blocks - change * to 512 byte blocks */ limit = (((long)frsize > 0) ? howmany(frsize, DEV_BSIZE) : howmany(bsize, DEV_BSIZE)) * svfsb.f_bavail; if (ilimit == 0) { ilimit = (svfsb.f_favail > 0) ? svfsb.f_favail : svfsb.f_ffree; } nparts = splpkgmap(eptlist, eptnum, (char **)order, bsize, frsize, &limit, &ilimit, &llimit); if (nparts <= 0) { progerr(gettext(ERR_SPLIT)); quit(1); } if (nflag) { for (i = 0; eptlist[i]; i++) (void) ppkgmap(eptlist[i], stdout); exit(0); /*NOTREACHED*/ } (void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s", pkgdev.dirname, pkginst); if (!isdir(pkgloc) && !overwrite) { progerr(gettext(ERR_OVERWRITE), pkgloc); quit(1); } /* output all environment install parameters */ t_pkginfo = tempnam(tmpdir, "pkginfo"); if ((fp = fopen(t_pkginfo, "w")) == NULL) { progerr(gettext(ERR_TEMP), errno); exit(99); } for (i = 0; environ[i]; i++) { if (isupper(*environ[i])) { (void) fputs(environ[i], fp); (void) fputc('\n', fp); } } (void) fclose(fp); started++; (void) rrmdir(pkgloc); if (mkdir(pkgloc, 0755)) { progerr(gettext(ERR_MKDIR), pkgloc); quit(1); } /* determine how many packages already reside on the medium */ pkgdir = pkgdev.dirname; npkgs = 0; while (pt = fpkginst("all", NULL, NULL)) npkgs++; (void) fpkginst(NULL); /* free resource usage */ if (nparts > 1) { if (pkgdev.mount && npkgs) { progerr(gettext(ERR_ONEVOL)); quit(1); } } /* * update pkgmap entry for pkginfo file, since it may * have changed due to command line or failure to * specify all neccessary parameters */ for (i = 0; eptlist[i]; i++) { if (eptlist[i]->ftype != 'i') continue; if (strcmp(eptlist[i]->path, "pkginfo") == 0) { svept = eptlist[i]; svept->ftype = '?'; svept->ainfo.local = t_pkginfo; (void) cverify(0, &svept->ftype, t_pkginfo, &svept->cinfo, 1); svept->ftype = 'i'; break; } } if (nparts > 1) (void) fprintf(stderr, gettext(MSG_PACKAGEM), nparts); else (void) fprintf(stderr, gettext(MSG_PACKAGE1)); for (part = 1; part <= nparts; part++) { if ((part > 1) && pkgdev.mount) { if (pkgumount(&pkgdev)) { progerr(gettext(ERR_UMOUNT), pkgdev.mount); quit(99); } if (n = pkgmount(&pkgdev, NULL, part, nparts, 1)) quit(n); (void) rrmdir(pkgloc); if (mkdir(pkgloc, 0555)) { progerr(gettext(ERR_MKDIR), pkgloc); quit(99); } } outvol(eptlist, eptnum, part, nparts); /* Validate (as much as possible) the control scripts. */ if (part == 1) { char inst_path[PATH_MAX]; (void) fprintf(stderr, gettext(MSG_VALSCRIPTS)); (void) snprintf(inst_path, sizeof (inst_path), "%s/install", pkgloc); checkscripts(inst_path, 0); } } quit(0); /*NOTREACHED*/ }