Signed-off-by: Florian Pritz <bluewind@xinu.at> --- doc/pacman.8.txt | 4 +++ src/pacman/conf.h | 2 ++ src/pacman/files.c | 70 ++++++++++++++++++++++++++++++++++++++--------------- src/pacman/pacman.c | 6 +++++ 4 files changed, 63 insertions(+), 19 deletions(-) diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index a4dd1f0..8aff288 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -473,6 +473,10 @@ The '--list', '--search' and '--owns' options are exclusive and can not be combi *-o <file>, \--owns<file>*:: Search for packages that own a particular file. +*--machinereadable*:: + Use a machine readable output format for '--list', '--search' and + '--owns'. The format is 'repository/pkgname pkgver path'. + Handling Config Files[[HCF]] ---------------------------- diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 3fff900..1760b07 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -89,6 +89,7 @@ typedef struct __config_t { unsigned short op_s_upgrade; unsigned short op_f_regex; + unsigned short op_f_machinereadable; unsigned short group; unsigned short noask; @@ -190,6 +191,7 @@ enum { OP_RECURSIVE, OP_SEARCH, OP_REGEX, + OP_MACHINEREADABLE, OP_UNREQUIRED, OP_UPGRADES, OP_SYSUPGRADE, diff --git a/src/pacman/files.c b/src/pacman/files.c index feda75d..33825df 100644 --- a/src/pacman/files.c +++ b/src/pacman/files.c @@ -27,6 +27,15 @@ #include "conf.h" #include "package.h" +static void dump_pkg_machinereadable(alpm_db_t *db, alpm_pkg_t *pkg) { + alpm_filelist_t *pkgfiles = alpm_pkg_get_files(pkg); + const char *root = alpm_option_get_root(config->handle); + for(size_t filenum = 0; filenum < pkgfiles->count; filenum++) { + const alpm_file_t *file = pkgfiles->files + filenum; + printf("%s/%s %s %s%s\n", alpm_db_get_name(db), alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg), root, file->name); + } +} static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) { int ret = 0; @@ -59,13 +68,17 @@ static int files_fileowner(alpm_list_t *syncs, alpm_list_t *targets) { alpm_filelist_t *files = alpm_pkg_get_files(pkg); if(alpm_filelist_contains(files, f)) { - - if(!config->quiet) { - printf(_("/%s is owned by %s/%s %s\n"), f, - alpm_db_get_name(repo), alpm_pkg_get_name(pkg), - alpm_pkg_get_version(pkg)); + if(config->op_f_machinereadable) { + printf("%s/%s %s /%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg), f); } else { - printf("%s/%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg)); + if(!config->quiet) { + printf(_("/%s is owned by %s/%s %s\n"), f, + alpm_db_get_name(repo), alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg)); + } else { + printf("%s/%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg)); + } } found = 1; @@ -137,19 +150,28 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { } if(match != NULL) { - if(config->quiet) { - printf("%s/%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg)); - } else { + if(config->op_f_machinereadable) { alpm_list_t *ml; - printf("%s%s/%s%s %s%s%s\n", colstr->repo, alpm_db_get_name(repo), - colstr->title, alpm_pkg_get_name(pkg), - colstr->version, alpm_pkg_get_version(pkg), colstr->nocolor); - for(ml = match; ml; ml = alpm_list_next(ml)) { - c = ml->data; - printf(" /%s\n", c); + char *filename = ml->data; + printf("%s/%s %s /%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg), filename); + } + } else { + if(config->quiet) { + printf("%s/%s\n", alpm_db_get_name(repo), alpm_pkg_get_name(pkg)); + } else { + alpm_list_t *ml; + printf("%s%s/%s%s %s%s%s\n", colstr->repo, alpm_db_get_name(repo), + colstr->title, alpm_pkg_get_name(pkg), + colstr->version, alpm_pkg_get_version(pkg), colstr->nocolor); + + for(ml = match; ml; ml = alpm_list_next(ml)) { + c = ml->data; + printf(" /%s\n", c); + } + FREELIST(match); } - FREELIST(match); } } } @@ -200,8 +222,14 @@ static int files_list(alpm_list_t *syncs, alpm_list_t *targets) { if((pkg = alpm_db_get_pkg(db, targ)) != NULL) { found = 1; - dump_pkg_files(pkg, config->quiet); - break; + if(config->op_f_machinereadable) { + dump_pkg_machinereadable(db, pkg); + // list all repos if not asked for a specific one + continue; + } else { + dump_pkg_files(pkg, config->quiet); + break; + } } } if(!found) { @@ -218,7 +246,11 @@ static int files_list(alpm_list_t *syncs, alpm_list_t *targets) { for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) { alpm_pkg_t *pkg = j->data; - dump_pkg_files(pkg, config->quiet); + if(config->op_f_machinereadable) { + dump_pkg_machinereadable(db, pkg); + } else { + dump_pkg_files(pkg, config->quiet); + } } } } diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index c680067..0bb1b39 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -181,6 +181,8 @@ static void usage(int op, const char * const myname) addlist(_(" -x, --regex enable searching using regular expressions\n")); addlist(_(" -y, --refresh download fresh package databases from the server\n" " (-yy to force a refresh even if up to date)\n")); + addlist(_(" --machinereadable\n" + " produce machine-readable output\n")); } switch(op) { case PM_OP_SYNC: @@ -792,6 +794,9 @@ static int parsearg_files(int opt) case 'x': config->op_f_regex = 1; break; + case OP_MACHINEREADABLE: + config->op_f_machinereadable = 1; + break; case OP_QUIET: case 'q': config->quiet = 1; @@ -941,6 +946,7 @@ static int parseargs(int argc, char *argv[]) {"recursive", no_argument, 0, OP_RECURSIVE}, {"search", no_argument, 0, OP_SEARCH}, {"regex", no_argument, 0, OP_REGEX}, + {"machinereadable", no_argument, 0, OP_MACHINEREADABLE}, {"unrequired", no_argument, 0, OP_UNREQUIRED}, {"upgrades", no_argument, 0, OP_UPGRADES}, {"sysupgrade", no_argument, 0, OP_SYSUPGRADE}, -- 2.6.2