diff options
author | Andrew Gregory <andrew.gregory.8@gmail.com> | 2017-04-09 20:42:01 -0400 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2017-04-12 11:47:33 +1000 |
commit | 04d211effa8d65020887112ee30c7b3b0fc28ad3 (patch) | |
tree | 9939b65851a6fc5bb6a0863d286b8da0d4876e74 /lib | |
parent | 86f5c74694cb0403eaf11fa4734f307a0df345cb (diff) |
add --overwrite option to ignore file conflicts
Allows for safer, more fine-grained control for overwriting files than
--force's all-or-nothing approach.
Implements FS#31549.
Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com>
Signed-off-by: Allan McRae <allan@archlinux.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libalpm/alpm.h | 5 | ||||
-rw-r--r-- | lib/libalpm/conflict.c | 14 | ||||
-rw-r--r-- | lib/libalpm/handle.c | 21 | ||||
-rw-r--r-- | lib/libalpm/handle.h | 1 |
4 files changed, 37 insertions, 4 deletions
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 448d42d2..2637a055 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -830,6 +830,11 @@ int alpm_option_add_hookdir(alpm_handle_t *handle, const char *hookdir); int alpm_option_remove_hookdir(alpm_handle_t *handle, const char *hookdir); /** @} */ +alpm_list_t *alpm_option_get_overwrite_files(alpm_handle_t *handle); +int alpm_option_set_overwrite_files(alpm_handle_t *handle, alpm_list_t *globs); +int alpm_option_add_overwrite_file(alpm_handle_t *handle, const char *glob); +int alpm_option_remove_overwrite_file(alpm_handle_t *handle, const char *glob); + /** Returns the logfile name. */ const char *alpm_option_get_logfile(alpm_handle_t *handle); /** Sets the logfile name. */ diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index b1666dfe..0e37419f 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -385,6 +385,12 @@ static alpm_list_t *alpm_db_find_file_owners(alpm_db_t* db, const char *path) return owners; } +static int _alpm_can_overwrite_file(alpm_handle_t *handle, const char *path) +{ + return handle->trans->flags & ALPM_TRANS_FLAG_FORCE + || _alpm_fnmatch_patterns(handle->overwrite_files, path) == 0; +} + /** * @brief Find file conflicts that may occur during the transaction. * @@ -448,8 +454,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, /* can skip file-file conflicts when forced * * checking presence in p2_files detects dir-file or file-dir * conflicts as the path from p1 is returned */ - if((handle->trans->flags & ALPM_TRANS_FLAG_FORCE) && - alpm_filelist_contains(p2_files, filename)) { + if(_alpm_can_overwrite_file(handle, filename) + && alpm_filelist_contains(p2_files, filename)) { _alpm_log(handle, ALPM_LOG_DEBUG, "%s exists in both '%s' and '%s'\n", filename, p1->name, p2->name); @@ -654,8 +660,8 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle, } /* skip file-file conflicts when being forced */ - if((handle->trans->flags & ALPM_TRANS_FLAG_FORCE) && - !S_ISDIR(lsbuf.st_mode)) { + if(!S_ISDIR(lsbuf.st_mode) + && _alpm_can_overwrite_file(handle, filestr)) { _alpm_log(handle, ALPM_LOG_DEBUG, "conflict with file on filesystem being forced\n"); resolved_conflict = 1; diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index f08f614c..b6b27881 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -283,6 +283,12 @@ alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle) return handle->ignoregroup; } +alpm_list_t SYMEXPORT *alpm_option_get_overwrite_files(alpm_handle_t *handle) +{ + CHECK_HANDLE(handle, return NULL); + return handle->overwrite_files; +} + alpm_list_t SYMEXPORT *alpm_option_get_assumeinstalled(alpm_handle_t *handle) { CHECK_HANDLE(handle, return NULL); @@ -657,6 +663,21 @@ int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char * return _alpm_option_strlist_rem(handle, &(handle->ignoregroup), grp); } +int SYMEXPORT alpm_option_add_overwrite_file(alpm_handle_t *handle, const char *glob) +{ + return _alpm_option_strlist_add(handle, &(handle->overwrite_files), glob); +} + +int SYMEXPORT alpm_option_set_overwrite_files(alpm_handle_t *handle, alpm_list_t *globs) +{ + return _alpm_option_strlist_set(handle, &(handle->overwrite_files), globs); +} + +int SYMEXPORT alpm_option_remove_overwrite_file(alpm_handle_t *handle, const char *glob) +{ + return _alpm_option_strlist_rem(handle, &(handle->overwrite_files), glob); +} + int SYMEXPORT alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep) { alpm_depend_t *depcpy; diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h index 223eac12..115c3481 100644 --- a/lib/libalpm/handle.h +++ b/lib/libalpm/handle.h @@ -84,6 +84,7 @@ struct __alpm_handle_t { char *gpgdir; /* Directory where GnuPG files are stored */ alpm_list_t *cachedirs; /* Paths to pacman cache directories */ alpm_list_t *hookdirs; /* Paths to hook directories */ + alpm_list_t *overwrite_files; /* Paths that may be overwritten */ /* package lists */ alpm_list_t *noupgrade; /* List of packages NOT to be upgraded */ |