Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
/*
 * 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);
}
Example #4
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);
}
Example #5
0
/*
 * 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);
	}
}