chiark / gitweb /
logind: remove fbdev session-device support
[elogind.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 }