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