1
0
mirror of https://github.com/moparisthebest/pacman synced 2024-12-22 15:58:50 -05:00

Database cleanup enhancements

Ensure we give database signatures special treatment like we already did
for package signatures. Attempt to parse the database name out of them
before taking the proper steps to handle their existence. This fixes
FS#28714.

We also add an unlink_verbose() helper method that displays any errors
that occur when unlinking, optionally opting to skip any ENOENT errors
from being fatal.

Finally, the one prompt per unknown database has been removed, this has
no real sound purpose and we don't do this for packages. Simply kill
databases we don't know about; other programs shouldn't have random data
in this directory anyway.

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2012-02-29 15:51:54 -06:00
parent 78adb71f20
commit d1151b5ab9

View File

@ -25,6 +25,7 @@
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h>
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -37,6 +38,20 @@
#include "package.h" #include "package.h"
#include "conf.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 /* if keep_used != 0, then the db files which match an used syncdb
* will be kept */ * will be kept */
static int sync_cleandb(const char *dbpath, int keep_used) 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; DIR *dir;
struct dirent *ent; struct dirent *ent;
alpm_list_t *syncdbs; alpm_list_t *syncdbs;
int ret = 0;
dir = opendir(dbpath); dir = opendir(dbpath);
if(dir == NULL) { if(dir == NULL) {
@ -60,6 +76,7 @@ static int sync_cleandb(const char *dbpath, int keep_used)
struct stat buf; struct stat buf;
int found = 0; int found = 0;
const char *dname = ent->d_name; const char *dname = ent->d_name;
char *dbname;
size_t len; size_t len;
if(strcmp(dname, ".") == 0 || strcmp(dname, "..") == 0) { 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 */ /* remove all non-skipped directories and non-database files */
stat(path, &buf); stat(path, &buf);
len = strlen(path); if(S_ISDIR(buf.st_mode)) {
if(S_ISDIR(buf.st_mode) || strcmp(path + len - 3, ".db") != 0) {
if(rmrf(path)) { if(rmrf(path)) {
pm_printf(ALPM_LOG_ERROR, pm_printf(ALPM_LOG_ERROR, _("could not remove %s: %s\n"),
_("could not remove %s\n"), path); path, strerror(errno));
closedir(dir);
return 1;
} }
continue; 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) { if(keep_used) {
alpm_list_t *i; alpm_list_t *i;
len = strlen(dname);
char *dbname = strndup(dname, len - 3);
for(i = syncdbs; i && !found; i = alpm_list_next(i)) { for(i = syncdbs; i && !found; i = alpm_list_next(i)) {
alpm_db_t *db = alpm_list_getdata(i); alpm_db_t *db = alpm_list_getdata(i);
found = !strcmp(dbname, alpm_db_get_name(db)); 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)) { /* We have a database that doesn't match any syncdb. */
pm_printf(ALPM_LOG_ERROR, if(!found) {
_("could not remove %s\n"), path); /* ENOENT check is because the signature and database could come in any
closedir(dir); * order in our readdir() call, so either file may already be gone. */
return 1; 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); closedir(dir);
return 0; return ret;
} }
static int sync_cleandb_all(void) 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?"))) { if(!yesno(_("Do you want to remove unused repositories?"))) {
return 0; return 0;
} }
printf(_("removing unused sync repositories...\n"));
/* The sync dbs were previously put in dbpath/ but are now in dbpath/sync/. /* 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 * We will clean everything in dbpath/ except local/, sync/ and db.lck, and
* only the unused sync dbs in dbpath/sync/ */ * only the unused sync dbs in dbpath/sync/ */
@ -142,7 +162,6 @@ static int sync_cleandb_all(void)
ret += sync_cleandb(newdbpath, 1); ret += sync_cleandb(newdbpath, 1);
free(newdbpath); free(newdbpath);
printf(_("Database directory cleaned up\n"));
return ret; return ret;
} }
@ -210,7 +229,7 @@ static int sync_cleancache(int level)
/* short circuit for removing all files from cache */ /* short circuit for removing all files from cache */
if(level > 1) { if(level > 1) {
unlink(path); ret += unlink_verbose(path, 0);
continue; continue;
} }
@ -256,11 +275,11 @@ static int sync_cleancache(int level)
if(delete) { if(delete) {
size_t pathlen = strlen(path); size_t pathlen = strlen(path);
unlink(path); ret += unlink_verbose(path, 0);
/* unlink a signature file if present too */ /* unlink a signature file if present too */
if(PATH_MAX - 5 >= pathlen) { if(PATH_MAX - 5 >= pathlen) {
strcpy(path + pathlen, ".sig"); strcpy(path + pathlen, ".sig");
unlink(path); ret += unlink_verbose(path, 1);
} }
} }
} }