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

Reply via email to