chiark / gitweb /
nspawn: fix getent fallback
[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 #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         else
183                 printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT), "(none)");
184
185         return r;
186 }