index : pacman | |
Archlinux32 fork of pacman | gitolite user |
summaryrefslogtreecommitdiff |
-rw-r--r-- | lib/libalpm/conflict.c | 128 |
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index 6bfd256f..ccfe990c 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -1,7 +1,7 @@ /* * conflict.c * - * Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org> * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> * Copyright (c) 2006 by David Kimpe <dnaku@frugalware.org> @@ -22,8 +22,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "config.h" - #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -40,6 +38,7 @@ #include "util.h" #include "log.h" #include "deps.h" +#include "filelist.h" static alpm_conflict_t *conflict_new(alpm_pkg_t *pkg1, alpm_pkg_t *pkg2, alpm_depend_t *reason) @@ -215,67 +214,6 @@ alpm_list_t SYMEXPORT *alpm_checkconflicts(alpm_handle_t *handle, return _alpm_innerconflicts(handle, pkglist); } -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! - * When done, free the list but NOT the contained data. - * - * Operations: - * DIFFERENCE - a difference operation is performed. filesA - filesB. - * INTERSECT - an intersection operation is performed. filesA & filesB. - */ -static alpm_list_t *filelist_operation(alpm_filelist_t *filesA, - alpm_filelist_t *filesB, int operation) -{ - alpm_list_t *ret = NULL; - size_t ctrA = 0, ctrB = 0; - - while(ctrA < filesA->count && ctrB < filesB->count) { - alpm_file_t *fileA = filesA->files + ctrA; - alpm_file_t *fileB = filesB->files + ctrB; - const char *strA = fileA->name; - const char *strB = fileB->name; - /* skip directories, we don't care about them */ - if(strA[strlen(strA)-1] == '/') { - ctrA++; - } else if(strB[strlen(strB)-1] == '/') { - ctrB++; - } else { - int cmp = strcmp(strA, strB); - if(cmp < 0) { - if(operation == DIFFERENCE) { - /* item only in filesA, qualifies as a difference */ - ret = alpm_list_add(ret, fileA); - } - ctrA++; - } else if(cmp > 0) { - ctrB++; - } else { - if(operation == INTERSECT) { - /* item in both, qualifies as an intersect */ - ret = alpm_list_add(ret, fileA); - } - ctrA++; - ctrB++; - } - } - } - - /* if doing a difference, ensure we have completely emptied pA */ - while(operation == DIFFERENCE && ctrA < filesA->count) { - alpm_file_t *fileA = filesA->files + ctrA; - const char *strA = fileA->name; - /* skip directories */ - if(strA[strlen(strA)-1] != '/') { - ret = alpm_list_add(ret, fileA); - } - ctrA++; - } - - return ret; -} - /* Adds alpm_fileconflict_t to a conflicts list. Pass the conflicts list, the * conflicting file path, and either two packages or one package and NULL. */ @@ -314,20 +252,6 @@ void _alpm_fileconflict_free(alpm_fileconflict_t *conflict) FREE(conflict); } -const alpm_file_t *_alpm_filelist_contains(alpm_filelist_t *filelist, - const char *name) -{ - size_t i; - const alpm_file_t *file = filelist->files; - for(i = 0; i < filelist->count; i++) { - if(strcmp(file->name, name) == 0) { - return file; - } - file++; - } - return NULL; -} - static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath, alpm_pkg_t *pkg) { @@ -340,7 +264,7 @@ static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath, const char *root = handle->root; /* check directory is actually in package - used for subdirectory checks */ - if(!_alpm_filelist_contains(alpm_pkg_get_files(pkg), dirpath)) { + if(!alpm_filelist_contains(alpm_pkg_get_files(pkg), dirpath)) { _alpm_log(handle, ALPM_LOG_DEBUG, "directory %s not in package %s\n", dirpath, pkg->name); return 0; @@ -358,7 +282,7 @@ static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath, continue; } - if(_alpm_filelist_contains(alpm_pkg_get_files(i->data), dirpath)) { + if(alpm_filelist_contains(alpm_pkg_get_files(i->data), dirpath)) { _alpm_log(handle, ALPM_LOG_DEBUG, "file %s also in package %s\n", dirpath, ((alpm_pkg_t*)i->data)->name); @@ -392,7 +316,7 @@ static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath, return 0; } } else { - if(_alpm_filelist_contains(alpm_pkg_get_files(pkg), path)) { + if(alpm_filelist_contains(alpm_pkg_get_files(pkg), path)) { continue; } else { closedir(dir); @@ -410,16 +334,19 @@ static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath, * 1: check every target against every target * 2: check every target against the filesystem */ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, - alpm_list_t *upgrade, alpm_list_t *remove) + alpm_list_t *upgrade, alpm_list_t *rem) { alpm_list_t *i, *conflicts = NULL; size_t numtargs = alpm_list_count(upgrade); size_t current; + size_t rootlen; if(!upgrade) { return NULL; } + rootlen = strlen(handle->root); + /* TODO this whole function needs a huge change, which hopefully will * be possible with real transactions. Right now we only do half as much * here as we do when we actually extract files in add.c with our 12 @@ -440,8 +367,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, for(j = i->next; j; j = j->next) { alpm_list_t *common_files; alpm_pkg_t *p2 = j->data; - common_files = filelist_operation(alpm_pkg_get_files(p1), - alpm_pkg_get_files(p2), INTERSECT); + common_files = _alpm_filelist_intersection(alpm_pkg_get_files(p1), + alpm_pkg_get_files(p2)); if(common_files) { alpm_list_t *k; @@ -473,8 +400,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, if(dbpkg) { alpm_list_t *difference; /* older ver of package currently installed */ - difference = filelist_operation(alpm_pkg_get_files(p1), - alpm_pkg_get_files(dbpkg), DIFFERENCE); + difference = _alpm_filelist_difference(alpm_pkg_get_files(p1), + alpm_pkg_get_files(dbpkg)); tmpfiles.count = alpm_list_count(difference); tmpfiles.files = alpm_list_to_array(difference, tmpfiles.count, sizeof(alpm_file_t)); @@ -493,8 +420,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, int resolved_conflict = 0; struct stat lsbuf; char path[PATH_MAX]; + size_t pathlen; - snprintf(path, PATH_MAX, "%s%s", handle->root, filestr); + pathlen = snprintf(path, PATH_MAX, "%s%s", handle->root, filestr); /* stat the file - if it exists, do some checks */ if(_alpm_lstat(path, &lsbuf) != 0) { @@ -518,15 +446,15 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, /* if we made it to here, we want all subsequent path comparisons to * not include the trailing slash. This allows things like file -> * directory replacements. */ - path[strlen(path) - 1] = '\0'; + path[pathlen - 1] = '\0'; } - relative_path = path + strlen(handle->root); + relative_path = path + rootlen; /* Check remove list (will we remove the conflicting local file?) */ - for(k = remove; k && !resolved_conflict; k = k->next) { + for(k = rem; k && !resolved_conflict; k = k->next) { alpm_pkg_t *rempkg = k->data; - if(rempkg && _alpm_filelist_contains(alpm_pkg_get_files(rempkg), + if(rempkg && alpm_filelist_contains(alpm_pkg_get_files(rempkg), relative_path)) { _alpm_log(handle, ALPM_LOG_DEBUG, "local file will be removed, not a conflict\n"); @@ -543,7 +471,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, alpm_pkg_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_filelist_contains(alpm_pkg_get_files(localp2), filestr)) { + if(localp2 && alpm_filelist_contains(alpm_pkg_get_files(localp2), filestr)) { /* skip removal of file, but not add. this will prevent a second * package from removing the file when it was already installed * by its new owner (whether the file is in backup array or not */ @@ -559,7 +487,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, if(!resolved_conflict && S_ISDIR(lsbuf.st_mode) && dbpkg) { char *dir = malloc(strlen(filestr) + 2); sprintf(dir, "%s/", filestr); - if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) { + if(alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) { _alpm_log(handle, ALPM_LOG_DEBUG, "checking if all files in %s belong to %s\n", dir, dbpkg->name); @@ -573,17 +501,15 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, * consideration cannot itself be a link, as it might be unowned- path * components can be safely checked as all directories are "unowned". */ if(!resolved_conflict && dbpkg && !S_ISLNK(lsbuf.st_mode)) { - char *rpath = calloc(PATH_MAX, sizeof(char)); - const char *relative_rpath; + char rpath[PATH_MAX]; if(realpath(path, rpath)) { - relative_rpath = rpath + strlen(handle->root); - if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) { + const char *relative_rpath = rpath + rootlen; + if(alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) { _alpm_log(handle, ALPM_LOG_DEBUG, "package contained the resolved realpath\n"); resolved_conflict = 1; } } - free(rpath); } /* is the file unowned and in the backup list of the new package? */ @@ -591,7 +517,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, alpm_list_t *local_pkgs = _alpm_db_get_pkgcache(handle->db_local); int found = 0; for(k = local_pkgs; k && !found; k = k->next) { - if(_alpm_filelist_contains(alpm_pkg_get_files(k->data), filestr)) { + if(alpm_filelist_contains(alpm_pkg_get_files(k->data), filestr)) { found = 1; } } @@ -607,7 +533,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, if(handle->pm_errno == ALPM_ERR_MEMORY) { FREELIST(conflicts); if(dbpkg) { - /* only freed if it was generated from filelist_operation() */ + /* only freed if it was generated from _alpm_filelist_difference() */ free(tmpfiles.files); } return NULL; @@ -615,7 +541,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, } } if(dbpkg) { - /* only freed if it was generated from filelist_operation() */ + /* only freed if it was generated from _alpm_filelist_difference() */ free(tmpfiles.files); } } |