chiark / gitweb /
tree-wide: remove Lennart's copyright lines
[elogind.git] / src / login / sysfs-show.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <string.h>
5
6 #if 0 /// elogind needs the systems udev header
7 #include "libudev.h"
8 #else
9 #include <libudev.h>
10 #endif // 0
11
12 #include "alloc-util.h"
13 #include "locale-util.h"
14 #include "path-util.h"
15 #include "string-util.h"
16 #include "sysfs-show.h"
17 #include "terminal-util.h"
18 #include "udev-util.h"
19 #include "util.h"
20
21 static int show_sysfs_one(
22                 struct udev *udev,
23                 const char *seat,
24                 struct udev_list_entry **item,
25                 const char *sub,
26                 const char *prefix,
27                 unsigned n_columns,
28                 OutputFlags flags) {
29
30         size_t max_width;
31
32         assert(udev);
33         assert(seat);
34         assert(item);
35         assert(prefix);
36
37         if (flags & OUTPUT_FULL_WIDTH)
38                 max_width = (size_t) -1;
39         else if (n_columns < 10)
40                 max_width = 10;
41         else
42                 max_width = n_columns;
43
44         while (*item) {
45                 _cleanup_(udev_device_unrefp) struct udev_device *d = NULL;
46                 struct udev_list_entry *next, *lookahead;
47                 const char *sn, *name, *sysfs, *subsystem, *sysname;
48                 _cleanup_free_ char *k = NULL, *l = NULL;
49                 bool is_master;
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
65                 /* Explicitly also check for tag 'seat' here */
66                 if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
67                         *item = udev_list_entry_get_next(*item);
68                         continue;
69                 }
70
71                 is_master = udev_device_has_tag(d, "master-of-seat");
72
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)) {
88                                 _cleanup_(udev_device_unrefp) struct udev_device *lookahead_d = NULL;
89
90                                 lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
91                                 if (lookahead_d) {
92                                         const char *lookahead_sn;
93
94                                         lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
95                                         if (isempty(lookahead_sn))
96                                                 lookahead_sn = "seat0";
97
98                                         if (streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat"))
99                                                 break;
100                                 }
101                         }
102
103                         lookahead = udev_list_entry_get_next(lookahead);
104                 }
105
106                 k = ellipsize(sysfs, max_width, 20);
107                 if (!k)
108                         return -ENOMEM;
109
110                 printf("%s%s%s\n", prefix, special_glyph(lookahead ? TREE_BRANCH : TREE_RIGHT), k);
111
112                 if (asprintf(&l,
113                              "%s%s:%s%s%s%s",
114                              is_master ? "[MASTER] " : "",
115                              subsystem, sysname,
116                              name ? " \"" : "", strempty(name), name ? "\"" : "") < 0)
117                         return -ENOMEM;
118
119                 free(k);
120                 k = ellipsize(l, max_width, 70);
121                 if (!k)
122                         return -ENOMEM;
123
124                 printf("%s%s%s\n", prefix, lookahead ? special_glyph(TREE_VERTICAL) : "  ", k);
125
126                 *item = next;
127                 if (*item) {
128                         _cleanup_free_ char *p = NULL;
129
130                         p = strappend(prefix, lookahead ? special_glyph(TREE_VERTICAL) : "  ");
131                         if (!p)
132                                 return -ENOMEM;
133
134                         show_sysfs_one(udev, seat, item, sysfs, p,
135                                        n_columns == (unsigned) -1 || n_columns < 2 ? n_columns : n_columns - 2,
136                                        flags);
137                 }
138         }
139
140         return 0;
141 }
142
143 int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) {
144         _cleanup_(udev_enumerate_unrefp) struct udev_enumerate *e = NULL;
145         _cleanup_(udev_unrefp) struct udev *udev = NULL;
146         struct udev_list_entry *first = NULL;
147         int r;
148
149         if (n_columns <= 0)
150                 n_columns = columns();
151
152         prefix = strempty(prefix);
153
154         if (isempty(seat))
155                 seat = "seat0";
156
157         udev = udev_new();
158         if (!udev)
159                 return -ENOMEM;
160
161         e = udev_enumerate_new(udev);
162         if (!e)
163                 return -ENOMEM;
164
165         if (!streq(seat, "seat0"))
166                 r = udev_enumerate_add_match_tag(e, seat);
167         else
168                 r = udev_enumerate_add_match_tag(e, "seat");
169         if (r < 0)
170                 return r;
171
172         r = udev_enumerate_add_match_is_initialized(e);
173         if (r < 0)
174                 return r;
175
176         r = udev_enumerate_scan_devices(e);
177         if (r < 0)
178                 return r;
179
180         first = udev_enumerate_get_list_entry(e);
181         if (first)
182                 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns, flags);
183         else
184                 printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), "(none)");
185
186         return r;
187 }