chiark / gitweb /
b0edc33b8031c418d0b8e6a7dc599d45b1052231
[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
29 static int show_sysfs_one(
30                 struct udev *udev,
31                 const char *seat,
32                 struct udev_list_entry **item,
33                 const char *sub,
34                 const char *prefix,
35                 unsigned n_columns) {
36
37         assert(udev);
38         assert(seat);
39         assert(item);
40         assert(prefix);
41
42         while (*item) {
43                 struct udev_list_entry *next, *lookahead;
44                 struct udev_device *d;
45                 const char *sn, *name, *sysfs, *subsystem, *sysname;
46                 char *l, *k;
47
48                 sysfs = udev_list_entry_get_name(*item);
49                 if (!path_startswith(sysfs, sub))
50                         return 0;
51
52                 d = udev_device_new_from_syspath(udev, sysfs);
53                 if (!d) {
54                         *item = udev_list_entry_get_next(*item);
55                         continue;
56                 }
57
58                 sn = udev_device_get_property_value(d, "ID_SEAT");
59                 if (isempty(sn))
60                         sn = "seat0";
61
62                 /* fixme, also check for tag 'seat' here */
63                 if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
64                         udev_device_unref(d);
65                         *item = udev_list_entry_get_next(*item);
66                         continue;
67                 }
68
69                 name = udev_device_get_sysattr_value(d, "name");
70                 if (!name)
71                         name = udev_device_get_sysattr_value(d, "id");
72                 subsystem = udev_device_get_subsystem(d);
73                 sysname = udev_device_get_sysname(d);
74
75                 /* Look if there's more coming after this */
76                 lookahead = next = udev_list_entry_get_next(*item);
77                 while (lookahead) {
78                         const char *lookahead_sysfs;
79
80                         lookahead_sysfs = udev_list_entry_get_name(lookahead);
81
82                         if (path_startswith(lookahead_sysfs, sub) &&
83                             !path_startswith(lookahead_sysfs, sysfs)) {
84                                 struct udev_device *lookahead_d;
85
86                                 lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
87                                 if (lookahead_d) {
88                                         const char *lookahead_sn;
89                                         bool found;
90
91                                         lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
92                                         if (isempty(lookahead_sn))
93                                                 lookahead_sn = "seat0";
94
95                                         found = streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat");
96                                         udev_device_unref(lookahead_d);
97
98                                         if (found)
99                                                 break;
100                                 }
101                         }
102
103                         lookahead = udev_list_entry_get_next(lookahead);
104                 }
105
106                 k = ellipsize(sysfs, n_columns, 20);
107                 printf("%s%s %s\n", prefix, lookahead ? "\342\224\234" : "\342\224\224", k ? k : sysfs);
108                 free(k);
109
110                 if (asprintf(&l,
111                              "(%s:%s)%s%s%s",
112                              subsystem, sysname,
113                              name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) {
114                         udev_device_unref(d);
115                         return -ENOMEM;
116                 }
117
118                 k = ellipsize(l, n_columns, 70);
119                 printf("%s%s %s\n", prefix, lookahead ? "\342\224\202" : " ", k ? k : l);
120                 free(k);
121                 free(l);
122
123                 *item = next;
124                 if (*item) {
125                         char *p;
126
127                         p = strappend(prefix, lookahead ? "\342\224\202 " : "  ");
128                         show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2);
129                         free(p);
130                 }
131
132                 udev_device_unref(d);
133         }
134
135         return 0;
136 }
137
138 int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
139         struct udev *udev;
140         struct udev_list_entry *first = NULL;
141         struct udev_enumerate *e;
142         int r;
143
144         if (n_columns <= 0)
145                 n_columns = columns();
146
147         if (!prefix)
148                 prefix = "";
149
150         if (isempty(seat))
151                 seat = "seat0";
152
153         udev = udev_new();
154         if (!udev)
155                 return -ENOMEM;
156
157         e = udev_enumerate_new(udev);
158         if (!e) {
159                 r = -ENOMEM;
160                 goto finish;
161         }
162
163         if (!streq(seat, "seat0"))
164                 r = udev_enumerate_add_match_tag(e, seat);
165         else
166                 r = udev_enumerate_add_match_tag(e, "seat");
167
168         if (r < 0)
169                 goto finish;
170
171         r = udev_enumerate_scan_devices(e);
172         if (r < 0)
173                 goto finish;
174
175         first = udev_enumerate_get_list_entry(e);
176         if (first)
177                 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
178
179 finish:
180         if (e)
181                 udev_enumerate_unref(e);
182
183         if (udev)
184                 udev_unref(udev);
185
186         return r;
187 }