]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/sysfs-show.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / login / sysfs-show.c
CommitLineData
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
35static 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 157int 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}