diff options
Diffstat (limited to 'lib/libalpm/conflict.c')
-rw-r--r-- | lib/libalpm/conflict.c | 174 |
1 files changed, 58 insertions, 116 deletions
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 6faced16..89214707 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -45,15 +45,13 @@ pmconflict_t *_alpm_conflict_new(const char *package1, const char *package2, { pmconflict_t *conflict; - ALPM_LOG_FUNC; - MALLOC(conflict, sizeof(pmconflict_t), RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(conflict->package1, package1, RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(conflict->package2, package2, RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(conflict->reason, reason, RET_ERR(PM_ERR_MEMORY, NULL)); - return(conflict); + return conflict; } void _alpm_conflict_free(pmconflict_t *conflict) @@ -73,7 +71,7 @@ pmconflict_t *_alpm_conflict_dup(const pmconflict_t *conflict) STRDUP(newconflict->package2, conflict->package2, RET_ERR(PM_ERR_MEMORY, NULL)); STRDUP(newconflict->reason, conflict->reason, RET_ERR(PM_ERR_MEMORY, NULL)); - return(newconflict); + return newconflict; } static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) @@ -82,19 +80,17 @@ static int conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) const char *npkg1 = needle->package1; const char *npkg2 = needle->package2; - ALPM_LOG_FUNC; - for(i = haystack; i; i = i->next) { pmconflict_t *conflict = i->data; const char *cpkg1 = conflict->package1; const char *cpkg2 = conflict->package2; if((strcmp(cpkg1, npkg1) == 0 && strcmp(cpkg2, npkg2) == 0) || (strcmp(cpkg1, npkg2) == 0 && strcmp(cpkg2, npkg1) == 0)) { - return(1); + return 1; } } - return(0); + return 0; } /** Adds the pkg1/pkg2 conflict to the baddeps list @@ -168,12 +164,10 @@ alpm_list_t *_alpm_innerconflicts(alpm_list_t *packages) { alpm_list_t *baddeps = NULL; - ALPM_LOG_FUNC; - _alpm_log(PM_LOG_DEBUG, "check targets vs targets\n"); check_conflict(packages, packages, &baddeps, 0); - return(baddeps); + return baddeps; } /* Check for target vs (db - target) conflicts @@ -184,10 +178,8 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) { alpm_list_t *baddeps = NULL; - ALPM_LOG_FUNC; - if(db == NULL) { - return(NULL); + return NULL; } alpm_list_t *dblist = alpm_list_diff(_alpm_db_get_pkgcache(db), @@ -200,7 +192,7 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) check_conflict(dblist, packages, &baddeps, -1); alpm_list_free(dblist); - return(baddeps); + return baddeps; } /** Check the package conflicts in a database @@ -209,14 +201,20 @@ alpm_list_t *_alpm_outerconflicts(pmdb_t *db, alpm_list_t *packages) * @return an alpm_list_t of pmconflict_t */ alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_list_t *pkglist) { - return(_alpm_innerconflicts(pkglist)); + return _alpm_innerconflicts(pkglist); } -/* Returns a alpm_list_t* of file conflicts. - * Hooray for set-intersects! - * Pre-condition: both lists are sorted! +static const int DIFFERENCE = 0; +static const int INTERSECT = 1; +/* Returns a set operation on the provided two lists of files. + * Pre-condition: both lists are sorted! + * + * Operations: + * DIFFERENCE - a difference operation is performed. filesA - filesB. + * INTERSECT - an intersection operation is performed. filesA & filesB. */ -static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) +static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB, + int operation) { alpm_list_t *ret = NULL; alpm_list_t *pA = filesA, *pB = filesB; @@ -224,7 +222,7 @@ static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) while(pA && pB) { const char *strA = pA->data; const char *strB = pB->data; - /* skip directories, we don't care about dir conflicts */ + /* skip directories, we don't care about them */ if(strA[strlen(strA)-1] == '/') { pA = pA->next; } else if(strB[strlen(strB)-1] == '/') { @@ -232,59 +230,26 @@ static alpm_list_t *chk_fileconflicts(alpm_list_t *filesA, alpm_list_t *filesB) } else { int cmp = strcmp(strA, strB); if(cmp < 0) { - /* item only in filesA, ignore it */ + if(operation == DIFFERENCE) { + /* item only in filesA, qualifies as a difference */ + ret = alpm_list_add(ret, strdup(strA)); + } pA = pA->next; } else if(cmp > 0) { - /* item only in filesB, ignore it */ pB = pB->next; } else { - /* item in both, record it */ - ret = alpm_list_add(ret, strdup(strA)); + if(operation == INTERSECT) { + /* item in both, qualifies as an intersect */ + ret = alpm_list_add(ret, strdup(strA)); + } pA = pA->next; pB = pB->next; } } } - return(ret); -} - -/* Returns a alpm_list_t* of files that are in filesA but *NOT* in filesB - * This is an 'A minus B' set operation - * Pre-condition: both lists are sorted! - */ -static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB) -{ - alpm_list_t *ret = NULL; - alpm_list_t *pA = filesA, *pB = filesB; - - /* if both filesA and filesB have entries, do this loop */ - while(pA && pB) { - const char *strA = pA->data; - const char *strB = pB->data; - /* skip directories, we don't care about dir conflicts */ - if(strA[strlen(strA)-1] == '/') { - pA = pA->next; - } else if(strB[strlen(strB)-1] == '/') { - pB = pB->next; - } else { - int cmp = strcmp(strA, strB); - if(cmp < 0) { - /* item only in filesA, record it */ - ret = alpm_list_add(ret, strdup(strA)); - pA = pA->next; - } else if(cmp > 0) { - /* item only in fileB, but this means nothing */ - pB = pB->next; - } else { - /* item in both, ignore it */ - pA = pA->next; - pB = pB->next; - } - } - } - /* ensure we have completely emptied pA */ - while(pA) { + /* if doing a difference, ensure we have completely emptied pA */ + while(operation == DIFFERENCE && pA) { const char *strA = pA->data; /* skip directories */ if(strA[strlen(strA)-1] != '/') { @@ -293,7 +258,7 @@ static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB) pA = pA->next; } - return(ret); + return ret; } /* Adds pmfileconflict_t to a conflicts list. Pass the conflicts list, type (either @@ -314,22 +279,20 @@ static alpm_list_t *add_fileconflict(alpm_list_t *conflicts, if(name2) { STRDUP(conflict->ctarget, name2, RET_ERR(PM_ERR_MEMORY, NULL)); } else { - conflict->ctarget = ""; + STRDUP(conflict->ctarget, "", RET_ERR(PM_ERR_MEMORY, NULL)); } conflicts = alpm_list_add(conflicts, conflict); _alpm_log(PM_LOG_DEBUG, "found file conflict %s, packages %s and %s\n", filestr, name1, name2 ? name2 : "(filesystem)"); - return(conflicts); + return conflicts; } void _alpm_fileconflict_free(pmfileconflict_t *conflict) { - if(strlen(conflict->ctarget) > 0) { - FREE(conflict->ctarget); - } - FREE(conflict->file);; + FREE(conflict->ctarget); + FREE(conflict->file); FREE(conflict->target); FREE(conflict); } @@ -342,10 +305,10 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) char abspath[PATH_MAX]; DIR *dir; - snprintf(abspath, PATH_MAX, "%s%s", handle->root, dirpath); + snprintf(abspath, PATH_MAX, "%s%s", pkg->handle->root, dirpath); dir = opendir(abspath); if(dir == NULL) { - return(1); + return 1; } while((ent = readdir(dir)) != NULL) { const char *name = ent->d_name; @@ -354,7 +317,7 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) continue; } snprintf(path, PATH_MAX, "%s/%s", dirpath, name); - snprintf(abspath, PATH_MAX, "%s%s", handle->root, path); + snprintf(abspath, PATH_MAX, "%s%s", pkg->handle->root, path); if(stat(abspath, &sbuf) != 0) { continue; } @@ -363,35 +326,34 @@ static int dir_belongsto_pkg(char *dirpath, pmpkg_t *pkg) continue; } else { closedir(dir); - return(0); + return 0; } } else { if(alpm_list_find_str(alpm_pkg_get_files(pkg), path)) { continue; } else { closedir(dir); - return(0); + return 0; } } } closedir(dir); - return(1); + return 1; } /* Find file conflicts that may occur during the transaction with two checks: * 1: check every target against every target * 2: check every target against the filesystem */ -alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, +alpm_list_t *_alpm_db_find_fileconflicts(pmhandle_t *handle, alpm_list_t *upgrade, alpm_list_t *remove) { alpm_list_t *i, *j, *conflicts = NULL; size_t numtargs = alpm_list_count(upgrade); size_t current; + pmtrans_t *trans = handle->trans; - ALPM_LOG_FUNC; - - if(db == NULL || upgrade == NULL || trans == NULL) { - return(NULL); + if(!upgrade) { + return NULL; } /* TODO this whole function needs a huge change, which hopefully will @@ -419,7 +381,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, if(!p2) { continue; } - tmpfiles = chk_fileconflicts(alpm_pkg_get_files(p1), alpm_pkg_get_files(p2)); + tmpfiles = filelist_operation( alpm_pkg_get_files(p1), + alpm_pkg_get_files(p2), INTERSECT); if(tmpfiles) { for(k = tmpfiles; k; k = k->next) { @@ -437,15 +400,15 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, /* CHECK 2: check every target against the filesystem */ _alpm_log(PM_LOG_DEBUG, "searching for filesystem conflicts: %s\n", p1->name); - dbpkg = _alpm_db_get_pkgfromcache(db, p1->name); + dbpkg = _alpm_db_get_pkgfromcache(handle->db_local, p1->name); /* Do two different checks here. If the package is currently installed, * then only check files that are new in the new package. If the package * is not currently installed, then simply stat the whole filelist */ if(dbpkg) { /* older ver of package currently installed */ - tmpfiles = chk_filedifference(alpm_pkg_get_files(p1), - alpm_pkg_get_files(dbpkg)); + tmpfiles = filelist_operation(alpm_pkg_get_files(p1), + alpm_pkg_get_files(dbpkg), DIFFERENCE); } else { /* no version of package currently installed */ tmpfiles = alpm_list_strdup(alpm_pkg_get_files(p1)); @@ -491,7 +454,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, if(!p2 || strcmp(p1->name, p2->name) == 0) { continue; } - pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(db, p2->name); + pmpkg_t *localp2 = _alpm_db_get_pkgfromcache(handle->db_local, p2->name); /* localp2->files will be removed (target conflicts are handled by CHECK 1) */ if(localp2 && alpm_list_find_str(alpm_pkg_get_files(localp2), filestr)) { @@ -540,82 +503,61 @@ alpm_list_t *_alpm_db_find_fileconflicts(pmdb_t *db, pmtrans_t *trans, PROGRESS(trans, PM_TRANS_PROGRESS_CONFLICTS_START, "", 100, numtargs, current); - return(conflicts); + return conflicts; } const char SYMEXPORT *alpm_conflict_get_package1(pmconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->package1; } const char SYMEXPORT *alpm_conflict_get_package2(pmconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->package2; } const char SYMEXPORT *alpm_conflict_get_reason(pmconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->reason; } const char SYMEXPORT *alpm_fileconflict_get_target(pmfileconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->target; } pmfileconflicttype_t SYMEXPORT alpm_fileconflict_get_type(pmfileconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(-1)); - ASSERT(conflict != NULL, return(-1)); + ASSERT(conflict != NULL, return -1); return conflict->type; } const char SYMEXPORT *alpm_fileconflict_get_file(pmfileconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->file; } const char SYMEXPORT *alpm_fileconflict_get_ctarget(pmfileconflict_t *conflict) { - ALPM_LOG_FUNC; - /* Sanity checks */ - ASSERT(handle != NULL, return(NULL)); - ASSERT(conflict != NULL, return(NULL)); + ASSERT(conflict != NULL, return NULL); return conflict->ctarget; } |