]>
Commit | Line | Data |
---|---|---|
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 | 17 | static 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 | 128 | int 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 | } |