]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/sysfs-show.c
logind: add infrastructure to watch busnames
[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 #include <libudev.h>
25
26 #include "util.h"
27 #include "sysfs-show.h"
28 #include "path-util.h"
29
30 static int show_sysfs_one(
31 struct udev *udev,
32 const char *seat,
33 struct udev_list_entry **item,
34 const char *sub,
35 const char *prefix,
36 unsigned n_columns) {
37
38 assert(udev);
39 assert(seat);
40 assert(item);
41 assert(prefix);
42
43 while (*item) {
44 struct udev_list_entry *next, *lookahead;
45 struct udev_device *d;
46 const char *sn, *name, *sysfs, *subsystem, *sysname;
47 char *l, *k;
48 bool is_master;
49
50 sysfs = udev_list_entry_get_name(*item);
51 if (!path_startswith(sysfs, sub))
52 return 0;
53
54 d = udev_device_new_from_syspath(udev, sysfs);
55 if (!d) {
56 *item = udev_list_entry_get_next(*item);
57 continue;
58 }
59
60 sn = udev_device_get_property_value(d, "ID_SEAT");
61 if (isempty(sn))
62 sn = "seat0";
63
64 /* Explicitly also check for tag 'seat' here */
65 if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
66 udev_device_unref(d);
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 struct udev_device *lookahead_d;
89
90 lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
91 if (lookahead_d) {
92 const char *lookahead_sn;
93 bool found;
94
95 lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
96 if (isempty(lookahead_sn))
97 lookahead_sn = "seat0";
98
99 found = streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat");
100 udev_device_unref(lookahead_d);
101
102 if (found)
103 break;
104 }
105 }
106
107 lookahead = udev_list_entry_get_next(lookahead);
108 }
109
110 k = ellipsize(sysfs, n_columns, 20);
111 printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT),
112 k ? k : sysfs);
113 free(k);
114
115 if (asprintf(&l,
116 "%s%s:%s%s%s%s",
117 is_master ? "[MASTER] " : "",
118 subsystem, sysname,
119 name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) {
120 udev_device_unref(d);
121 return -ENOMEM;
122 }
123
124 k = ellipsize(l, n_columns, 70);
125 printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : " ",
126 k ? k : l);
127 free(k);
128 free(l);
129
130 *item = next;
131 if (*item) {
132 char *p;
133
134 p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : " ");
135 show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2);
136 free(p);
137 }
138
139 udev_device_unref(d);
140 }
141
142 return 0;
143 }
144
145 int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
146 struct udev *udev;
147 struct udev_list_entry *first = NULL;
148 struct udev_enumerate *e;
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 r = -ENOMEM;
167 goto finish;
168 }
169
170 if (!streq(seat, "seat0"))
171 r = udev_enumerate_add_match_tag(e, seat);
172 else
173 r = udev_enumerate_add_match_tag(e, "seat");
174
175 if (r < 0)
176 goto finish;
177
178 r = udev_enumerate_scan_devices(e);
179 if (r < 0)
180 goto finish;
181
182 first = udev_enumerate_get_list_entry(e);
183 if (first)
184 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
185
186 finish:
187 if (e)
188 udev_enumerate_unref(e);
189
190 if (udev)
191 udev_unref(udev);
192
193 return r;
194 }