]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/sysfs-show.c
Merge pull request #11827 from keszybz/pkgconfig-variables
[thirdparty/systemd.git] / src / login / sysfs-show.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
24310c11
LP
2
3#include <errno.h>
4#include <string.h>
24310c11 5
e156d24b 6#include "sd-device.h"
b4bbcaa9
TA
7
8#include "alloc-util.h"
e156d24b 9#include "device-enumerator-private.h"
8752c575 10#include "locale-util.h"
9eb977db 11#include "path-util.h"
07630cea
LP
12#include "string-util.h"
13#include "sysfs-show.h"
288a74cc 14#include "terminal-util.h"
07630cea 15#include "util.h"
24310c11 16
24310c11 17static int show_sysfs_one(
24310c11 18 const char *seat,
e156d24b
YW
19 sd_device **dev_list,
20 size_t *i_dev,
21 size_t n_dev,
24310c11
LP
22 const char *sub,
23 const char *prefix,
3850319b
LP
24 unsigned n_columns,
25 OutputFlags flags) {
26
27 size_t max_width;
e156d24b 28 int r;
24310c11 29
24310c11 30 assert(seat);
e156d24b
YW
31 assert(dev_list);
32 assert(i_dev);
24310c11
LP
33 assert(prefix);
34
3850319b
LP
35 if (flags & OUTPUT_FULL_WIDTH)
36 max_width = (size_t) -1;
37 else if (n_columns < 10)
38 max_width = 10;
39 else
40 max_width = n_columns;
41
e156d24b 42 while (*i_dev < n_dev) {
c679e12a 43 const char *sysfs, *sn, *name = NULL, *subsystem, *sysname;
06acf2d4 44 _cleanup_free_ char *k = NULL, *l = NULL;
e156d24b 45 size_t lookahead;
5d1fb81b 46 bool is_master;
24310c11 47
e156d24b
YW
48 if (sd_device_get_syspath(dev_list[*i_dev], &sysfs) < 0 ||
49 !path_startswith(sysfs, sub))
24310c11
LP
50 return 0;
51
e156d24b 52 if (sd_device_get_property_value(dev_list[*i_dev], "ID_SEAT", &sn) < 0 || isempty(sn))
24310c11
LP
53 sn = "seat0";
54
d239d84a 55 /* Explicitly also check for tag 'seat' here */
c679e12a
YW
56 if (!streq(seat, sn) ||
57 sd_device_has_tag(dev_list[*i_dev], "seat") <= 0 ||
58 sd_device_get_subsystem(dev_list[*i_dev], &subsystem) < 0 ||
59 sd_device_get_sysname(dev_list[*i_dev], &sysname) < 0) {
e156d24b 60 (*i_dev)++;
24310c11
LP
61 continue;
62 }
63
e156d24b
YW
64 is_master = sd_device_has_tag(dev_list[*i_dev], "master-of-seat") > 0;
65
66 if (sd_device_get_sysattr_value(dev_list[*i_dev], "name", &name) < 0)
67 (void) sd_device_get_sysattr_value(dev_list[*i_dev], "id", &name);
d239d84a 68
24310c11 69 /* Look if there's more coming after this */
e156d24b 70 for (lookahead = *i_dev + 1; lookahead < n_dev; lookahead++) {
24310c11
LP
71 const char *lookahead_sysfs;
72
e156d24b
YW
73 if (sd_device_get_syspath(dev_list[lookahead], &lookahead_sysfs) < 0)
74 continue;
24310c11
LP
75
76 if (path_startswith(lookahead_sysfs, sub) &&
77 !path_startswith(lookahead_sysfs, sysfs)) {
e156d24b 78 const char *lookahead_sn;
24310c11 79
e156d24b
YW
80 if (sd_device_get_property_value(dev_list[lookahead], "ID_SEAT", &lookahead_sn) < 0 ||
81 isempty(lookahead_sn))
82 lookahead_sn = "seat0";
24310c11 83
e156d24b
YW
84 if (streq(seat, lookahead_sn) && sd_device_has_tag(dev_list[lookahead], "seat") > 0)
85 break;
24310c11 86 }
24310c11
LP
87 }
88
3850319b 89 k = ellipsize(sysfs, max_width, 20);
06acf2d4
LP
90 if (!k)
91 return -ENOMEM;
92
9a6f746f 93 printf("%s%s%s\n", prefix, special_glyph(lookahead < n_dev ? SPECIAL_GLYPH_TREE_BRANCH : SPECIAL_GLYPH_TREE_RIGHT), k);
24310c11 94
88e3dc90 95 if (asprintf(&l,
5d1fb81b
LP
96 "%s%s:%s%s%s%s",
97 is_master ? "[MASTER] " : "",
88e3dc90 98 subsystem, sysname,
5cfee414 99 name ? " \"" : "", strempty(name), name ? "\"" : "") < 0)
88e3dc90 100 return -ENOMEM;
88e3dc90 101
88e3dc90 102 free(k);
3850319b 103 k = ellipsize(l, max_width, 70);
06acf2d4
LP
104 if (!k)
105 return -ENOMEM;
106
9a6f746f 107 printf("%s%s%s\n", prefix, lookahead < n_dev ? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL) : " ", k);
24310c11 108
e156d24b 109 if (++(*i_dev) < n_dev) {
06acf2d4 110 _cleanup_free_ char *p = NULL;
24310c11 111
9a6f746f 112 p = strappend(prefix, lookahead < n_dev ? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL) : " ");
06acf2d4
LP
113 if (!p)
114 return -ENOMEM;
24310c11 115
e156d24b
YW
116 r = show_sysfs_one(seat, dev_list, i_dev, n_dev, sysfs, p,
117 n_columns == (unsigned) -1 || n_columns < 2 ? n_columns : n_columns - 2,
118 flags);
119 if (r < 0)
120 return r;
06acf2d4 121 }
e156d24b 122
24310c11
LP
123 }
124
125 return 0;
126}
127
3850319b 128int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) {
e156d24b 129 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
e132a043
YW
130 size_t n_dev = 0, i = 0;
131 sd_device **dev_list;
24310c11
LP
132 int r;
133
134 if (n_columns <= 0)
135 n_columns = columns();
136
3850319b 137 prefix = strempty(prefix);
24310c11
LP
138
139 if (isempty(seat))
140 seat = "seat0";
141
e156d24b
YW
142 r = sd_device_enumerator_new(&e);
143 if (r < 0)
144 return r;
24310c11 145
e156d24b 146 r = sd_device_enumerator_allow_uninitialized(e);
e1202047
LP
147 if (r < 0)
148 return r;
24310c11 149
e156d24b 150 r = sd_device_enumerator_add_match_tag(e, streq(seat, "seat0") ? "seat" : seat);
3e085b6c 151 if (r < 0)
1ca208fb 152 return r;
3e085b6c 153
e156d24b 154 r = device_enumerator_scan_devices(e);
24310c11 155 if (r < 0)
1ca208fb 156 return r;
24310c11 157
e132a043 158 dev_list = device_enumerator_get_devices(e, &n_dev);
e156d24b 159
e132a043 160 if (dev_list && n_dev > 0)
e156d24b 161 show_sysfs_one(seat, dev_list, &i, n_dev, "/", prefix, n_columns, flags);
ddae67fa 162 else
9a6f746f 163 printf("%s%s%s\n", prefix, special_glyph(SPECIAL_GLYPH_TREE_RIGHT), "(none)");
24310c11 164
e156d24b 165 return 0;
24310c11 166}