diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:49:52 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:49:52 +0000 |
commit | 55944e5e40b1be2afc4855d8d2baf4b73d1876b5 (patch) | |
tree | 33f869f55a1b149e9b7c2b7e201867ca5dd52992 /src/login/sysfs-show.c | |
parent | Initial commit. (diff) | |
download | systemd-55944e5e40b1be2afc4855d8d2baf4b73d1876b5.tar.xz systemd-55944e5e40b1be2afc4855d8d2baf4b73d1876b5.zip |
Adding upstream version 255.4.upstream/255.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/login/sysfs-show.c')
-rw-r--r-- | src/login/sysfs-show.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c new file mode 100644 index 0000000..0a8c02a --- /dev/null +++ b/src/login/sysfs-show.c @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include <errno.h> + +#include "sd-device.h" + +#include "alloc-util.h" +#include "device-enumerator-private.h" +#include "glyph-util.h" +#include "path-util.h" +#include "string-util.h" +#include "sysfs-show.h" +#include "terminal-util.h" + +static int show_sysfs_one( + const char *seat, + sd_device **dev_list, + size_t *i_dev, + size_t n_dev, + const char *sub, + const char *prefix, + unsigned n_columns, + OutputFlags flags) { + + size_t max_width; + int r; + + assert(seat); + assert(dev_list); + assert(i_dev); + assert(prefix); + + if (flags & OUTPUT_FULL_WIDTH) + max_width = SIZE_MAX; + else if (n_columns < 10) + max_width = 10; + else + max_width = n_columns; + + while (*i_dev < n_dev) { + const char *sysfs, *sn, *name = NULL, *subsystem, *sysname; + _cleanup_free_ char *k = NULL, *l = NULL; + size_t lookahead; + bool is_master; + + if (sd_device_get_syspath(dev_list[*i_dev], &sysfs) < 0 || + !path_startswith(sysfs, sub)) + return 0; + + if (sd_device_get_property_value(dev_list[*i_dev], "ID_SEAT", &sn) < 0 || isempty(sn)) + sn = "seat0"; + + /* Explicitly also check for tag 'seat' here */ + if (!streq(seat, sn) || + sd_device_has_current_tag(dev_list[*i_dev], "seat") <= 0 || + sd_device_get_subsystem(dev_list[*i_dev], &subsystem) < 0 || + sd_device_get_sysname(dev_list[*i_dev], &sysname) < 0) { + (*i_dev)++; + continue; + } + + is_master = sd_device_has_current_tag(dev_list[*i_dev], "master-of-seat") > 0; + + if (sd_device_get_sysattr_value(dev_list[*i_dev], "name", &name) < 0) + (void) sd_device_get_sysattr_value(dev_list[*i_dev], "id", &name); + + /* Look if there's more coming after this */ + for (lookahead = *i_dev + 1; lookahead < n_dev; lookahead++) { + const char *lookahead_sysfs; + + if (sd_device_get_syspath(dev_list[lookahead], &lookahead_sysfs) < 0) + continue; + + if (path_startswith(lookahead_sysfs, sub) && + !path_startswith(lookahead_sysfs, sysfs)) { + const char *lookahead_sn; + + if (sd_device_get_property_value(dev_list[lookahead], "ID_SEAT", &lookahead_sn) < 0 || + isempty(lookahead_sn)) + lookahead_sn = "seat0"; + + if (streq(seat, lookahead_sn) && sd_device_has_current_tag(dev_list[lookahead], "seat") > 0) + break; + } + } + + k = ellipsize(sysfs, max_width, 20); + if (!k) + return -ENOMEM; + + printf("%s%s%s\n", prefix, special_glyph(lookahead < n_dev ? SPECIAL_GLYPH_TREE_BRANCH : SPECIAL_GLYPH_TREE_RIGHT), k); + + if (asprintf(&l, + "%s%s:%s%s%s%s", + is_master ? "[MASTER] " : "", + subsystem, sysname, + name ? " \"" : "", strempty(name), name ? "\"" : "") < 0) + return -ENOMEM; + + free(k); + k = ellipsize(l, max_width, 70); + if (!k) + return -ENOMEM; + + printf("%s%s%s\n", prefix, lookahead < n_dev ? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL) : " ", k); + + if (++(*i_dev) < n_dev) { + _cleanup_free_ char *p = NULL; + + p = strjoin(prefix, lookahead < n_dev ? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL) : " "); + if (!p) + return -ENOMEM; + + r = show_sysfs_one(seat, dev_list, i_dev, n_dev, sysfs, p, + n_columns == UINT_MAX || n_columns < 2 ? n_columns : n_columns - 2, + flags); + if (r < 0) + return r; + } + + } + + return 0; +} + +int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + size_t n_dev = 0, i = 0; + sd_device **dev_list; + int r; + + if (n_columns <= 0) + n_columns = columns(); + + prefix = strempty(prefix); + + if (isempty(seat)) + seat = "seat0"; + + r = sd_device_enumerator_new(&e); + if (r < 0) + return r; + + r = sd_device_enumerator_allow_uninitialized(e); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_tag(e, streq(seat, "seat0") ? "seat" : seat); + if (r < 0) + return r; + + r = device_enumerator_scan_devices(e); + if (r < 0) + return r; + + dev_list = device_enumerator_get_devices(e, &n_dev); + + if (dev_list && n_dev > 0) + show_sysfs_one(seat, dev_list, &i, n_dev, "/", prefix, n_columns, flags); + else + printf("%s%s%s\n", prefix, special_glyph(SPECIAL_GLYPH_TREE_RIGHT), "(none)"); + + return 0; +} |