コード例 #1
0
ファイル: order.c プロジェクト: 41px/pkgin
/**
 * \fn order_install
 *
 * order the install list according to dependency level
 * here we only rely on basic level given by pkg_summary, the only drawback
 * is that pkg_add will install direct dependencies, giving a "failed,
 * package already installed"
 */
Plisthead *
order_install(Plisthead *impacthead)
{
	Plisthead	*ordtreehead;
	Pkglist		*pimpact, *pdp, *pi_dp = NULL;
	int			i, maxlevel = 0;
	char		tmpcheck[BUFSIZ];

	/* record higher dependency level on impact list */
	SLIST_FOREACH(pimpact, impacthead, next) {
		if ((pimpact->action == TOUPGRADE ||
			pimpact->action == TOINSTALL) &&
			pimpact->level > maxlevel)
			maxlevel = pimpact->level;
	}

	ordtreehead = init_head();

	for (i = 0; i <= maxlevel; i++) {
		SLIST_FOREACH(pimpact, impacthead, next) {
			if ((pimpact->action == TOUPGRADE ||
				pimpact->action == TOINSTALL) &&
				pimpact->level == i) {

				if (pkg_in_impact(ordtreehead, pimpact->full))
					continue;

				pdp = malloc_pkglist(DEPTREE);

				pdp->computed = pimpact->action; /* XXX: ugly*/
				XSTRDUP(pdp->depend, pimpact->full);
				pdp->name = NULL; /* safety */
				pdp->level = pimpact->level;
				/* record package size for download check */
				pdp->file_size = pimpact->file_size;

				/* check for pkg_install upgrade */
				strcpy(tmpcheck, pimpact->full);
				trunc_str(tmpcheck, '-', STR_BACKWARD);
				/* match on pkg_install */
				if (strcmp(tmpcheck, PKG_INSTALL) == 0) {
					pi_upgrade = 1;
					/* backup pdp for future insertion */
					pi_dp = pdp;
				} else					
					SLIST_INSERT_HEAD(ordtreehead,
						pdp, next);
			} /* action == TOINSTALL */
		} /* SLIST_FOREACH pimpact */
	} /* for i < maxlevel */

	/* pkg_install is to be upgraded, make it first */
	if (pi_upgrade && pi_dp != NULL)
		SLIST_INSERT_HEAD(ordtreehead, pi_dp, next);

	return ordtreehead;
}
コード例 #2
0
ファイル: sqlite_callbacks.c プロジェクト: 41px/pkgin
/**
 * sqlite callback
 * DIRECT_DEPS or REVERSE_DEPS result, feeds a Pkglist SLIST
 * Plisthead is the head of Pkglist
 */
int
pdb_rec_depends(void *param, int argc, char **argv, char **colname)
{
	Pkglist		*deptree, *pdp, *pkg_map;
	Plisthead	*pdphead = (Plisthead *)param, *plisthead;

	if (argv == NULL)
		return PDB_ERR;

	/* check if dependency is already recorded, do not insert on list  */
	SLIST_FOREACH(pdp, pdphead, next)
		if (strcmp(DEPS_PKGNAME, pdp->name) == 0) {
			TRACE(" < dependency %s already recorded\n", pdp->name);
			/* proceed to next result */
			return PDB_OK;
		}

	deptree = malloc_pkglist(DEPTREE);
	XSTRDUP(deptree->depend, DEPS_FULLPKG);

	/* unresolved pkgname because of complex dependency glob */
	if (non_trivial_glob(DEPS_FULLPKG)) {
		/* check wether we're getting local or remote dependencies */
		if (strncmp(colname[0], "LOCAL_", 6) == 0)
			plisthead = &l_plisthead;
		else
			plisthead = &r_plisthead;

		/* map corresponding pkgname */
		if ((pkg_map = map_pkg_to_dep(plisthead, deptree->depend)) != NULL)
			XSTRDUP(deptree->name, pkg_map->name);
		else
			/* some dependencies just don't match anything */
			XSTRDUP(deptree->name, DEPS_PKGNAME);
	} else
		/* case handled by get_pkgname_from_depend() */
		XSTRDUP(deptree->name, DEPS_PKGNAME);

	deptree->computed = 0;
	deptree->level = 0;
	/* used in LOCAL_REVERSE_DEPS / autoremove.c */
	if (argc > 2 && PKG_KEEP != NULL)
		deptree->keep = 1;
	else
		deptree->keep = 0;

	SLIST_INSERT_HEAD(pdphead, deptree, next);

	return PDB_OK;
}
コード例 #3
0
ファイル: sqlite_callbacks.c プロジェクト: 41px/pkgin
/** 
 * SQLite callback, record package list
 */
int
pdb_rec_list(void *param, int argc, char **argv, char **colname)
{
	Pkglist	   	*plist;
	Plistnumbered	*plisthead = (Plistnumbered *)param;
	int			i;

	if (argv == NULL)
		return PDB_ERR;

	/* FULLPKGNAME was empty, probably a package installed
	 * from pkgsrc or wip that does not exist in
	 * pkg_summary(5), return
	 */
	if (argv[0] == NULL)
		return PDB_ERR;

	plist = malloc_pkglist(LIST);

	/*
	 * rec_pkglist is used for convenience for REQUIRES / PROVIDES
	 * otherwise contains FULLPKGNAME
	 */
	XSTRDUP(plist->full, argv[0]);

	for (i = 1; i < argc; i++) {
		if (argv[i] == NULL)
			continue;

		if (strcmp(colname[i], "PKGNAME") == 0)
			XSTRDUP(plist->name, argv[i]);
		if (strcmp(colname[i], "PKGVERS") == 0)
			XSTRDUP(plist->version, argv[i]);
		if (strcmp(colname[i], "COMMENT") == 0)
			XSTRDUP(plist->comment, argv[i]);
		if (strcmp(colname[i], "PKGPATH") == 0)
			XSTRDUP(plist->pkgpath, argv[i]);
		if (strcmp(colname[i], "CATEGORIES") == 0)
			XSTRDUP(plist->category, argv[i]);
		if (strcmp(colname[i], "FILE_SIZE") == 0)
			plist->file_size = strtol(argv[i], (char **)NULL, 10);
		if (strcmp(colname[i], "SIZE_PKG") == 0)
			plist->size_pkg = strtol(argv[i], (char **)NULL, 10);
	}

	SLIST_INSERT_HEAD(plisthead->P_Plisthead, plist, next);
	plisthead->P_count++;

	return PDB_OK;
}
コード例 #4
0
ファイル: order.c プロジェクト: 41px/pkgin
/**
 * \fn order_upgrade_remove
 *
 * \brief order the remove-for-upgrade list according to dependency level
 */
Plisthead *
order_upgrade_remove(Plisthead *impacthead)
{
	Plisthead	*ordtreehead;
	Pkglist		*pimpact, *pdp;
	int		i, maxlevel = 0;

	upgrade_dep_deepness(impacthead);

	/* record higher dependency level on impact upgrade list */
	SLIST_FOREACH(pimpact, impacthead, next)
		if ((pimpact->action == TOUPGRADE ||
			pimpact->action == TOREMOVE) &&
			pimpact->level > maxlevel)

			maxlevel = pimpact->level;

	ordtreehead = init_head();

	for (i = maxlevel; i >= 0; i--)
		SLIST_FOREACH(pimpact, impacthead, next) {
			if ((pimpact->action == TOUPGRADE ||
				pimpact->action == TOREMOVE) &&
				pimpact->level == i) {

				if (pkg_in_impact(ordtreehead, pimpact->old))
					continue;

				pdp = malloc_pkglist(DEPTREE);

				XSTRDUP(pdp->depend, pimpact->old);
				pdp->name = NULL; /* safety */
				/* XXX: use the "computed" value to record
				 * action type. Ugly.
				 */
				pdp->computed = pimpact->action;
				/* informative only */
				pdp->level = pimpact->level;
				SLIST_INSERT_HEAD(ordtreehead, pdp, next);

			} /* action == TOUPGRADE || TOREMOVE */
		} /* for maxlevel */

	return ordtreehead;
}
コード例 #5
0
ファイル: impact.c プロジェクト: jacques/pkgin
static void
break_depends(Plisthead *impacthead)
{
	Pkglist	   	*rmimpact, *pimpact;
	Plisthead	*rdphead, *fdphead;
	Pkglist	   	*rdp, *fdp;
	char		*pkgname, *rpkg;
	int			dep_break, exists;

	SLIST_FOREACH(pimpact, impacthead, next) {

		if (pimpact->old == NULL) /* DONOTHING or TOINSTALL  */
			continue;

		rdphead = init_head();

		XSTRDUP(pkgname, pimpact->old);
		trunc_str(pkgname, '-', STR_BACKWARD);

		/* fetch old package reverse dependencies */
		full_dep_tree(pkgname, LOCAL_REVERSE_DEPS, rdphead);

		XFREE(pkgname);

		/* browse reverse dependencies */
		SLIST_FOREACH(rdp, rdphead, next) {

			exists = 0;
			/* check if rdp was already on impact list */
			SLIST_FOREACH(rmimpact, impacthead, next)
				if (strcmp(rmimpact->depend, rdp->depend) == 0) {
					exists = 1;
					break;
				}
			if (exists)
				continue;

			fdphead = init_head();

			/*
			 * reverse dependency is a full package name,
			 * use it and strip it
			 */
			XSTRDUP(rpkg, rdp->depend);
			trunc_str(rpkg, '-', STR_BACKWARD);

			/* fetch dependencies for rdp */
			full_dep_tree(rpkg, DIRECT_DEPS, fdphead);

			/* initialize to broken dependency */
			dep_break = 1;

			/* empty full dep tree, this can't happen in normal situation.
			 * If it does, that means that the reverse dependency we're
			 * analyzing has no direct dependency.
			 * Such a situation could occur if the reverse dependency is not on
			 * the repository anymore, leading to no information regarding this
			 * package.
			 * So we will check if local package dependencies are satisfied by
			 * our newly upgraded packages.
			 */
			if (SLIST_EMPTY(fdphead)) {
				free_pkglist(&fdphead, DEPTREE);
				fdphead = init_head();
				full_dep_tree(rpkg, LOCAL_DIRECT_DEPS, fdphead);
			}
			XFREE(rpkg);

			/*
			 * browse dependencies for rdp and see if
			 * new package to be installed matches
			 */
			SLIST_FOREACH(fdp, fdphead, next) {
				if (pkg_match(fdp->depend, pimpact->full)) {
					dep_break = 0;
					break;
				}
			}

			free_pkglist(&fdphead, DEPTREE);

			if (!dep_break)
				continue;

			/* dependency break, insert rdp in remove-list */
			rmimpact = malloc_pkglist(IMPACT);
			XSTRDUP(rmimpact->depend, rdp->depend);
			XSTRDUP(rmimpact->full, rdp->depend);
			XSTRDUP(rmimpact->old, rdp->depend);
			rmimpact->action = TOREMOVE;
			rmimpact->level = 0;

			SLIST_INSERT_HEAD(impacthead, rmimpact, next);
		}
		free_pkglist(&rdphead, DEPTREE);
	}