]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/sysfs-show.c
core,logind: libudev usage modernizations
[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 #include "udev-util.h"
30
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) {
45 _cleanup_udev_device_unref_ 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_unref_ 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, n_columns, 20);
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);
111
112 if (asprintf(&l,
113 "%s%s:%s%s%s%s",
114 is_master ? "[MASTER] " : "",
115 subsystem, sysname,
116 name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0)
117 return -ENOMEM;
118
119 free(k);
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);
125
126 *item = next;
127 if (*item) {
128 _cleanup_free_ char *p = NULL;
129
130 p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : " ");
131 if (!p)
132 return -ENOMEM;
133
134 show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
135 }
136 }
137
138 return 0;
139 }
140
141 int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
142 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
143 _cleanup_udev_unref_ struct udev *udev = NULL;
144 struct udev_list_entry *first = NULL;
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);
161 if (!e)
162 return -ENOMEM;
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");
168 if (r < 0)
169 return r;
170
171 r = udev_enumerate_add_match_is_initialized(e);
172 if (r < 0)
173 return r;
174
175 r = udev_enumerate_scan_devices(e);
176 if (r < 0)
177 return r;
178
179 first = udev_enumerate_get_list_entry(e);
180 if (first)
181 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
182
183 return r;
184 }