]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/sysfs-show.c
relicense to LGPLv2.1 (with exceptions)
[thirdparty/systemd.git] / src / login / sysfs-show.c
CommitLineData
24310c11
LP
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
5430f7f2
LP
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
24310c11
LP
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
5430f7f2 16 Lesser General Public License for more details.
24310c11 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
24310c11
LP
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
24310c11
LP
29static 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;
88e3dc90
LP
45 const char *sn, *name, *sysfs, *subsystem, *sysname;
46 char *l, *k;
24310c11
LP
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 */
309c2a2c 63 if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
24310c11
LP
64 udev_device_unref(d);
65 *item = udev_list_entry_get_next(*item);
66 continue;
67 }
68
24310c11
LP
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
309c2a2c 95 found = streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat");
24310c11
LP
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
88e3dc90
LP
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);
24310c11 109
88e3dc90
LP
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);
24310c11
LP
122
123 *item = next;
124 if (*item) {
125 char *p;
126
127 p = strappend(prefix, lookahead ? "\342\224\202 " : " ");
88e3dc90 128 show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2);
24310c11
LP
129 free(p);
130 }
131
132 udev_device_unref(d);
133 }
134
135 return 0;
136}
137
138int 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
3e085b6c
LP
168 if (r < 0)
169 goto finish;
170
24310c11
LP
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
179finish:
180 if (e)
181 udev_enumerate_unref(e);
182
183 if (udev)
184 udev_unref(udev);
185
186 return r;
187}