From 66747bfa70fff9298d9ad22a1a5d79f20aa2b070 Mon Sep 17 00:00:00 2001 From: classabbyamp Date: Sun, 19 Feb 2023 21:42:06 -0500 Subject: [PATCH] bin/xbps-query: add --long for -f to show file perms, owner, size --- bin/xbps-query/defs.h | 6 +- bin/xbps-query/main.c | 13 +++-- bin/xbps-query/show-info-files.c | 97 ++++++++++++++++++++++++++++++-- bin/xbps-query/xbps-query.1 | 4 ++ data/_xbps | 1 + 5 files changed, 109 insertions(+), 12 deletions(-) diff --git a/bin/xbps-query/defs.h b/bin/xbps-query/defs.h index 2a1747253..ab5bd397c 100644 --- a/bin/xbps-query/defs.h +++ b/bin/xbps-query/defs.h @@ -39,9 +39,9 @@ void show_pkg_info(xbps_dictionary_t); void show_pkg_info_one(xbps_dictionary_t, const char *); int show_pkg_info_from_metadir(struct xbps_handle *, const char *, const char *); -int show_pkg_files(xbps_dictionary_t); -int show_pkg_files_from_metadir(struct xbps_handle *, const char *); -int repo_show_pkg_files(struct xbps_handle *, const char *); +int show_pkg_files(xbps_dictionary_t, bool); +int show_pkg_files_from_metadir(struct xbps_handle *, const char *, bool); +int repo_show_pkg_files(struct xbps_handle *, const char *, bool); int cat_file(struct xbps_handle *, const char *, const char *); int repo_cat_file(struct xbps_handle *, const char *, const char *); int repo_show_pkg_info(struct xbps_handle *, const char *, const char *); diff --git a/bin/xbps-query/main.c b/bin/xbps-query/main.c index 44316c1ad..992b591e7 100644 --- a/bin/xbps-query/main.c +++ b/bin/xbps-query/main.c @@ -53,6 +53,7 @@ usage(bool fail) " specified multiple times\n" " --regex Use Extended Regular Expressions to match\n" " --fulldeptree Full dependency tree for -x/--deps\n" + " --long Show permissions, ownership, and size for -f/--files\n" " -r, --rootdir Full path to rootdir\n" " -V, --version Show XBPS version\n" " -v, --verbose Verbose messages\n" @@ -100,6 +101,7 @@ main(int argc, char **argv) { "version", no_argument, NULL, 'V' }, { "verbose", no_argument, NULL, 'v' }, { "files", required_argument, NULL, 'f' }, + { "long", no_argument, NULL, 4 }, { "deps", required_argument, NULL, 'x' }, { "revdeps", required_argument, NULL, 'X' }, { "regex", no_argument, NULL, 0 }, @@ -112,14 +114,14 @@ main(int argc, char **argv) int c, flags, rv; bool list_pkgs, list_repos, orphans, own, list_repolock; bool list_manual, list_hold, show_prop, show_files, show_deps, show_rdeps; - bool show, pkg_search, regex, repo_mode, opmode, fulldeptree; + bool show, pkg_search, regex, repo_mode, opmode, fulldeptree, long_listing; rootdir = cachedir = confdir = props = pkg = catfile = NULL; flags = rv = c = 0; list_pkgs = list_repos = list_hold = orphans = pkg_search = own = false; list_manual = list_repolock = show_prop = show_files = false; regex = show = show_deps = show_rdeps = fulldeptree = false; - repo_mode = opmode = false; + repo_mode = opmode = long_listing = false; memset(&xh, 0, sizeof(xh)); @@ -213,6 +215,9 @@ main(int argc, char **argv) case 3: list_repolock = opmode = true; break; + case 4: + long_listing = true; + break; case '?': default: usage(true); @@ -302,9 +307,9 @@ main(int argc, char **argv) } else if (show_files) { /* show-files mode */ if (repo_mode) - rv = repo_show_pkg_files(&xh, pkg); + rv = repo_show_pkg_files(&xh, pkg, long_listing); else - rv = show_pkg_files_from_metadir(&xh, pkg); + rv = show_pkg_files_from_metadir(&xh, pkg, long_listing); } else if (show_deps) { /* show-deps mode */ diff --git a/bin/xbps-query/show-info-files.c b/bin/xbps-query/show-info-files.c index d9fa51748..2021fb9bf 100644 --- a/bin/xbps-query/show-info-files.c +++ b/bin/xbps-query/show-info-files.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include #include "defs.h" @@ -39,6 +41,60 @@ #define _BOLD "\033[1m" #define _RESET "\033[m" +/* +1111 111 111 111 111 +^~~~ ^~~ ^~~ ^~~ ^~~ + | | | | `- other rwx + | | | `- group rwx + | | `- user rwx + | `- suid, sgid, sticky + `- file type +*/ +static void +print_mode(const mode_t mode) { + char hmode[10] = ""; + switch (mode & S_IFMT) { + case S_IFREG: hmode[0] = '-'; break; + case S_IFLNK: hmode[0] = 'l'; break; + case S_IFDIR: hmode[0] = 'd'; break; + default: hmode[0] = '?'; break; + } + hmode[1] = (mode & S_IRUSR) ? 'r' : '-'; + hmode[2] = (mode & S_IWUSR) ? 'w' : '-'; + if ((mode & S_ISUID) && (mode & S_IXUSR)) { + hmode[3] = 's'; + } else if (mode & S_ISUID) { + hmode[3] = 'S'; + } else if (mode & S_IXUSR) { + hmode[3] = 'x'; + } else { + hmode[3] = '-'; + } + hmode[4] = (mode & S_IRGRP) ? 'r' : '-'; + hmode[5] = (mode & S_IWGRP) ? 'w' : '-'; + if ((mode & S_ISGID) && (mode & S_IXGRP)) { + hmode[6] = 's'; + } else if (mode & S_ISGID) { + hmode[6] = 'S'; + } else if (mode & S_IXGRP) { + hmode[6] = 'x'; + } else { + hmode[6] = '-'; + } + hmode[7] = (mode & S_IROTH) ? 'r' : '-'; + hmode[8] = (mode & S_IWOTH) ? 'w' : '-'; + if ((mode & S_ISVTX) && (mode & S_IXOTH)) { + hmode[9] = 't'; + } else if (mode & S_ISVTX) { + hmode[9] = 'T'; + } else if (mode & S_IXOTH) { + hmode[9] = 'x'; + } else { + hmode[9] = '-'; + } + printf("%s\t", hmode); +} + static void print_value_obj(const char *keyname, xbps_object_t obj, const char *indent, const char *bold, @@ -187,11 +243,17 @@ show_pkg_info(xbps_dictionary_t dict) } int -show_pkg_files(xbps_dictionary_t filesd) +show_pkg_files(xbps_dictionary_t filesd, bool long_listing) { xbps_array_t array, allkeys; xbps_object_t obj; xbps_dictionary_keysym_t ksym; + uint64_t size; + uid_t uid; + gid_t gid; + mode_t mode; + struct passwd *user; + struct group *grp; const char *keyname = NULL, *file = NULL; if (xbps_object_type(filesd) != XBPS_TYPE_DICTIONARY) @@ -214,6 +276,31 @@ show_pkg_files(xbps_dictionary_t filesd) obj = xbps_array_get(array, x); if (xbps_object_type(obj) != XBPS_TYPE_DICTIONARY) continue; + if (long_listing) { + mode = uid = gid = size = 0; + if (xbps_dictionary_get_uint32(obj, "mode", &mode)) { + print_mode(mode); + } else { + printf("?\t"); + } + if (xbps_dictionary_get_uint32(obj, "uid", &uid)) { + user = getpwuid(uid); + (user != NULL) ? printf("%s\t", user->pw_name) : printf("%u\t", uid); + } else { + printf("?\t"); + } + if (xbps_dictionary_get_uint32(obj, "gid", &gid)) { + grp = getgrgid(gid); + (grp != NULL) ? printf("%s\t", grp->gr_name) : printf("%u\t", gid); + } else { + printf("?\t"); + } + if (xbps_dictionary_get_uint64(obj, "size", &size)) { + printf("%lu\t", size); + } else { + printf("?\t"); + } + } xbps_dictionary_get_cstring_nocopy(obj, "file", &file); printf("%s", file); if (xbps_dictionary_get_cstring_nocopy(obj, @@ -248,7 +335,7 @@ show_pkg_info_from_metadir(struct xbps_handle *xhp, } int -show_pkg_files_from_metadir(struct xbps_handle *xhp, const char *pkg) +show_pkg_files_from_metadir(struct xbps_handle *xhp, const char *pkg, bool long_listing) { xbps_dictionary_t d; int rv = 0; @@ -257,7 +344,7 @@ show_pkg_files_from_metadir(struct xbps_handle *xhp, const char *pkg) if (d == NULL) return ENOENT; - rv = show_pkg_files(d); + rv = show_pkg_files(d, long_listing); return rv; } @@ -324,7 +411,7 @@ repo_cat_file(struct xbps_handle *xhp, const char *pkg, const char *file) } int -repo_show_pkg_files(struct xbps_handle *xhp, const char *pkg) +repo_show_pkg_files(struct xbps_handle *xhp, const char *pkg, bool long_listing) { xbps_dictionary_t pkgd; int rv; @@ -337,7 +424,7 @@ repo_show_pkg_files(struct xbps_handle *xhp, const char *pkg) return errno; } - rv = show_pkg_files(pkgd); + rv = show_pkg_files(pkgd, long_listing); xbps_object_release(pkgd); return rv; } diff --git a/bin/xbps-query/xbps-query.1 b/bin/xbps-query/xbps-query.1 index b4c364180..0673fbe03 100644 --- a/bin/xbps-query/xbps-query.1 +++ b/bin/xbps-query/xbps-query.1 @@ -129,6 +129,10 @@ modes. Prints a full dependency tree in the .Sy show dependencies mode. +.It Fl -long +Prints permissions, ownership, and filesize in the +.Sy files +mode. .It Fl r, Fl -rootdir Ar dir Specifies a full path for the target root directory. .It Fl v, Fl -verbose diff --git a/data/_xbps b/data/_xbps index 315875717..2514215c1 100644 --- a/data/_xbps +++ b/data/_xbps @@ -154,6 +154,7 @@ _xbps_query() { {-p,--property=-}'[Show properties]:property:($_xbps_properties)' \ --regex'[Use Extended Regular Expressions to match]' \ --fulldeptree'[Full dependency tree for -x/--deps]' \ + --long'[Show permissions, ownership, and size for -f/--files]' \ {-R,--repository}'[Enable repository mode]' \ '*'--repository=-'[Add repository to the top of the list]:repository url:_files -/' \ - '(mode)' \