summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/conflict.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/conflict.c')
-rw-r--r--lib/libalpm/conflict.c174
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;
}