[pacman-dev] [PATCH] pacman: don't nuke local repos with -Sc
morganamilo
morganamilo at archlinux.org
Mon Jun 14 19:11:28 UTC 2021
When using a local repo as a cachedir pacman -Scc or pacman -Sc
without KeepCurrent will delete the repo database and packages
resulting in a lost database and non functional pacman.
So special case file:/// repos in cache to not get nuked and foce
KeepCurrent on.
---
src/pacman/sync.c | 64 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 55 insertions(+), 9 deletions(-)
diff --git a/src/pacman/sync.c b/src/pacman/sync.c
index b6da1a36..129d3f5c 100644
--- a/src/pacman/sync.c
+++ b/src/pacman/sync.c
@@ -151,34 +151,71 @@ static int sync_cleandb_all(void)
return ret;
}
-static int sync_cleancache(int level)
+static int is_local_repo(char *dir)
+{
+ alpm_list_t *j, *k;
+ char *sanatized_dir = strdup(dir);
+ int len = strlen(sanatized_dir);
+ int ret = 0;
+
+ if(sanatized_dir[len - 1] == '/') {
+ sanatized_dir[len - 1] = '\0';
+ }
+
+ for(j = alpm_get_syncdbs(config->handle); j; j = alpm_list_next(j)) {
+ alpm_db_t *db = j->data;
+
+ for(k = alpm_db_get_servers(db); k; k = alpm_list_next(k)) {
+ char *server = k->data;
+
+ if(strncmp(server, "file://", 7) == 0) {
+ server += 7;
+
+ if(strcmp(server, sanatized_dir) == 0) {
+ ret = 1;
+ goto cleanup;
+ }
+ }
+ }
+
+ }
+
+cleanup:
+ free(sanatized_dir);
+ return ret;
+}
+
+static int sync_cleancache(int config_level)
{
alpm_list_t *i;
alpm_list_t *sync_dbs = alpm_get_syncdbs(config->handle);
alpm_db_t *db_local = alpm_get_localdb(config->handle);
alpm_list_t *cachedirs = alpm_option_get_cachedirs(config->handle);
+ int config_cleanmethod = config->cleanmethod;
int ret = 0;
- if(!config->cleanmethod) {
+ if(config_cleanmethod) {
/* default to KeepInstalled if user did not specify */
- config->cleanmethod = PM_CLEAN_KEEPINST;
+ config_cleanmethod = PM_CLEAN_KEEPINST;
}
- if(level == 1) {
+ if(config_level == 1) {
printf(_("Packages to keep:\n"));
- if(config->cleanmethod & PM_CLEAN_KEEPINST) {
+ if(config_cleanmethod & PM_CLEAN_KEEPINST) {
printf(_(" All locally installed packages\n"));
}
- if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
+ if(config_cleanmethod & PM_CLEAN_KEEPCUR) {
printf(_(" All current sync database packages\n"));
}
}
printf("\n");
for(i = cachedirs; i; i = alpm_list_next(i)) {
- const char *cachedir = i->data;
+ char *cachedir = i->data;
DIR *dir;
struct dirent *ent;
+ int cleanmethod = config_cleanmethod;
+ int level = config_level;
printf(_("Cache directory: %s\n"), (const char *)i->data);
@@ -196,6 +233,15 @@ static int sync_cleancache(int level)
printf(_("removing all files from cache...\n"));
}
+ if(is_local_repo(cachedir)) {
+ pm_printf(ALPM_LOG_DEBUG,
+ _("cachedir '%s' is a local repo, keeping packages\n"), cachedir);
+
+ level = 1;
+ cleanmethod |= PM_CLEAN_KEEPCUR;
+ cleanmethod &= ~PM_CLEAN_KEEPINST;
+ }
+
dir = opendir(cachedir);
if(dir == NULL) {
pm_printf(ALPM_LOG_ERROR,
@@ -258,7 +304,7 @@ static int sync_cleancache(int level)
local_name = alpm_pkg_get_name(localpkg);
local_version = alpm_pkg_get_version(localpkg);
- if(config->cleanmethod & PM_CLEAN_KEEPINST) {
+ if(cleanmethod & PM_CLEAN_KEEPINST) {
/* check if this package is in the local DB */
pkg = alpm_db_get_pkg(db_local, local_name);
if(pkg != NULL && alpm_pkg_vercmp(local_version,
@@ -269,7 +315,7 @@ static int sync_cleancache(int level)
delete = 0;
}
}
- if(config->cleanmethod & PM_CLEAN_KEEPCUR) {
+ if(cleanmethod & PM_CLEAN_KEEPCUR) {
alpm_list_t *j;
/* check if this package is in a sync DB */
for(j = sync_dbs; j && delete; j = alpm_list_next(j)) {
--
2.32.0
More information about the pacman-dev
mailing list