index : pacman | |
Archlinux32 fork of pacman | gitolite user |
summaryrefslogtreecommitdiff |
author | Dan McGee <dan@archlinux.org> | 2012-02-29 15:51:54 -0600 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2012-03-05 11:44:33 -0600 |
commit | d1151b5ab9c407732ded462a0fe0259dea8dcc2a (patch) | |
tree | d693ec6f216e9b4d149cc48cd7bdfaf32394d66d | |
parent | 78adb71f20ee335dff49e34d33f04817a40002b6 (diff) |
-rw-r--r-- | src/pacman/sync.c | 71 |
diff --git a/src/pacman/sync.c b/src/pacman/sync.c index fcc887ae..a9a9e99c 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -25,6 +25,7 @@ #include <string.h> #include <limits.h> #include <unistd.h> +#include <errno.h> #include <dirent.h> #include <sys/stat.h> @@ -37,6 +38,20 @@ #include "package.h" #include "conf.h" +static int unlink_verbose(const char *pathname, int ignore_missing) +{ + int ret = unlink(pathname); + if(ret) { + if(ignore_missing && errno == ENOENT) { + ret = 0; + } else { + pm_printf(ALPM_LOG_ERROR, _("could not remove %s: %s\n"), + pathname, strerror(errno)); + } + } + return ret; +} + /* if keep_used != 0, then the db files which match an used syncdb * will be kept */ static int sync_cleandb(const char *dbpath, int keep_used) @@ -44,6 +59,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) DIR *dir; struct dirent *ent; alpm_list_t *syncdbs; + int ret = 0; dir = opendir(dbpath); if(dir == NULL) { @@ -60,6 +76,7 @@ static int sync_cleandb(const char *dbpath, int keep_used) struct stat buf; int found = 0; const char *dname = ent->d_name; + char *dbname; size_t len; if(strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0) { @@ -79,44 +96,46 @@ static int sync_cleandb(const char *dbpath, int keep_used) /* remove all non-skipped directories and non-database files */ stat(path, &buf); - len = strlen(path); - if(S_ISDIR(buf.st_mode) || strcmp(path + len - 3, ".db") != 0) { + if(S_ISDIR(buf.st_mode)) { if(rmrf(path)) { - pm_printf(ALPM_LOG_ERROR, - _("could not remove %s\n"), path); - closedir(dir); - return 1; + pm_printf(ALPM_LOG_ERROR, _("could not remove %s: %s\n"), + path, strerror(errno)); } continue; } + len = strlen(dname); + if(len > 3 && strcmp(dname + len - 3, ".db") == 0) { + dbname = strndup(dname, len - 3); + } else if(len > 7 && strcmp(dname + len - 7, ".db.sig") == 0) { + dbname = strndup(dname, len - 7); + } else { + ret += unlink_verbose(path, 0); + continue; + } + if(keep_used) { alpm_list_t *i; - len = strlen(dname); - char *dbname = strndup(dname, len - 3); for(i = syncdbs; i && !found; i = alpm_list_next(i)) { alpm_db_t *db = alpm_list_getdata(i); found = !strcmp(dbname, alpm_db_get_name(db)); } - free(dbname); } - /* We have a database that doesn't match any syncdb. - * Ask the user if he wants to remove it. */ - if(!found) { - if(!yesno(_("Do you want to remove %s?"), path)) { - continue; - } - if(rmrf(path)) { - pm_printf(ALPM_LOG_ERROR, - _("could not remove %s\n"), path); - closedir(dir); - return 1; - } + /* We have a database that doesn't match any syncdb. */ + if(!found) { + /* ENOENT check is because the signature and database could come in any + * order in our readdir() call, so either file may already be gone. */ + snprintf(path, PATH_MAX, "%s%s.db", dbpath, dbname); + ret += unlink_verbose(path, 1); + /* unlink a signature file if present too */ + snprintf(path, PATH_MAX, "%s%s.db.sig", dbpath, dbname); + ret += unlink_verbose(path, 1); } + free(dbname); } closedir(dir); - return 0; + return ret; } static int sync_cleandb_all(void) @@ -130,6 +149,7 @@ static int sync_cleandb_all(void) if(!yesno(_("Do you want to remove unused repositories?"))) { return 0; } + printf(_("removing unused sync repositories...\n")); /* The sync dbs were previously put in dbpath/ but are now in dbpath/sync/. * We will clean everything in dbpath/ except local/, sync/ and db.lck, and * only the unused sync dbs in dbpath/sync/ */ @@ -142,7 +162,6 @@ static int sync_cleandb_all(void) ret += sync_cleandb(newdbpath, 1); free(newdbpath); - printf(_("Database directory cleaned up\n")); return ret; } @@ -210,7 +229,7 @@ static int sync_cleancache(int level) /* short circuit for removing all files from cache */ if(level > 1) { - unlink(path); + ret += unlink_verbose(path, 0); continue; } @@ -256,11 +275,11 @@ static int sync_cleancache(int level) if(delete) { size_t pathlen = strlen(path); - unlink(path); + ret += unlink_verbose(path, 0); /* unlink a signature file if present too */ if(PATH_MAX - 5 >= pathlen) { strcpy(path + pathlen, ".sig"); - unlink(path); + ret += unlink_verbose(path, 1); } } } |