]>
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 | |
24310c11 LP |
6 | ***/ |
7 | ||
8 | #include <errno.h> | |
9 | #include <string.h> | |
24310c11 | 10 | |
cf0fbc49 | 11 | #include "libudev.h" |
b4bbcaa9 TA |
12 | |
13 | #include "alloc-util.h" | |
8752c575 | 14 | #include "locale-util.h" |
9eb977db | 15 | #include "path-util.h" |
07630cea LP |
16 | #include "string-util.h" |
17 | #include "sysfs-show.h" | |
288a74cc | 18 | #include "terminal-util.h" |
07630cea LP |
19 | #include "udev-util.h" |
20 | #include "util.h" | |
24310c11 | 21 | |
24310c11 LP |
22 | static int show_sysfs_one( |
23 | struct udev *udev, | |
24 | const char *seat, | |
25 | struct udev_list_entry **item, | |
26 | const char *sub, | |
27 | const char *prefix, | |
3850319b LP |
28 | unsigned n_columns, |
29 | OutputFlags flags) { | |
30 | ||
31 | size_t max_width; | |
24310c11 LP |
32 | |
33 | assert(udev); | |
34 | assert(seat); | |
35 | assert(item); | |
36 | assert(prefix); | |
37 | ||
3850319b LP |
38 | if (flags & OUTPUT_FULL_WIDTH) |
39 | max_width = (size_t) -1; | |
40 | else if (n_columns < 10) | |
41 | max_width = 10; | |
42 | else | |
43 | max_width = n_columns; | |
44 | ||
24310c11 | 45 | while (*item) { |
06acf2d4 | 46 | _cleanup_udev_device_unref_ struct udev_device *d = NULL; |
24310c11 | 47 | struct udev_list_entry *next, *lookahead; |
88e3dc90 | 48 | const char *sn, *name, *sysfs, *subsystem, *sysname; |
06acf2d4 | 49 | _cleanup_free_ char *k = NULL, *l = NULL; |
5d1fb81b | 50 | bool is_master; |
24310c11 LP |
51 | |
52 | sysfs = udev_list_entry_get_name(*item); | |
53 | if (!path_startswith(sysfs, sub)) | |
54 | return 0; | |
55 | ||
56 | d = udev_device_new_from_syspath(udev, sysfs); | |
57 | if (!d) { | |
58 | *item = udev_list_entry_get_next(*item); | |
59 | continue; | |
60 | } | |
61 | ||
62 | sn = udev_device_get_property_value(d, "ID_SEAT"); | |
63 | if (isempty(sn)) | |
64 | sn = "seat0"; | |
65 | ||
d239d84a | 66 | /* Explicitly also check for tag 'seat' here */ |
309c2a2c | 67 | if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) { |
24310c11 LP |
68 | *item = udev_list_entry_get_next(*item); |
69 | continue; | |
70 | } | |
71 | ||
2d96536d | 72 | is_master = udev_device_has_tag(d, "master-of-seat"); |
d239d84a | 73 | |
24310c11 LP |
74 | name = udev_device_get_sysattr_value(d, "name"); |
75 | if (!name) | |
76 | name = udev_device_get_sysattr_value(d, "id"); | |
77 | subsystem = udev_device_get_subsystem(d); | |
78 | sysname = udev_device_get_sysname(d); | |
79 | ||
80 | /* Look if there's more coming after this */ | |
81 | lookahead = next = udev_list_entry_get_next(*item); | |
82 | while (lookahead) { | |
83 | const char *lookahead_sysfs; | |
84 | ||
85 | lookahead_sysfs = udev_list_entry_get_name(lookahead); | |
86 | ||
87 | if (path_startswith(lookahead_sysfs, sub) && | |
88 | !path_startswith(lookahead_sysfs, sysfs)) { | |
06acf2d4 | 89 | _cleanup_udev_device_unref_ struct udev_device *lookahead_d = NULL; |
24310c11 LP |
90 | |
91 | lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs); | |
92 | if (lookahead_d) { | |
93 | const char *lookahead_sn; | |
24310c11 LP |
94 | |
95 | lookahead_sn = udev_device_get_property_value(d, "ID_SEAT"); | |
96 | if (isempty(lookahead_sn)) | |
97 | lookahead_sn = "seat0"; | |
98 | ||
06acf2d4 | 99 | if (streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat")) |
24310c11 LP |
100 | break; |
101 | } | |
102 | } | |
103 | ||
104 | lookahead = udev_list_entry_get_next(lookahead); | |
105 | } | |
106 | ||
3850319b | 107 | k = ellipsize(sysfs, max_width, 20); |
06acf2d4 LP |
108 | if (!k) |
109 | return -ENOMEM; | |
110 | ||
323b7dc9 | 111 | printf("%s%s%s\n", prefix, special_glyph(lookahead ? TREE_BRANCH : TREE_RIGHT), k); |
24310c11 | 112 | |
88e3dc90 | 113 | if (asprintf(&l, |
5d1fb81b LP |
114 | "%s%s:%s%s%s%s", |
115 | is_master ? "[MASTER] " : "", | |
88e3dc90 | 116 | subsystem, sysname, |
5cfee414 | 117 | name ? " \"" : "", strempty(name), name ? "\"" : "") < 0) |
88e3dc90 | 118 | return -ENOMEM; |
88e3dc90 | 119 | |
88e3dc90 | 120 | free(k); |
3850319b | 121 | k = ellipsize(l, max_width, 70); |
06acf2d4 LP |
122 | if (!k) |
123 | return -ENOMEM; | |
124 | ||
323b7dc9 | 125 | printf("%s%s%s\n", prefix, lookahead ? special_glyph(TREE_VERTICAL) : " ", k); |
24310c11 LP |
126 | |
127 | *item = next; | |
128 | if (*item) { | |
06acf2d4 | 129 | _cleanup_free_ char *p = NULL; |
24310c11 | 130 | |
323b7dc9 | 131 | p = strappend(prefix, lookahead ? special_glyph(TREE_VERTICAL) : " "); |
06acf2d4 LP |
132 | if (!p) |
133 | return -ENOMEM; | |
24310c11 | 134 | |
3850319b LP |
135 | show_sysfs_one(udev, seat, item, sysfs, p, |
136 | n_columns == (unsigned) -1 || n_columns < 2 ? n_columns : n_columns - 2, | |
137 | flags); | |
06acf2d4 | 138 | } |
24310c11 LP |
139 | } |
140 | ||
141 | return 0; | |
142 | } | |
143 | ||
3850319b | 144 | int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) { |
1ca208fb | 145 | _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL; |
06acf2d4 | 146 | _cleanup_udev_unref_ struct udev *udev = NULL; |
24310c11 | 147 | struct udev_list_entry *first = NULL; |
24310c11 LP |
148 | int r; |
149 | ||
150 | if (n_columns <= 0) | |
151 | n_columns = columns(); | |
152 | ||
3850319b | 153 | prefix = strempty(prefix); |
24310c11 LP |
154 | |
155 | if (isempty(seat)) | |
156 | seat = "seat0"; | |
157 | ||
158 | udev = udev_new(); | |
159 | if (!udev) | |
160 | return -ENOMEM; | |
161 | ||
162 | e = udev_enumerate_new(udev); | |
1ca208fb | 163 | if (!e) |
a051da35 | 164 | return -ENOMEM; |
24310c11 LP |
165 | |
166 | if (!streq(seat, "seat0")) | |
167 | r = udev_enumerate_add_match_tag(e, seat); | |
168 | else | |
169 | r = udev_enumerate_add_match_tag(e, "seat"); | |
e1202047 LP |
170 | if (r < 0) |
171 | return r; | |
24310c11 | 172 | |
e1202047 | 173 | r = udev_enumerate_add_match_is_initialized(e); |
3e085b6c | 174 | if (r < 0) |
1ca208fb | 175 | return r; |
3e085b6c | 176 | |
24310c11 LP |
177 | r = udev_enumerate_scan_devices(e); |
178 | if (r < 0) | |
1ca208fb | 179 | return r; |
24310c11 LP |
180 | |
181 | first = udev_enumerate_get_list_entry(e); | |
182 | if (first) | |
3850319b | 183 | show_sysfs_one(udev, seat, &first, "/", prefix, n_columns, flags); |
ddae67fa | 184 | else |
323b7dc9 | 185 | printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), "(none)"); |
24310c11 | 186 | |
24310c11 LP |
187 | return r; |
188 | } |