summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Woodward2010-06-09 19:52:13 -0400
committerJason Woodward2010-06-09 19:52:13 -0400
commit9a371df4c02189cd1fabc1e2576162e75e43f756 (patch)
tree427d367b9446e506ead2af4a54377d648d0c9321
parent33eb4afdaaae102ce44232d28c227ba98318d5d3 (diff)
downloadslapt-get-9a371df4c02189cd1fabc1e2576162e75e43f756.tar.gz
updated slapt_is_required_by
make slapt_is_required_by properly account for alternative/conditional dependencies as well as be aware of what is to be installed and removed.
-rw-r--r--ChangeLog2
-rw-r--r--doc/libslapt.33
-rw-r--r--src/action.c5
-rw-r--r--src/package.c77
-rw-r--r--src/package.h4
-rw-r--r--src/transaction.c2
6 files changed, 85 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index b5b06ff..8cb5216 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
0.10.2f June 09, 2010
+ * make slapt_is_required_by properly account for alternative/conditional
+ dependencies as well as be aware of what is to be installed and removed.
* Updated API, generalizing several types into slapt_list_t
* added reinstall notification
diff --git a/doc/libslapt.3 b/doc/libslapt.3
index cb389f9..1e85485 100644
--- a/doc/libslapt.3
+++ b/doc/libslapt.3
@@ -292,6 +292,9 @@ The following functions deal with determining package dependencies and conflicts
.B "struct slapt_pkg_list *"
.B "slapt_is_required_by(const slapt_rc_config *global_config,
.B " struct slapt_pkg_list *avail,
+.B " struct slapt_pkg_list *installed_pkgs,
+.B " struct slapt_pkg_list *pkgs_to_install,
+.B " struct slapt_pkg_list *pkgs_to_remove,
.B " slapt_pkg_info_t *pkg);"
.sp
.fi
diff --git a/src/action.c b/src/action.c
index 2a7ad07..5f3a1ef 100644
--- a/src/action.c
+++ b/src/action.c
@@ -278,7 +278,10 @@ void slapt_pkg_action_remove(const slapt_rc_config *global_config,
}
- deps = slapt_is_required_by(global_config,avail_pkgs,pkg);
+ deps = slapt_is_required_by(global_config,
+ avail_pkgs, installed_pkgs,
+ tran->install_pkgs, tran->remove_pkgs,
+ pkg);
for (c = 0; c < deps->pkg_count; ++c) {
slapt_pkg_info_t *dep = deps->pkgs[c];
diff --git a/src/package.c b/src/package.c
index 48cd57a..53a5112 100644
--- a/src/package.c
+++ b/src/package.c
@@ -32,7 +32,11 @@ static slapt_pkg_info_t *parse_meta_entry(struct slapt_pkg_list *avail_pkgs,
struct slapt_pkg_list *installed_pkgs,
char *dep_entry);
/* called by slapt_is_required_by */
-static void required_by(struct slapt_pkg_list *avail, slapt_pkg_info_t *pkg,
+static void required_by(struct slapt_pkg_list *avail,
+ struct slapt_pkg_list *installed_pkgs,
+ struct slapt_pkg_list *pkgs_to_install,
+ struct slapt_pkg_list *pkgs_to_remove,
+ slapt_pkg_info_t *pkg,
struct slapt_pkg_list *required_by_list);
static char *escape_package_name(slapt_pkg_info_t *pkg);
/* free pkg_version_parts struct */
@@ -1692,6 +1696,9 @@ static slapt_pkg_info_t *parse_meta_entry(struct slapt_pkg_list *avail_pkgs,
struct slapt_pkg_list *slapt_is_required_by(const slapt_rc_config *global_config,
struct slapt_pkg_list *avail,
+ struct slapt_pkg_list *installed_pkgs,
+ struct slapt_pkg_list *pkgs_to_install,
+ struct slapt_pkg_list *pkgs_to_remove,
slapt_pkg_info_t *pkg)
{
struct slapt_pkg_list *required_by_list = slapt_init_pkg_list();
@@ -1702,7 +1709,7 @@ struct slapt_pkg_list *slapt_is_required_by(const slapt_rc_config *global_config
if (global_config->disable_dep_check == SLAPT_TRUE)
return required_by_list;
- required_by(avail,pkg,required_by_list);
+ required_by(avail,installed_pkgs,pkgs_to_install,pkgs_to_remove,pkg,required_by_list);
return required_by_list;
}
@@ -1738,6 +1745,9 @@ static char *escape_package_name(slapt_pkg_info_t *pkg)
}
static void required_by(struct slapt_pkg_list *avail,
+ struct slapt_pkg_list *installed_pkgs,
+ struct slapt_pkg_list *pkgs_to_install,
+ struct slapt_pkg_list *pkgs_to_remove,
slapt_pkg_info_t *pkg,
struct slapt_pkg_list *required_by_list)
{
@@ -1764,6 +1774,8 @@ static void required_by(struct slapt_pkg_list *avail,
for (i = 0; i < avail->pkg_count;i++) {
slapt_pkg_info_t *pkg_ptr = avail->pkgs[i];
+ slapt_list_t *dep_list = NULL;
+ unsigned int d = 0;
if (strcmp(pkg_ptr->required,"") == 0 )
continue;
@@ -1778,10 +1790,59 @@ static void required_by(struct slapt_pkg_list *avail,
if (required_by_reg->reg_return != 0 )
continue;
- if (slapt_get_exact_pkg(required_by_list, pkg_ptr->name, pkg_ptr->version) == NULL) {
- slapt_add_pkg_to_pkg_list(required_by_list,pkg_ptr);
- required_by(avail, pkg_ptr, required_by_list );
+ /* check for the offending dependency entry and see if we have an alternative */
+ dep_list = slapt_parse_delimited_list(pkg_ptr->required,',');
+ for (d = 0; d < dep_list->count; d++) {
+ slapt_list_t *satisfies = NULL;
+ unsigned int s = 0;
+ SLAPT_BOOL_T has_alternative = SLAPT_FALSE;
+
+ /* found our package in the list of dependencies */
+ if (strstr(dep_list->items[d], pkg->name) == NULL)
+ continue;
+
+ /* not an |or, just add it */
+ if (strchr(dep_list->items[d],'|') == NULL) {
+ if (slapt_get_exact_pkg(required_by_list, pkg_ptr->name, pkg_ptr->version) == NULL) {
+ slapt_add_pkg_to_pkg_list(required_by_list,pkg_ptr);
+ required_by(avail,installed_pkgs,pkgs_to_install,pkgs_to_remove, pkg_ptr, required_by_list );
+ }
+ break;
+ }
+
+ /* we need to find out if we have something else that satisfies the dependency */
+ satisfies = slapt_parse_delimited_list(dep_list->items[d],'|');
+ for (s = 0; s < satisfies->count; s++) {
+ slapt_pkg_info_t *tmp_pkg = parse_meta_entry(avail,installed_pkgs,satisfies->items[s]);
+
+ if (tmp_pkg != NULL) {
+ if (strcmp(tmp_pkg->name,pkg->name) == 0)
+ continue;
+
+ if (slapt_get_exact_pkg(installed_pkgs,tmp_pkg->name, tmp_pkg->version) != NULL) {
+ if (slapt_get_exact_pkg(pkgs_to_remove,tmp_pkg->name, tmp_pkg->version) == NULL) {
+ has_alternative = SLAPT_TRUE;
+ break;
+ }
+ } else if (slapt_get_exact_pkg(pkgs_to_install, tmp_pkg->name, tmp_pkg->version) != NULL) {
+ has_alternative = SLAPT_TRUE;
+ break;
+ }
+ }
+ }
+ slapt_free_list(satisfies);
+
+ /* we couldn't find an installed pkg that satisfies the |or */
+ if (has_alternative == SLAPT_FALSE) {
+ if (slapt_get_exact_pkg(required_by_list, pkg_ptr->name, pkg_ptr->version) == NULL) {
+ slapt_add_pkg_to_pkg_list(required_by_list,pkg_ptr);
+ required_by(avail,installed_pkgs,pkgs_to_install,pkgs_to_remove, pkg_ptr, required_by_list );
+ }
+ }
+
}
+ slapt_free_list(dep_list);
+
}
@@ -3282,6 +3343,8 @@ struct slapt_pkg_list *
{
unsigned int r;
struct slapt_pkg_list *obsolete = slapt_init_pkg_list();
+ struct slapt_pkg_list *to_install = slapt_init_pkg_list();
+ struct slapt_pkg_list *to_remove = slapt_init_pkg_list();
for (r = 0; r < installed_pkgs->pkg_count; ++r) {
slapt_pkg_info_t *p = installed_pkgs->pkgs[r];
@@ -3298,7 +3361,7 @@ struct slapt_pkg_list *
any packages that require this package we are about to remove
should be scheduled to remove as well
*/
- deps = slapt_is_required_by(global_config,avail_pkgs, p);
+ deps = slapt_is_required_by(global_config,avail_pkgs,installed_pkgs,to_install,to_remove,p);
for (c = 0; c < deps->pkg_count; ++c ) {
slapt_pkg_info_t *dep = deps->pkgs[c];
@@ -3318,6 +3381,8 @@ struct slapt_pkg_list *
}
+ slapt_free_pkg_list(to_install);
+ slapt_free_pkg_list(to_remove);
return obsolete;
}
diff --git a/src/package.h b/src/package.h
index a0fb2b0..fa39f6d 100644
--- a/src/package.h
+++ b/src/package.h
@@ -231,6 +231,9 @@ struct slapt_pkg_list *slapt_get_pkg_conflicts(struct slapt_pkg_list *avail_pkgs
*/
struct slapt_pkg_list *slapt_is_required_by(const slapt_rc_config *global_config,
struct slapt_pkg_list *avail,
+ struct slapt_pkg_list *installed_pkgs,
+ struct slapt_pkg_list *pkgs_to_install,
+ struct slapt_pkg_list *pkgs_to_remove,
slapt_pkg_info_t *pkg);
/*
@@ -297,3 +300,4 @@ char *slapt_get_pkg_filelist(const slapt_pkg_info_t *pkg);
caller responsible for freeing the returned data
*/
char *slapt_gen_package_log_dir_name(void);
+
diff --git a/src/transaction.c b/src/transaction.c
index 1115690..e9b1d8b 100644
--- a/src/transaction.c
+++ b/src/transaction.c
@@ -530,7 +530,7 @@ void slapt_add_remove_to_transaction(slapt_transaction_t *tran,
tmp_list = realloc(
tran->remove_pkgs->pkgs,
sizeof *tran->remove_pkgs->pkgs * (tran->remove_pkgs->pkg_count + 1)
- );
+ );
if (tmp_list != NULL) {
tran->remove_pkgs->pkgs = tmp_list;