Compare commits

..

1 Commits

Author SHA1 Message Date
morganamilo
a61c500557 pacman: add -Q --backup
pacman -Q -w/--backup will print the modified backup files of a system
(passing twice will print all backup files). This could be useful for
backup/moving system config files.
2021-10-02 00:12:52 +01:00
13 changed files with 192 additions and 351 deletions

View File

@@ -364,6 +364,9 @@ Query Options (apply to '-Q')[[QO]]
replacements are not checked here. This option works best if the sync
database is refreshed using '-Sy'.
*-w, \--backup*::
List all modified backup files owened by a given package. Multiple packages can
be specified on the command line. Pass twice to print all backup files.
Remove Options (apply to '-R')[[RO]]
------------------------------------

View File

@@ -101,11 +101,6 @@ typedef struct _alpm_handle_t alpm_handle_t;
typedef struct _alpm_db_t alpm_db_t;
/** A Database file iterator
* @ingroup libalpm_databases
*/
typedef struct __alpm_db_files_t alpm_db_files_t;
/** A package.
*
* A package can be loaded from disk via \link alpm_pkg_load \endlink or retrieved from a database.
@@ -163,9 +158,6 @@ typedef struct _alpm_backup_t {
*/
alpm_file_t *alpm_filelist_contains(alpm_filelist_t *filelist, const char *path);
/** Frees a file list */
void alpm_filelist_free(alpm_filelist_t *files);
/* End of libalpm_files */
/** @} */
@@ -1452,42 +1444,6 @@ int alpm_db_get_usage(alpm_db_t *db, int *usage);
/* End of usage accessors */
/** @} */
/** @name File iterators
* @{
*/
/** Opens a handle to the db files iterator.
* @param db the db files to iterate over
* @return handle to the iterator
*/
alpm_db_files_t *alpm_db_files_open(alpm_db_t *db);
/** Goes to the next package.
* @param files handle to the file iterator
* @param pkgname stores the pkgname of the current package
* @return 0 on success, 1 if end of iterator, -1 on error
*/
int alpm_db_files_next(alpm_db_files_t *files, char** pkgname);
/** Loads the files for a package into a file list.
*
* This extends the file list as needed, reusing the memory alloced.
* You can reuse the same file list for calls to this function but
* the list should be freed with \link alpm_filelist_free alpm_filelist_free \endlink
* after use.
* @param files handle to the file iterator
* @param filelist the filelist to load files into
* @return 0 on success, -1 on error
*/
int alpm_db_files_load(alpm_db_files_t *files, alpm_filelist_t *filelist);
/** Close the db file iterator
* @param files handle to the file iterator
*/
void alpm_db_files_close(alpm_db_files_t *files);
/* End of file iterators */
/** @} */
/* End of libalpm_databases */
/** @} */
@@ -2722,6 +2678,7 @@ int alpm_pkg_mtree_close(const alpm_pkg_t *pkg, struct archive *archive);
/* End of mtree accessors */
/** @} */
/* End of libalpm_packages */
/** @} */

View File

@@ -566,7 +566,8 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
return 0;
}
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0) {
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|| strcmp(filename, "files") == 0) {
int ret;
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
char *line = buf.line;
@@ -635,6 +636,36 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
READ_AND_SPLITDEP(pkg->conflicts);
} else if(strcmp(line, "%PROVIDES%") == 0) {
READ_AND_SPLITDEP(pkg->provides);
} else if(strcmp(line, "%FILES%") == 0) {
/* TODO: this could lazy load if there is future demand */
size_t files_count = 0, files_size = 0;
alpm_file_t *files = NULL;
while(1) {
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) {
goto error;
}
line = buf.line;
if(_alpm_strip_newline(line, buf.real_line_size) == 0) {
break;
}
if(!_alpm_greedy_grow((void **)&files, &files_size,
(files_count ? (files_count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) {
goto error;
}
STRDUP(files[files_count].name, line, goto error);
files_count++;
}
/* attempt to hand back any memory we don't need */
if(files_count > 0) {
REALLOC(files, sizeof(alpm_file_t) * files_count, (void)0);
} else {
FREE(files);
}
pkg->files.count = files_count;
pkg->files.files = files;
_alpm_filelist_sort(&pkg->files);
}
}
if(ret != ARCHIVE_EOF) {
@@ -685,152 +716,3 @@ alpm_db_t *_alpm_db_register_sync(alpm_handle_t *handle, const char *treename,
handle->dbs_sync = alpm_list_add(handle->dbs_sync, db);
return db;
}
static int load_files(struct archive *archive, alpm_filelist_t *filelist)
{
struct archive_read_buffer buf = {0};
/* 512K for a line length seems reasonable */
buf.max_line_size = 512 * 1024;
_alpm_filelist_truncate(filelist);
int ret;
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
char *line = buf.line;
if(_alpm_strip_newline(line, buf.real_line_size) == 0) {
/* length of stripped line was zero */
continue;
}
if(strcmp(line, "%FILES%") == 0) {
size_t files_size = 0;
while(1) {
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) {
goto error;
}
line = buf.line;
if(_alpm_strip_newline(line, buf.real_line_size) == 0) {
break;
}
if(!_alpm_greedy_grow((void **)&filelist->files, &files_size,
(filelist->count ? (filelist->count + 1) * sizeof(alpm_file_t) : 8 * sizeof(alpm_file_t)))) {
goto error;
}
STRDUP(filelist->files[filelist->count].name, line, goto error);
filelist->count++;
}
_alpm_filelist_sort(filelist);
}
}
if(ret != ARCHIVE_EOF) {
goto error;
}
return 0;
error:
return -1;
}
alpm_db_files_t SYMEXPORT *alpm_db_files_open(alpm_db_t *db)
{
const char *dbpath;
int fd;
struct stat buf;
struct archive *archive;
alpm_db_files_t *files = NULL;
ASSERT(db != NULL, return NULL);
dbpath = _alpm_db_path(db);
if(!dbpath) {
/* pm_errno set in _alpm_db_path() */
return NULL;
}
if(db->status & DB_STATUS_INVALID || db->status & DB_STATUS_MISSING) {
return NULL;
}
fd = _alpm_open_archive(db->handle, dbpath, &buf,
&archive, ALPM_ERR_DB_OPEN);
if(fd < 0) {
db->status &= ~DB_STATUS_VALID;
db->status |= DB_STATUS_INVALID;
_alpm_archive_read_free(archive);
return NULL;
}
MALLOC(files, sizeof(alpm_db_files_t), RET_ERR(db->handle, ALPM_ERR_MEMORY, NULL));
files->archive = archive;
files->fd = fd;
files->db = db;
return files;
}
int SYMEXPORT alpm_db_files_next(alpm_db_files_t *files, char** pkgname)
{
struct archive_entry *entry;
const char *entryname;
int archive_ret;
char *filename;
ASSERT(files != NULL, return -1);
ASSERT(pkgname != NULL, return -1);
while((archive_ret = archive_read_next_header(files->archive, &entry)) == ARCHIVE_OK) {
mode_t mode = archive_entry_mode(entry);
if(!S_ISDIR(mode)) {
entryname = archive_entry_pathname(entry);
if(entryname == NULL) {
_alpm_log(files->db->handle, ALPM_LOG_DEBUG,
"invalid archive entry provided to alpm_db_files_next, skipping\n");
return -1;
}
if(_alpm_splitname(entryname, pkgname, NULL, NULL) != 0) {
_alpm_log(files->db->handle, ALPM_LOG_ERROR,
_("invalid name for database entry '%s'\n"), entryname);
return -1;
}
filename = strrchr(entryname, '/');
filename++;
/* we only want to read the file list */
if(filename && strcmp(filename, "files") == 0) {
return 0;
}
}
}
if(archive_ret != ARCHIVE_EOF) {
return -1;
}
return 1;
}
int SYMEXPORT alpm_db_files_load(alpm_db_files_t *files, alpm_filelist_t *filelist)
{
ASSERT(files != NULL, return -1);
ASSERT(filelist != NULL, return -1);
_alpm_filelist_truncate(filelist);
if(load_files(files->archive, filelist) != 0) {
_alpm_log(files->db->handle, ALPM_LOG_ERROR,
_("could not parse package description file '%s' from db '%s'\n"),
"files", files->db->treename);
return -1;
}
return 0;
}
void SYMEXPORT alpm_db_files_close(alpm_db_files_t *files)
{
ASSERT(files != NULL, return);
_alpm_archive_read_free(files->archive);
close(files->fd);
free(files);
}

View File

@@ -61,13 +61,6 @@ struct db_operations {
void (*unregister) (alpm_db_t *);
};
/* Database files iterator */
struct __alpm_db_files_t {
struct archive *archive;
int fd;
alpm_db_t *db;
};
/* Database */
struct _alpm_db_t {
alpm_handle_t *handle;

View File

@@ -145,17 +145,3 @@ void _alpm_filelist_sort(alpm_filelist_t *filelist)
}
}
}
void _alpm_filelist_truncate(alpm_filelist_t *files)
{
for(size_t i = 0; i < files->count; i++) {
FREE(files->files[i].name);
}
files->count = 0;
}
void SYMEXPORT alpm_filelist_free(alpm_filelist_t *files)
{
_alpm_filelist_truncate(files);
free(files->files);
}

View File

@@ -28,6 +28,5 @@ alpm_list_t *_alpm_filelist_intersection(alpm_filelist_t *filesA,
alpm_filelist_t *filesB);
void _alpm_filelist_sort(alpm_filelist_t *filelist);
void _alpm_filelist_truncate(alpm_filelist_t *filelist);
#endif /* ALPM_FILELIST_H */

View File

@@ -99,7 +99,6 @@ static alpm_list_t *_pkg_get_replaces(alpm_pkg_t *pkg) { return pkg->replaces;
static alpm_filelist_t *_pkg_get_files(alpm_pkg_t *pkg) { return &(pkg->files); }
static alpm_list_t *_pkg_get_backup(alpm_pkg_t *pkg) { return pkg->backup; }
static void *_pkg_changelog_open(alpm_pkg_t UNUSED *pkg)
{
return NULL;

View File

@@ -83,6 +83,7 @@ typedef struct __config_t {
unsigned short op_q_upgrade;
unsigned short op_q_check;
unsigned short op_q_locality;
unsigned short op_q_backup;
unsigned short op_s_clean;
unsigned short op_s_downloadonly;
@@ -180,6 +181,7 @@ enum {
OP_DBPATH,
OP_CASCADE,
OP_CHANGELOG,
OP_BACKUP,
OP_CLEAN,
OP_NODEPS,
OP_DEPS,

View File

@@ -40,8 +40,9 @@ static void print_line_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg, char *fil
fputs("\n", stdout);
}
static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg, alpm_filelist_t *pkgfiles)
static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg)
{
alpm_filelist_t *pkgfiles = alpm_pkg_get_files(pkg);
for(size_t filenum = 0; filenum < pkgfiles->count; filenum++) {
const alpm_file_t *file = pkgfiles->files + filenum;
print_line_machinereadable(db, pkg, file->name);
@@ -107,9 +108,7 @@ static void filetarget_free(struct filetarget *ftarg) {
static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
int ret = 0;
alpm_list_t *t, *s, *filetargs = NULL;
alpm_filelist_t filelist = {0};
char *pkgname = NULL;
alpm_list_t *t, *filetargs = NULL;
for(t = targets; t; t = alpm_list_next(t)) {
char *targ = t->data;
@@ -145,58 +144,43 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
goto cleanup;
}
for(s = syncs; s; s = alpm_list_next(s)) {
alpm_db_t *repo = s->data;
int m;
for(t = filetargs; t; t = alpm_list_next(t)) {
struct filetarget *ftarg = t->data;
char *targ = ftarg->targ;
regex_t *reg = &ftarg->reg;
int exact_file = ftarg->exact_file;
alpm_list_t *s;
int found = 0;
alpm_db_files_t *files = alpm_db_files_open(repo);
for(s = syncs; s; s = alpm_list_next(s)) {
alpm_list_t *p;
alpm_db_t *repo = s->data;
alpm_list_t *packages = alpm_db_get_pkgcache(repo);
int m;
if(!files) {
continue;
}
while(1) {
int ok = alpm_db_files_next(files, &pkgname);
if(ok == 1) {
break;
}
if(ok != 0) {
continue;
}
if(alpm_db_files_load(files, &filelist) != 0) {
ret = 1;
continue;
}
alpm_pkg_t *pkg = alpm_db_get_pkg(repo, pkgname);
for(t = filetargs; t; t = alpm_list_next(t)) {
struct filetarget *ftarg = t->data;
char *targ = ftarg->targ;
regex_t *reg = &ftarg->reg;
int exact_file = ftarg->exact_file;
int found = 0;
for(p = packages; p; p = alpm_list_next(p)) {
alpm_pkg_t *pkg = p->data;
alpm_filelist_t *files = alpm_pkg_get_files(pkg);
alpm_list_t *match = NULL;
if(exact_file) {
if(regex) {
for(size_t f = 0; f < filelist.count; f++) {
char *c = filelist.files[f].name;
if (regex) {
for(size_t f = 0; f < files->count; f++) {
char *c = files->files[f].name;
if(regexec(reg, c, 0, 0, 0) == 0) {
match = alpm_list_add(match, filelist.files[f].name);
match = alpm_list_add(match, files->files[f].name);
found = 1;
}
}
} else {
if(alpm_filelist_contains(&filelist, targ)) {
if(alpm_filelist_contains(files, targ)) {
match = alpm_list_add(match, targ);
found = 1;
}
}
} else {
for(size_t f = 0; f < filelist.count; f++) {
char *c = strrchr(filelist.files[f].name, '/');
for(size_t f = 0; f < files->count; f++) {
char *c = strrchr(files->files[f].name, '/');
if(c && *(c + 1)) {
if(regex) {
m = regexec(reg, (c + 1), 0, 0, 0);
@@ -204,7 +188,7 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
m = strcmp(c + 1, targ);
}
if(m == 0) {
match = alpm_list_add(match, filelist.files[f].name);
match = alpm_list_add(match, files->files[f].name);
found = 1;
}
}
@@ -215,33 +199,28 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
print_match(match, repo, pkg, exact_file);
alpm_list_free(match);
}
if(!found) {
ret = 1;
}
}
}
alpm_db_files_close(files);
if(!found) {
ret = 1;
}
}
cleanup:
alpm_list_free_inner(filetargs, (alpm_list_fn_free) filetarget_free);
alpm_list_free(filetargs);
alpm_filelist_free(&filelist);
if(pkgname) {
free(pkgname);
}
return ret;
}
static void dump_file_list(alpm_pkg_t *pkg, alpm_filelist_t *pkgfiles) {
static void dump_file_list(alpm_pkg_t *pkg) {
const char *pkgname;
alpm_filelist_t *pkgfiles;
size_t i;
pkgname = alpm_pkg_get_name(pkg);
pkgfiles = alpm_pkg_get_files(pkg);
for(i = 0; i < pkgfiles->count; i++) {
const alpm_file_t *file = pkgfiles->files + i;
@@ -260,97 +239,73 @@ static void dump_file_list(alpm_pkg_t *pkg, alpm_filelist_t *pkgfiles) {
static int files_list(alpm_list_t *syncs, alpm_list_t *targets) {
alpm_list_t *i, *j;
int ret = 0;
size_t found = 0;
alpm_filelist_t filelist = {0};
char *pkgname = NULL;
for(j = syncs; j; j = alpm_list_next(j)) {
alpm_db_t *db = j->data;
alpm_db_files_t *files = alpm_db_files_open(db);
if(targets != NULL) {
for(i = targets; i; i = alpm_list_next(i)) {
int found = 0;
char *targ = i->data;
char *repo = NULL;
char *c = strchr(targ, '/');
if(!files) {
continue;
}
while(1) {
int ok = alpm_db_files_next(files, &pkgname);
if(ok == 1) {
break;
}
if(ok != 0) {
continue;
}
if(targets != NULL) {
int match = 0;
for(i = targets; i; i = alpm_list_next(i)) {
char *targ = i->data;
char *c = strchr(targ, '/');
char *repo = NULL;
if(c) {
if(! *(c + 1)) {
pm_printf(ALPM_LOG_ERROR,
_("invalid package: '%s'\n"), targ);
ret = 1;
continue;
}
repo = strndup(targ, c - targ);
targ = c + 1;
}
if(repo) {
if(strcmp(alpm_db_get_name(db), repo) != 0) {
free(repo);
continue;
}
free(repo);
}
if(strcmp(pkgname, targ) == 0) {
match = 1;
found++;
break;
}
}
if(!match) {
if(c) {
if(! *(c + 1)) {
pm_printf(ALPM_LOG_ERROR,
_("invalid package: '%s'\n"), targ);
ret += 1;
continue;
}
repo = strndup(targ, c - targ);
targ = c + 1;
}
for(j = syncs; j; j = alpm_list_next(j)) {
alpm_pkg_t *pkg;
alpm_db_t *db = j->data;
if(alpm_db_files_load(files, &filelist) != 0) {
ret = 1;
continue;
if(repo) {
if(strcmp(alpm_db_get_name(db), repo) != 0) {
continue;
}
}
if((pkg = alpm_db_get_pkg(db, targ)) != NULL) {
found = 1;
if(config->op_f_machinereadable) {
dump_pkg_machinereadable(db, pkg);
} else {
dump_file_list(pkg);
}
break;
}
}
alpm_pkg_t *pkg = alpm_db_get_pkg(db, pkgname);
if(config->op_f_machinereadable) {
dump_pkg_machinereadable(db, pkg, &filelist);
} else {
dump_file_list(pkg, &filelist);
if(!found) {
targ = i->data;
pm_printf(ALPM_LOG_ERROR,
_("package '%s' was not found\n"), targ);
ret += 1;
}
break;
free(repo);
}
alpm_db_files_close(files);
}
} else {
for(i = syncs; i; i = alpm_list_next(i)) {
alpm_db_t *db = i->data;
alpm_filelist_free(&filelist);
if(found != alpm_list_count(targets)) {
ret = 1;
}
if(pkgname) {
free(pkgname);
for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) {
alpm_pkg_t *pkg = j->data;
if(config->op_f_machinereadable) {
dump_pkg_machinereadable(db, pkg);
} else {
dump_file_list(pkg);
}
}
}
}
return ret;
}
int pacman_files(alpm_list_t *targets)
{
alpm_list_t *files_dbs = NULL;

View File

@@ -348,7 +348,7 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
/* Print additional package info if info flag passed more than once */
if(from == ALPM_PKG_FROM_LOCALDB && extra) {
dump_pkg_backups(pkg);
dump_backup_status(pkg);
}
/* final newline to separate packages */
@@ -359,6 +359,34 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra)
alpm_list_free(validation);
}
static int get_backup_file_changed(const char *root,
const alpm_backup_t *backup)
{
char path[PATH_MAX];
int ret = 0;
snprintf(path, PATH_MAX, "%s%s", root, backup->name);
/* if we find the file, calculate checksums, otherwise it is missing */
if(access(path, R_OK) == 0) {
char *md5sum = alpm_compute_md5sum(path);
if(md5sum == NULL) {
pm_printf(ALPM_LOG_ERROR,
_("could not calculate checksums for %s\n"), path);
return 0;
}
/* if checksums don't match, file has been modified */
ret = strcmp(md5sum, backup->hash) != 0;
free(md5sum);
} else if(errno != ENOENT) {
pm_printf(ALPM_LOG_ERROR,
_("could not read %s: %s\n"), path, strerror(errno));
}
return ret;
}
static const char *get_backup_file_status(const char *root,
const alpm_backup_t *backup)
{
@@ -401,7 +429,7 @@ static const char *get_backup_file_status(const char *root,
/* Display list of backup files and their modification states
*/
void dump_pkg_backups(alpm_pkg_t *pkg)
void dump_backup_status(alpm_pkg_t *pkg)
{
alpm_list_t *i;
const char *root = alpm_option_get_root(config->handle);
@@ -450,6 +478,32 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet)
fflush(stdout);
}
void dump_pkg_backups(alpm_pkg_t *pkg, int quiet, int all)
{
const char *pkgname, *root;
alpm_list_t *backups;
alpm_list_t *i;
pkgname = alpm_pkg_get_name(pkg);
backups = alpm_pkg_get_backup(pkg);
root = alpm_option_get_root(config->handle);
for(i = backups; i; i = i->next) {
alpm_backup_t *backup = i->data;
if(!all && backup->hash && !get_backup_file_changed(root, backup)) {
continue;
}
if(!quiet) {
printf("%s%s%s ", config->colstr.title, pkgname, config->colstr.nocolor);
}
printf("%s%s\n", root, backup->name);
}
fflush(stdout);
}
/* Display the changelog of a package
*/
void dump_pkg_changelog(alpm_pkg_t *pkg)

View File

@@ -24,7 +24,8 @@
void dump_pkg_full(alpm_pkg_t *pkg, int extra);
void dump_pkg_backups(alpm_pkg_t *pkg);
void dump_backup_status(alpm_pkg_t *pkg);
void dump_pkg_backups(alpm_pkg_t *pkg, int quiet, int all);
void dump_pkg_files(alpm_pkg_t *pkg, int quiet);
void dump_pkg_changelog(alpm_pkg_t *pkg);

View File

@@ -150,6 +150,7 @@ static void usage(int op, const char * const myname)
addlist(_(" -t, --unrequired list packages not (optionally) required by any\n"
" package (-tt to ignore optdepends) [filter]\n"));
addlist(_(" -u, --upgrades list outdated packages [filter]\n"));
addlist(_(" -w, --backup list modified backup files of a package (-xx for all backup files)\n"));
} else if(op == PM_OP_SYNC) {
printf("%s: %s {-S --sync} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
printf("%s:\n", str_opt);
@@ -516,6 +517,10 @@ static int parsearg_query(int opt)
case 'c':
config->op_q_changelog = 1;
break;
case OP_BACKUP:
case 'w':
(config->op_q_backup)++;
break;
case OP_DEPS:
case 'd':
config->op_q_deps = 1;
@@ -583,6 +588,7 @@ static void checkargs_query_display_opts(const char *opname) {
invalid_opt(config->op_q_check, opname, "--check");
invalid_opt(config->op_q_info, opname, "--info");
invalid_opt(config->op_q_list, opname, "--list");
invalid_opt(config->op_q_backup, opname, "--backup");
}
static void checkargs_query_filter_opts(const char *opname) {
@@ -896,6 +902,7 @@ static int parseargs(int argc, char *argv[])
{"dbpath", required_argument, 0, OP_DBPATH},
{"cascade", no_argument, 0, OP_CASCADE},
{"changelog", no_argument, 0, OP_CHANGELOG},
{"backup", no_argument, 0, OP_BACKUP},
{"clean", no_argument, 0, OP_CLEAN},
{"nodeps", no_argument, 0, OP_NODEPS},
{"deps", no_argument, 0, OP_DEPS},

View File

@@ -315,6 +315,9 @@ static int display(alpm_pkg_t *pkg)
if(config->op_q_list) {
dump_pkg_files(pkg, config->quiet);
}
if(config->op_q_backup) {
dump_pkg_backups(pkg, config->quiet, config->op_q_backup != 1);
}
if(config->op_q_changelog) {
dump_pkg_changelog(pkg);
}
@@ -325,8 +328,8 @@ static int display(alpm_pkg_t *pkg)
ret = check_pkg_full(pkg);
}
}
if(!config->op_q_info && !config->op_q_list
&& !config->op_q_changelog && !config->op_q_check) {
if(!config->op_q_info && !config->op_q_list && !config->op_q_changelog
&& !config->op_q_check && !config->op_q_backup) {
if(!config->quiet) {
const colstr_t *colstr = &config->colstr;
printf("%s%s %s%s%s", colstr->title, alpm_pkg_get_name(pkg),
@@ -431,7 +434,7 @@ int pacman_query(alpm_list_t *targets)
db_local = alpm_get_localdb(config->handle);
/* operations on all packages in the local DB
* valid: no-op (plain -Q), list, info, check
* valid: no-op (plain -Q), list, info, check, backup
* invalid: isfile, owns */
if(targets == NULL) {
if(config->op_q_isfile || config->op_q_owns) {