]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
24310c11 LP |
2 | /*** |
3 | This file is part of systemd. | |
4 | ||
5 | Copyright 2010 Lennart Poettering | |
6 | ||
7 | systemd is free software; you can redistribute it and/or modify it | |
5430f7f2 LP |
8 | under the terms of the GNU Lesser General Public License as published by |
9 | the Free Software Foundation; either version 2.1 of the License, or | |
24310c11 LP |
10 | (at your option) any later version. |
11 | ||
12 | systemd is distributed in the hope that it will be useful, but | |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
5430f7f2 | 15 | Lesser General Public License for more details. |
24310c11 | 16 | |
5430f7f2 | 17 | You should have received a copy of the GNU Lesser General Public License |
24310c11 LP |
18 | along with systemd; If not, see <http://www.gnu.org/licenses/>. |
19 | ***/ | |
20 | ||
21 | #include <errno.h> | |
22 | #include <string.h> | |
24310c11 | 23 | |
cf0fbc49 | 24 | #include "libudev.h" |
b4bbcaa9 TA |
25 | |
26 | #include "alloc-util.h" | |
8752c575 | 27 | #include "locale-util.h" |
9eb977db | 28 | #include "path-util.h" |
07630cea LP |
29 | #include "string-util.h" |
30 | #include "sysfs-show.h" | |
288a74cc | 31 | #include "terminal-util.h" |
07630cea LP |
32 | #include "udev-util.h" |
33 | #include "util.h" | |
24310c11 | 34 | |
24310c11 LP |
35 | static int show_sysfs_one( |
36 | struct udev *udev, | |
37 | const char *seat, | |
38 | struct udev_list_entry **item, | |
39 | const char *sub, | |
40 | const char *prefix, | |
3850319b LP |
41 | unsigned n_columns, |
42 | OutputFlags flags) { | |
43 | ||
44 | size_t max_width; | |
24310c11 LP |
45 | |
46 | assert(udev); | |
47 | assert(seat); | |
48 | assert(item); | |
49 | assert(prefix); | |
50 | ||
3850319b LP |
51 | if (flags & OUTPUT_FULL_WIDTH) |
52 | max_width = (size_t) -1; | |
53 | else if (n_columns < 10) | |
54 | max_width = 10; | |
55 | else | |
56 | max_width = n_columns; | |
57 | ||
24310c11 | 58 | while (*item) { |
06acf2d4 | 59 | _cleanup_udev_device_unref_ struct udev_device *d = NULL; |
24310c11 | 60 | struct udev_list_entry *next, *lookahead; |
88e3dc90 | 61 | const char *sn, *name, *sysfs, *subsystem, *sysname; |
06acf2d4 | 62 | _cleanup_free_ char *k = NULL, *l = NULL; |
5d1fb81b | 63 | bool is_master; |
24310c11 LP |
64 | |
65 | sysfs = udev_list_entry_get_name(*item); | |
66 | if (!path_startswith(sysfs, sub)) | |
67 | return 0; | |
68 | ||
69 | d = udev_device_new_from_syspath(udev, sysfs); | |
70 | if (!d) { | |
71 | *item = udev_list_entry_get_next(*item); | |
72 | continue; | |
73 | } | |
74 | ||
75 | sn = udev_device_get_property_value(d, "ID_SEAT"); | |
76 | if (isempty(sn)) | |
77 | sn = "seat0"; | |
78 | ||
d239d84a | 79 | /* Explicitly also check for tag 'seat' here */ |
309c2a2c | 80 | if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) { |
24310c11 LP |
81 | *item = udev_list_entry_get_next(*item); |
82 | continue; | |
83 | } | |
84 | ||
2d96536d | 85 | is_master = udev_device_has_tag(d, "master-of-seat"); |
d239d84a | 86 | |
24310c11 LP |
87 | name = udev_device_get_sysattr_value(d, "name"); |
88 | if (!name) | |
89 | name = udev_device_get_sysattr_value(d, "id"); | |
90 | subsystem = udev_device_get_subsystem(d); | |
91 | sysname = udev_device_get_sysname(d); | |
92 | ||
93 | /* Look if there's more coming after this */ | |
94 | lookahead = next = udev_list_entry_get_next(*item); | |
95 | while (lookahead) { | |
96 | const char *lookahead_sysfs; | |
97 | ||
98 | lookahead_sysfs = udev_list_entry_get_name(lookahead); | |
99 | ||
100 | if (path_startswith(lookahead_sysfs, sub) && | |
101 | !path_startswith(lookahead_sysfs, sysfs)) { | |
06acf2d4 | 102 | _cleanup_udev_device_unref_ struct udev_device *lookahead_d = NULL; |
24310c11 LP |
103 | |
104 | lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs); | |
105 | if (lookahead_d) { | |
106 | const char *lookahead_sn; | |
24310c11 LP |
107 | |
108 | lookahead_sn = udev_device_get_property_value(d, "ID_SEAT"); | |
109 | if (isempty(lookahead_sn)) | |
110 | lookahead_sn = "seat0"; | |
111 | ||
06acf2d4 | 112 | if (streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat")) |
24310c11 LP |
113 | break; |
114 | } | |
115 | } | |
116 | ||
117 | lookahead = udev_list_entry_get_next(lookahead); | |
118 | } | |
119 | ||
3850319b | 120 | k = ellipsize(sysfs, max_width, 20); |
06acf2d4 LP |
121 | if (!k) |
122 | return -ENOMEM; | |
123 | ||
323b7dc9 | 124 | printf("%s%s%s\n", prefix, special_glyph(lookahead ? TREE_BRANCH : TREE_RIGHT), k); |
24310c11 | 125 | |
88e3dc90 | 126 | if (asprintf(&l, |
5d1fb81b LP |
127 | "%s%s:%s%s%s%s", |
128 | is_master ? "[MASTER] " : "", | |
88e3dc90 | 129 | subsystem, sysname, |
5cfee414 | 130 | name ? " \"" : "", strempty(name), name ? "\"" : "") < 0) |
88e3dc90 | 131 | return -ENOMEM; |
88e3dc90 | 132 | |
88e3dc90 | 133 | free(k); |
3850319b | 134 | k = ellipsize(l, max_width, 70); |
06acf2d4 LP |
135 | if (!k) |
136 | return -ENOMEM; | |
137 | ||
323b7dc9 | 138 | printf("%s%s%s\n", prefix, lookahead ? special_glyph(TREE_VERTICAL) : " ", k); |
24310c11 LP |
139 | |
140 | *item = next; | |
141 | if (*item) { | |
06acf2d4 | 142 | _cleanup_free_ char *p = NULL; |
24310c11 | 143 | |
323b7dc9 | 144 | p = strappend(prefix, lookahead ? special_glyph(TREE_VERTICAL) : " "); |
06acf2d4 LP |
145 | if (!p) |
146 | return -ENOMEM; | |
24310c11 | 147 | |
3850319b LP |
148 | show_sysfs_one(udev, seat, item, sysfs, p, |
149 | n_columns == (unsigned) -1 || n_columns < 2 ? n_columns : n_columns - 2, | |
150 | flags); | |
06acf2d4 | 151 | } |
24310c11 LP |
152 | } |
153 | ||
154 | return 0; | |
155 | } | |
156 | ||
3850319b | 157 | int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) { |
1ca208fb | 158 | _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; |
06acf2d4 | 159 | _cleanup_udev_unref_ struct udev *udev = NULL; |
24310c11 | 160 | struct udev_list_entry *first = NULL; |
24310c11 LP |
161 | int r; |
162 | ||
163 | if (n_columns <= 0) | |
164 | n_columns = columns(); | |
165 | ||
3850319b | 166 | prefix = strempty(prefix); |
24310c11 LP |
167 | |
168 | if (isempty(seat)) | |
169 | seat = "seat0"; | |
170 | ||
171 | udev = udev_new(); | |
172 | if (!udev) | |
173 | return -ENOMEM; | |
174 | ||
175 | e = udev_enumerate_new(udev); | |
1ca208fb | 176 | if (!e) |
a051da35 | 177 | return -ENOMEM; |
24310c11 LP |
178 | |
179 | if (!streq(seat, "seat0")) | |
180 | r = udev_enumerate_add_match_tag(e, seat); | |
181 | else | |
182 | r = udev_enumerate_add_match_tag(e, "seat"); | |
e1202047 LP |
183 | if (r < 0) |
184 | return r; | |
24310c11 | 185 | |
e1202047 | 186 | r = udev_enumerate_add_match_is_initialized(e); |
3e085b6c | 187 | if (r < 0) |
1ca208fb | 188 | return r; |
3e085b6c | 189 | |
24310c11 LP |
190 | r = udev_enumerate_scan_devices(e); |
191 | if (r < 0) | |
1ca208fb | 192 | return r; |
24310c11 LP |
193 | |
194 | first = udev_enumerate_get_list_entry(e); | |
195 | if (first) | |
3850319b | 196 | show_sysfs_one(udev, seat, &first, "/", prefix, n_columns, flags); |
ddae67fa | 197 | else |
323b7dc9 | 198 | printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), "(none)"); |
24310c11 | 199 | |
24310c11 LP |
200 | return r; |
201 | } |