static void rdcontents(void) { VFP_T *vfp; struct cfstat *dp; struct pinfo *pinfo; int n; if (vfpOpen(&vfp, contents, "r", VFP_NEEDNOW) != 0) { progerr(gettext("unable to open \"%s\" for reading"), contents); exit(1); } /* check the contents file to look for referenced packages */ while ((n = srchcfile(&entry, "*", vfp, (VFP_T *)NULL)) > 0) { for (pinfo = entry.pinfo; pinfo; pinfo = pinfo->next) { /* see if entry is used by indicated packaged */ if (pkgcnt && (selectp(pinfo->pkg) < 0)) continue; dp = fpkg(pinfo->pkg); pkgusage(dp, &entry); if (entry.npkgs > 1) dp->shared++; /* * Only objects specifically tagged with '!' event * character are considered "partial", everything * else is considered "installed" (even server * objects). */ switch (pinfo->status) { case '!' : dp->partial++; break; default : dp->installed++; break; } } } if (n < 0) { char *errstr = getErrstr(); progerr(gettext("bad entry read in contents file")); logerr(gettext("pathname: %s"), (entry.path && *entry.path) ? entry.path : "Unknown"); logerr(gettext("problem: %s"), (errstr && *errstr) ? errstr : "Unknown"); exit(1); } (void) vfpClose(&vfp); }
static void rdcontents(void) { struct cfstat *dp; struct pinfo *pinfo; int n; PKGserver server; if (!socfile(&server, B_TRUE) || pkgopenfilter(server, pkgcnt == 1 ? pkg[0] : NULL) != 0) exit(1); /* check the contents file to look for referenced packages */ while ((n = srchcfile(&entry, "*", server)) > 0) { for (pinfo = entry.pinfo; pinfo; pinfo = pinfo->next) { /* see if entry is used by indicated packaged */ if (pkgcnt && (selectp(pinfo->pkg) < 0)) continue; dp = fpkg(pinfo->pkg); pkgusage(dp, &entry); if (entry.npkgs > 1) dp->shared++; /* * Only objects specifically tagged with '!' event * character are considered "partial", everything * else is considered "installed" (even server * objects). */ switch (pinfo->status) { case '!' : dp->partial++; break; default : dp->installed++; break; } } } if (n < 0) { char *errstr = getErrstr(); progerr(gettext("bad entry read in contents file")); logerr(gettext("pathname: %s"), (entry.path && *entry.path) ? entry.path : "Unknown"); logerr(gettext("problem: %s"), (errstr && *errstr) ? errstr : "Unknown"); exit(1); } pkgcloseserver(server); }
/* * convert_contents_to_sql * * Converts the entire contents file into a set of SQL transactions which * populate the database. The reason that a single transaction is not used * is that some systems run out of memory in this case. * * Return: 0 on success, nonzero on failure */ int convert_contents_to_sql(struct dstr *pd, const char *pcroot) { VFP_T *vfp; char path[PATH_MAX]; int n; int total = 0; struct cfent entry; if (pcroot == NULL) { pcroot = "/"; } if (pcroot[strlen(pcroot) - 1] == '/') { if (snprintf(path, sizeof (path), "%svar/sadm/install/contents", pcroot) >= sizeof (path)) { return (1); } } else { if (snprintf(path, sizeof (path), "%s/var/sadm/install/contents", pcroot) >= sizeof (path)) { return (1); } } if (vfpOpen(&vfp, path, "r", VFP_NEEDNOW) != 0) { log_msg(LOG_MSG_ERR, MSG_FILE_ACCESS, path, strerror(errno)); return (1); } while ((n = srchcfile(&entry, "*", vfp, (VFP_T *)NULL)) > 0) { if (append_contents_sql(pd, &entry)) { (void) vfpClose(&vfp); return (1); } total++; } (void) vfpClose(&vfp); if (n < 0) { log_msg(LOG_MSG_ERR, MSG_CONTENTS_FORMAT); return (1); } return (0); }
/*ARGSUSED*/ int dofinal(VFP_T *vfp, VFP_T *vfpo, int rmflag, char *myclass, char *prog) { struct cfextra entry; int n, indx, dbchg; char *save_path = NULL; entry.cf_ent.pinfo = NULL; entry.fsys_value = BADFSYS; entry.fsys_base = BADFSYS; indx = 0; while (extlist && extlist[indx] && (extlist[indx]->cf_ent.ftype == 'i')) indx++; dbchg = 0; while (n = srchcfile(&(entry.cf_ent), "*", vfp, vfpo)) { if (n < 0) { char *errstr = getErrstr(); progerr(gettext ("bad entry read in contents file")); logerr(gettext("pathname=%s"), (entry.cf_ent.path && *(entry.cf_ent.path)) ? entry.cf_ent.path : "Unknown"); logerr(gettext("problem=%s"), (errstr && *errstr) ? errstr : "Unknown"); quit(99); } save_path = check_db_entry( vfpo, &entry, rmflag, myclass, &dbchg); /* Restore original server-relative path, if needed */ if (save_path != NULL) { entry.cf_ent.path = save_path; save_path = NULL; } } return (dbchg); }
/* * This is the function that cleans up the installation of this class. * This is where hard links get put in since the stuff they're linking * probably exists by now. */ static void endofclass(struct cfextra **extlist, int myclass, int ckflag, VFP_T **a_cfVfp, VFP_T **a_cfTmpVfp) { char *temppath; char *pspool_loc; char *relocpath = (char *)NULL; char scrpt_dst[PATH_MAX]; int flag; int idx; int n; struct cfent *ept; /* entry from the internal list */ struct cfextra entry; /* entry from the package database */ struct mergstat *mstat; /* merge status */ struct pinfo *pinfo; /* open the package database (contents) file */ if (!ocfile(a_cfVfp, a_cfTmpVfp, pkgmap_blks)) { quit(99); } echo(MSG_VERIFYING_CLASS, cl_nam(myclass)); for (idx = 0; /* void */; idx++) { /* find next package object in this class */ while (extlist[idx]) { if ((extlist[idx]->cf_ent.ftype != 'i') && extlist[idx]->cf_ent.pkg_class_idx == myclass) { break; } idx++; } if (extlist[idx] == NULL) { /* finish copying contents file and exit loop */ (void) srchcfile(&(entry.cf_ent), NULL, *a_cfVfp, *a_cfTmpVfp); break; } ept = &(extlist[idx]->cf_ent); mstat = &(extlist[idx]->mstat); temppath = extlist[idx] ? extlist[idx]->client_path : NULL; /* * At this point the only difference between the entry * in the contents file and the entry in extlist[] is * that the status indicator contains CONFIRM_CONT. * So for the new DB we use this knowledge and just * verify everything in accordance with extlist without * trying to retrieve the entry from the DB. */ n = srchcfile(&(entry.cf_ent), (ept ? temppath : NULL), *a_cfVfp, *a_cfTmpVfp); if (n == 0) { break; } else if (n < 0) { char *errstr = getErrstr(); progerr(ERR_CFBAD); logerr(gettext("pathname=%s\n"), entry.cf_ent.path && *entry.cf_ent.path ? entry.cf_ent.path : "Unknown"); logerr(gettext("problem=%s\n"), (errstr && *errstr) ? errstr : "Unknown"); quit(99); } else if (n != 1) { /* * Check if path should be in the package * database. */ if ((mstat->shared && nocnflct)) { continue; } progerr(ERR_CFMISSING, ept->path); quit(99); } /* * If merge was not appropriate for this object, now is the * time to choose one or the other. */ if (mstat->denied) { /* * If installation was denied AFTER the package * database was updated, skip this. We've already * announced the discrepancy and the verifications * that follow will make faulty decisions based on * the ftype, which may not be correct. */ progerr(ERR_COULD_NOT_INSTALL, ept->path); warnflag++; } else { if (mstat->replace) /* * This replaces the old entry with the new * one. This should never happen in the new * DB since the entries are already identical. */ repl_cfent(ept, &(entry.cf_ent)); /* * Validate this entry and change the status flag in * the package database. */ if (ept->ftype == RM_RDY) { (void) eptstat(&(entry.cf_ent), pkginst, STAT_NEXT); } else { /* check the hard link now. */ if (ept->ftype == 'l') { if (averify(0, &ept->ftype, ept->path, &ept->ainfo)) { echo(MSG_HRDLINK, ept->path); mstat->attrchg++; } } /* * Don't install or verify objects for * remote, read-only filesystems. We need * only flag them as shared from some server. * Otherwise, ok to do final check. */ if (is_remote_fs(ept->path, &(extlist[idx]->fsys_value)) && !is_fs_writeable(ept->path, &(extlist[idx]->fsys_value))) { flag = -1; } else { boolean_t inheritedFlag; inheritedFlag = z_path_is_inherited(ept->path, ept->ftype, get_inst_root()); flag = finalck(ept, mstat->attrchg, (ckflag ? mstat->contchg : (-1)), inheritedFlag); } pinfo = entry.cf_ent.pinfo; /* Find this package in the list. */ while (pinfo) { if (strcmp(pkginst, pinfo->pkg) == 0) { break; } pinfo = pinfo->next; } /* * If this package owns this file, then store * it in the database with the appropriate * status. Need to check pinfo in case it * points to NULL which could happen if * pinfo->next = NULL above. */ if (pinfo) { if (flag < 0 || is_served(ept->path, &(extlist[idx]->fsys_value))) { /* * This is provided to * clients by a server. */ pinfo->status = SERVED_FILE; } else { /* * It's either there or it's * not. */ pinfo->status = (flag ? NOT_FND : ENTRY_OK); } } } } /* * If not installing from a partially spooled package, the * "save/pspool" area, and the file contents can be * changed (type is 'e' or 'v'), and the class IS "none": * copy the installed volatile file into the appropriate * location in the packages destination "save/pspool" area. */ if ((!is_partial_inst()) && ((ept->ftype == 'e') || (ept->ftype == 'v')) && (strcmp(ept->pkg_class, "none") == 0)) { if (absolutepath(extlist[idx]->map_path) == B_TRUE && parametricpath(extlist[idx]->cf_ent.ainfo.local, &relocpath) == B_FALSE) { pspool_loc = ROOT; } else { pspool_loc = RELOC; } n = snprintf(scrpt_dst, PATH_MAX, "%s/%s/%s", saveSpoolInstallDir, pspool_loc, relocpath ? relocpath : extlist[idx]->map_path); if (n >= PATH_MAX) { progerr(ERR_CREATE_PATH_2, saveSpoolInstallDir, extlist[idx]->map_path); quit(99); } /* copy, preserve source file mode */ if (cppath(MODE_SRC, ept->path, scrpt_dst, 0644)) { warnflag++; } } /* * Now insert this potentially changed package database * entry. */ if (entry.cf_ent.npkgs) { if (putcvfpfile(&(entry.cf_ent), *a_cfTmpVfp)) { quit(99); } } } n = swapcfile(a_cfVfp, a_cfTmpVfp, pkginst, dbchg); if (n == RESULT_WRN) { warnflag++; } else if (n == RESULT_ERR) { quit(99); } }