]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/sysfs-show.c
tree-wide: sort includes
[thirdparty/systemd.git] / src / login / sysfs-show.c
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
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
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
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <string.h>
24
25 #include "alloc-util.h"
26 #include "libudev.h"
27 #include "locale-util.h"
28 #include "path-util.h"
29 #include "string-util.h"
30 #include "sysfs-show.h"
31 #include "terminal-util.h"
32 #include "udev-util.h"
33 #include "util.h"
34
35 static 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,
41 unsigned n_columns) {
42
43 assert(udev);
44 assert(seat);
45 assert(item);
46 assert(prefix);
47
48 while (*item) {
49 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
50 struct udev_list_entry *next, *lookahead;
51 const char *sn, *name, *sysfs, *subsystem, *sysname;
52 _cleanup_free_ char *k = NULL, *l = NULL;
53 bool is_master;
54
55 sysfs = udev_list_entry_get_name(*item);
56 if (!path_startswith(sysfs, sub))
57 return 0;
58
59 d = udev_device_new_from_syspath(udev, sysfs);
60 if (!d) {
61 *item = udev_list_entry_get_next(*item);
62 continue;
63 }
64
65 sn = udev_device_get_property_value(d, "ID_SEAT");
66 if (isempty(sn))
67 sn = "seat0";
68
69 /* Explicitly also check for tag 'seat' here */
70 if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
71 *item = udev_list_entry_get_next(*item);
72 continue;
73 }
74
75 is_master = udev_device_has_tag(d, "master-of-seat");
76
77 name = udev_device_get_sysattr_value(d, "name");
78 if (!name)
79 name = udev_device_get_sysattr_value(d, "id");
80 subsystem = udev_device_get_subsystem(d);
81 sysname = udev_device_get_sysname(d);
82
83 /* Look if there's more coming after this */
84 lookahead = next = udev_list_entry_get_next(*item);
85 while (lookahead) {
86 const char *lookahead_sysfs;
87
88 lookahead_sysfs = udev_list_entry_get_name(lookahead);
89
90 if (path_startswith(lookahead_sysfs, sub) &&
91 !path_startswith(lookahead_sysfs, sysfs)) {
92 _cleanup_udev_device_unref_ struct udev_device *lookahead_d = NULL;
93
94 lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
95 if (lookahead_d) {
96 const char *lookahead_sn;
97
98 lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
99 if (isempty(lookahead_sn))
100 lookahead_sn = "seat0";
101
102 if (streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat"))
103 break;
104 }
105 }
106
107 lookahead = udev_list_entry_get_next(lookahead);
108 }
109
110 k = ellipsize(sysfs, n_columns, 20);
111 if (!k)
112 return -ENOMEM;
113
114 printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT), k);
115
116 if (asprintf(&l,
117 "%s%s:%s%s%s%s",
118 is_master ? "[MASTER] " : "",
119 subsystem, sysname,
120 name ? " \"" : "", strempty(name), name ? "\"" : "") < 0)
121 return -ENOMEM;
122
123 free(k);
124 k = ellipsize(l, n_columns, 70);
125 if (!k)
126 return -ENOMEM;
127
128 printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERTICAL) : " ", k);
129
130 *item = next;
131 if (*item) {
132 _cleanup_free_ char *p = NULL;
133
134 p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERTICAL) : " ");
135 if (!p)
136 return -ENOMEM;
137
138 show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
139 }
140 }
141
142 return 0;
143 }
144
145 int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
146 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
147 _cleanup_udev_unref_ struct udev *udev = NULL;
148 struct udev_list_entry *first = NULL;
149 int r;
150
151 if (n_columns <= 0)
152 n_columns = columns();
153
154 if (!prefix)
155 prefix = "";
156
157 if (isempty(seat))
158 seat = "seat0";
159
160 udev = udev_new();
161 if (!udev)
162 return -ENOMEM;
163
164 e = udev_enumerate_new(udev);
165 if (!e)
166 return -ENOMEM;
167
168 if (!streq(seat, "seat0"))
169 r = udev_enumerate_add_match_tag(e, seat);
170 else
171 r = udev_enumerate_add_match_tag(e, "seat");
172 if (r < 0)
173 return r;
174
175 r = udev_enumerate_add_match_is_initialized(e);
176 if (r < 0)
177 return r;
178
179 r = udev_enumerate_scan_devices(e);
180 if (r < 0)
181 return r;
182
183 first = udev_enumerate_get_list_entry(e);
184 if (first)
185 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
186 else
187 printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT), "(none)");
188
189 return r;
190 }