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