From 6dd2ecf4fa19346193e4ea69419c1b1004fb66e8 Mon Sep 17 00:00:00 2001 From: Aurelien Foret Date: Sun, 15 Jan 2006 15:55:16 +0000 Subject: pulled out conflict checkings from checkdeps() in its own function: checkconflicts() --- lib/libalpm/deps.c | 334 ++++++++++++++++------------------------------------- 1 file changed, 102 insertions(+), 232 deletions(-) (limited to 'lib/libalpm/deps.c') diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index d60b4778..ff6fc505 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -37,6 +37,25 @@ extern pmhandle_t *handle; +static pmdepmissing_t *depmissing_new(const char *target, unsigned char type, unsigned char depmod, + const char *depname, const char *depversion) +{ + pmdepmissing_t *miss; + + miss = (pmdepmissing_t *)malloc(sizeof(pmdepmissing_t)); + if(miss == NULL) { + return(NULL); + } + + STRNCPY(miss->target, target, PKG_NAME_LEN); + miss->type = type; + miss->depend.mod = depmod; + STRNCPY(miss->depend.name, depname, PKG_NAME_LEN); + STRNCPY(miss->depend.version, depversion, PKG_VERSION_LEN); + + return(miss); +} + /* Re-order a list of target packages with respect to their dependencies. * * Example (PM_TRANS_TYPE_ADD): @@ -121,13 +140,11 @@ PMList *sortbydeps(PMList *targets, int mode) /* Returns a PMList* of missing_t pointers. * - * conflicts are always name only, but dependencies can include versions - * with depmod operators. + * dependencies can include versions with depmod operators. * */ PMList *checkdeps(pmdb_t *db, unsigned char op, PMList *packages) { - pmpkg_t *info = NULL; pmdepend_t depend; PMList *i, *j, *k; int cmp; @@ -218,158 +235,13 @@ PMList *checkdeps(pmdb_t *db, unsigned char op, PMList *packages) } } if(op == PM_TRANS_TYPE_ADD || op == PM_TRANS_TYPE_UPGRADE) { + /* DEPENDENCIES -- look for unsatisfied dependencies */ for(i = packages; i; i = i->next) { pmpkg_t *tp = i->data; if(tp == NULL) { continue; } - /* CONFLICTS */ - for(j = tp->conflicts; j; j = j->next) { - if(!strcmp(tp->name, j->data)) { - /* a package cannot conflict with itself -- that's just not nice */ - continue; - } - /* CHECK 1: check targets against database */ - for(k = db_get_pkgcache(db); k; k = k->next) { - pmpkg_t *dp = (pmpkg_t *)k->data; - if(!strcmp(dp->name, tp->name)) { - /* a package cannot conflict with itself -- that's just not nice */ - continue; - } - if(!strcmp(j->data, dp->name)) { - /* conflict */ - MALLOC(miss, sizeof(pmdepmissing_t)); - miss->type = PM_DEP_TYPE_CONFLICT; - miss->depend.mod = PM_DEP_MOD_ANY; - miss->depend.version[0] = '\0'; - STRNCPY(miss->target, tp->name, PKG_NAME_LEN); - STRNCPY(miss->depend.name, dp->name, PKG_NAME_LEN); - if(!pm_list_is_in(miss, baddeps)) { - _alpm_log(PM_LOG_FLOW2, "checkdeps: targs vs db: adding %s as a conflict for %s", - dp->name, tp->name); - baddeps = pm_list_add(baddeps, miss); - } else { - FREE(miss); - } - } else { - /* see if dp provides something in tp's conflict list */ - PMList *m; - for(m = dp->provides; m; m = m->next) { - if(!strcmp(m->data, j->data)) { - /* confict */ - MALLOC(miss, sizeof(pmdepmissing_t)); - miss->type = PM_DEP_TYPE_CONFLICT; - miss->depend.mod = PM_DEP_MOD_ANY; - miss->depend.version[0] = '\0'; - STRNCPY(miss->target, tp->name, PKG_NAME_LEN); - STRNCPY(miss->depend.name, dp->name, PKG_NAME_LEN); - if(!pm_list_is_in(miss, baddeps)) { - _alpm_log(PM_LOG_FLOW2, "checkdeps: targs vs db: adding %s as a conflict for %s", - dp->name, tp->name); - baddeps = pm_list_add(baddeps, miss); - } else { - FREE(miss); - } - } - } - } - } - /* CHECK 2: check targets against targets */ - for(k = packages; k; k = k->next) { - pmpkg_t *otp = (pmpkg_t *)k->data; - if(!strcmp(otp->name, tp->name)) { - /* a package cannot conflict with itself -- that's just not nice */ - continue; - } - if(!strcmp(otp->name, (char *)j->data)) { - /* otp is listed in tp's conflict list */ - MALLOC(miss, sizeof(pmdepmissing_t)); - miss->type = PM_DEP_TYPE_CONFLICT; - miss->depend.mod = PM_DEP_MOD_ANY; - miss->depend.version[0] = '\0'; - STRNCPY(miss->target, tp->name, PKG_NAME_LEN); - STRNCPY(miss->depend.name, otp->name, PKG_NAME_LEN); - if(!pm_list_is_in(miss, baddeps)) { - _alpm_log(PM_LOG_FLOW2, "checkdeps: targs vs targs: adding %s as a conflict for %s", - otp->name, tp->name); - baddeps = pm_list_add(baddeps, miss); - } else { - FREE(miss); - } - } else { - /* see if otp provides something in tp's conflict list */ - PMList *m; - for(m = otp->provides; m; m = m->next) { - if(!strcmp(m->data, j->data)) { - MALLOC(miss, sizeof(pmdepmissing_t)); - miss->type = PM_DEP_TYPE_CONFLICT; - miss->depend.mod = PM_DEP_MOD_ANY; - miss->depend.version[0] = '\0'; - STRNCPY(miss->target, tp->name, PKG_NAME_LEN); - STRNCPY(miss->depend.name, otp->name, PKG_NAME_LEN); - if(!pm_list_is_in(miss, baddeps)) { - _alpm_log(PM_LOG_FLOW2, "checkdeps: targs vs targs: adding %s as a conflict for %s", - otp->name, tp->name); - baddeps = pm_list_add(baddeps, miss); - } else { - FREE(miss); - } - } - } - } - } - } - /* CHECK 3: check database against targets */ - for(k = db_get_pkgcache(db); k; k = k->next) { - info = k->data; - if(!strcmp(info->name, tp->name)) { - /* a package cannot conflict with itself -- that's just not nice */ - continue; - } - for(j = info->conflicts; j; j = j->next) { - if(!strcmp((char *)j->data, tp->name)) { - MALLOC(miss, sizeof(pmdepmissing_t)); - miss->type = PM_DEP_TYPE_CONFLICT; - miss->depend.mod = PM_DEP_MOD_ANY; - miss->depend.version[0] = '\0'; - STRNCPY(miss->target, tp->name, PKG_NAME_LEN); - STRNCPY(miss->depend.name, info->name, PKG_NAME_LEN); - if(!pm_list_is_in(miss, baddeps)) { - _alpm_log(PM_LOG_FLOW2, "checkdeps: db vs targs: adding %s as a conflict for %s", - info->name, tp->name); - baddeps = pm_list_add(baddeps, miss); - } else { - FREE(miss); - } - } else { - /* see if the db package conflicts with something we provide */ - PMList *m; - for(m = info->conflicts; m; m = m->next) { - PMList *n; - for(n = tp->provides; n; n = n->next) { - if(!strcmp(m->data, n->data)) { - MALLOC(miss, sizeof(pmdepmissing_t)); - miss->type = PM_DEP_TYPE_CONFLICT; - miss->depend.mod = PM_DEP_MOD_ANY; - miss->depend.version[0] = '\0'; - STRNCPY(miss->target, tp->name, PKG_NAME_LEN); - STRNCPY(miss->depend.name, info->name, PKG_NAME_LEN); - if(!pm_list_is_in(miss, baddeps)) { - _alpm_log(PM_LOG_FLOW2, "checkdeps: db vs targs: adding %s as a conflict for %s", - info->name, tp->name); - baddeps = pm_list_add(baddeps, miss); - } else { - FREE(miss); - } - } - } - } - } - } - } - - /* DEPENDENCIES -- look for unsatisfied dependencies */ for(j = tp->depends; j; j = j->next) { /* split into name/version pairs */ splitdep((char *)j->data, &depend); @@ -650,6 +522,8 @@ int resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList *list, for(i = deps; i; i = i->next) { int found = 0; pmdepmissing_t *miss = i->data; + pmpkg_t *sync = NULL; + int provisio_match = 0; /* XXX: conflicts are now treated specially in the _add and _sync functions */ @@ -658,106 +532,102 @@ int resolvedeps(pmdb_t *local, PMList *dbs_sync, pmpkg_t *syncpkg, PMList *list, RET_ERR(???, -1); } else*/ - if(miss->type == PM_DEP_TYPE_DEPEND) { - pmpkg_t *sync = NULL; - int provisio_match = 0; - - /* check if one of the packages in *list already provides this dependency */ - for(j = list; j; j = j->next) { - pmpkg_t *sp = (pmpkg_t*)j->data; - for(k = sp->provides; k; k = k->next) { - if(!strcmp(miss->depend.name, k->data)) { - _alpm_log(PM_LOG_DEBUG, "%s provides dependency %s -- skipping", sp->name, miss->depend.name); - provisio_match = 1; - } + + /* check if one of the packages in *list already provides this dependency */ + for(j = list; j; j = j->next) { + pmpkg_t *sp = (pmpkg_t*)j->data; + for(k = sp->provides; k; k = k->next) { + if(!strcmp(miss->depend.name, k->data)) { + _alpm_log(PM_LOG_DEBUG, "%s provides dependency %s -- skipping", sp->name, miss->depend.name); + provisio_match = 1; } } - if(provisio_match) { - continue; - } + } + if(provisio_match) { + continue; + } - /* find the package in one of the repositories */ - /* check literals */ - for(j = dbs_sync; !sync && j; j = j->next) { - PMList *k; - pmdb_t *dbs = j->data; - for(k = db_get_pkgcache(dbs); !sync && k; k = k->next) { - pmpkg_t *pkg = k->data; - if(!strcmp(miss->depend.name, pkg->name)) { - sync = pkg; - } + /* find the package in one of the repositories */ + /* check literals */ + for(j = dbs_sync; !sync && j; j = j->next) { + PMList *k; + pmdb_t *dbs = j->data; + for(k = db_get_pkgcache(dbs); !sync && k; k = k->next) { + pmpkg_t *pkg = k->data; + if(!strcmp(miss->depend.name, pkg->name)) { + sync = pkg; } } - /* check provides */ - for(j = dbs_sync; !sync && j; j = j->next) { - PMList *provides; - pmdb_t *dbs = j->data; - provides = _alpm_db_whatprovides(dbs, miss->depend.name); - if(provides) { - sync = provides->data; - } - FREELISTPTR(provides); + } + /* check provides */ + for(j = dbs_sync; !sync && j; j = j->next) { + PMList *provides; + pmdb_t *dbs = j->data; + provides = _alpm_db_whatprovides(dbs, miss->depend.name); + if(provides) { + sync = provides->data; } - if(sync == NULL) { - _alpm_log(PM_LOG_ERROR, "cannot resolve dependencies for \"%s\" (\"%s\" is not in the package set)", - miss->target, miss->depend.name); - pm_errno = PM_ERR_UNRESOLVABLE_DEPS; - goto error; + FREELISTPTR(provides); + } + if(sync == NULL) { + _alpm_log(PM_LOG_ERROR, "cannot resolve dependencies for \"%s\" (\"%s\" is not in the package set)", + miss->target, miss->depend.name); + pm_errno = PM_ERR_UNRESOLVABLE_DEPS; + goto error; + } + found = 0; + for(j = list; j && !found; j = j->next) { + pmpkg_t *tmp = j->data; + if(tmp && !strcmp(tmp->name, sync->name)) { + _alpm_log(PM_LOG_DEBUG, "dependency %s is already in the target list - skipping", + sync->name); + found = 1; + } + } + if(found) { + /* this dep is already in the target list */ + continue; + } + + found = 0; + for(j = trail; j; j = j->next) { + pmpkg_t *tmp = j->data; + if(tmp && !strcmp(tmp->name, sync->name)) { + found = 1; } + } + if(!found) { + /* check pmo_ignorepkg and pmo_s_ignore to make sure we haven't pulled in + * something we're not supposed to. + */ + int usedep = 1; found = 0; - for(j = list; j && !found; j = j->next) { - pmpkg_t *tmp = j->data; - if(tmp && !strcmp(tmp->name, sync->name)) { - _alpm_log(PM_LOG_DEBUG, "dependency %s is already in the target list - skipping", - sync->name); + for(j = handle->ignorepkg; j && !found; j = j->next) { + if(!strcmp(j->data, sync->name)) { found = 1; } } if(found) { - /* this dep is already in the target list */ - continue; - } - - found = 0; - for(j = trail; j; j = j->next) { - pmpkg_t *tmp = j->data; - if(tmp && !strcmp(tmp->name, sync->name)) { - found = 1; - } + pmpkg_t *dummypkg = pkg_new(miss->target, NULL); + QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, dummypkg, sync, NULL, &usedep); + FREEPKG(dummypkg); } - if(!found) { - /* check pmo_ignorepkg and pmo_s_ignore to make sure we haven't pulled in - * something we're not supposed to. - */ - int usedep = 1; - found = 0; - for(j = handle->ignorepkg; j && !found; j = j->next) { - if(!strcmp(j->data, sync->name)) { - found = 1; - } - } - if(found) { - pmpkg_t *dummypkg = pkg_new(miss->target, NULL); - QUESTION(trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, dummypkg, sync, NULL, &usedep); - FREEPKG(dummypkg); - } - if(usedep) { - trail = pm_list_add(trail, sync); - if(resolvedeps(local, dbs_sync, sync, list, trail, trans)) { - goto error; - } - _alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)", - sync->name, syncpkg->name); - list = pm_list_add(list, sync); - } else { - _alpm_log(PM_LOG_ERROR, "cannot resolve dependencies for \"%s\"", miss->target); - pm_errno = PM_ERR_UNRESOLVABLE_DEPS; + if(usedep) { + trail = pm_list_add(trail, sync); + if(resolvedeps(local, dbs_sync, sync, list, trail, trans)) { goto error; } + _alpm_log(PM_LOG_DEBUG, "pulling dependency %s (needed by %s)", + sync->name, syncpkg->name); + list = pm_list_add(list, sync); } else { - /* cycle detected -- skip it */ - _alpm_log(PM_LOG_DEBUG, "dependency cycle detected: %s", sync->name); + _alpm_log(PM_LOG_ERROR, "cannot resolve dependencies for \"%s\"", miss->target); + pm_errno = PM_ERR_UNRESOLVABLE_DEPS; + goto error; } + } else { + /* cycle detected -- skip it */ + _alpm_log(PM_LOG_DEBUG, "dependency cycle detected: %s", sync->name); } } -- cgit v1.2.3-54-g00ecf