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