]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/sysfs-show.c
core,logind: libudev usage modernizations
[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"
9eb977db 28#include "path-util.h"
1ca208fb 29#include "udev-util.h"
24310c11 30
24310c11
LP
31static 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) {
06acf2d4 45 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
24310c11 46 struct udev_list_entry *next, *lookahead;
88e3dc90 47 const char *sn, *name, *sysfs, *subsystem, *sysname;
06acf2d4 48 _cleanup_free_ char *k = NULL, *l = NULL;
5d1fb81b 49 bool is_master;
24310c11
LP
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
d239d84a 65 /* Explicitly also check for tag 'seat' here */
309c2a2c 66 if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
24310c11
LP
67 *item = udev_list_entry_get_next(*item);
68 continue;
69 }
70
2d96536d 71 is_master = udev_device_has_tag(d, "master-of-seat");
d239d84a 72
24310c11
LP
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)) {
06acf2d4 88 _cleanup_udev_device_unref_ struct udev_device *lookahead_d = NULL;
24310c11
LP
89
90 lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
91 if (lookahead_d) {
92 const char *lookahead_sn;
24310c11
LP
93
94 lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
95 if (isempty(lookahead_sn))
96 lookahead_sn = "seat0";
97
06acf2d4 98 if (streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat"))
24310c11
LP
99 break;
100 }
101 }
102
103 lookahead = udev_list_entry_get_next(lookahead);
104 }
105
88e3dc90 106 k = ellipsize(sysfs, n_columns, 20);
06acf2d4
LP
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);
24310c11 111
88e3dc90 112 if (asprintf(&l,
5d1fb81b
LP
113 "%s%s:%s%s%s%s",
114 is_master ? "[MASTER] " : "",
88e3dc90 115 subsystem, sysname,
06acf2d4 116 name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0)
88e3dc90 117 return -ENOMEM;
88e3dc90 118
88e3dc90 119 free(k);
06acf2d4
LP
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);
24310c11
LP
125
126 *item = next;
127 if (*item) {
06acf2d4 128 _cleanup_free_ char *p = NULL;
24310c11 129
45a5ff0d 130 p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : " ");
06acf2d4
LP
131 if (!p)
132 return -ENOMEM;
24310c11 133
06acf2d4
LP
134 show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
135 }
24310c11
LP
136 }
137
138 return 0;
139}
140
141int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
1ca208fb 142 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
06acf2d4 143 _cleanup_udev_unref_ struct udev *udev = NULL;
24310c11 144 struct udev_list_entry *first = NULL;
24310c11
LP
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);
1ca208fb 161 if (!e)
a051da35 162 return -ENOMEM;
24310c11
LP
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");
e1202047
LP
168 if (r < 0)
169 return r;
24310c11 170
e1202047 171 r = udev_enumerate_add_match_is_initialized(e);
3e085b6c 172 if (r < 0)
1ca208fb 173 return r;
3e085b6c 174
24310c11
LP
175 r = udev_enumerate_scan_devices(e);
176 if (r < 0)
1ca208fb 177 return r;
24310c11
LP
178
179 first = udev_enumerate_get_list_entry(e);
180 if (first)
181 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
182
24310c11
LP
183 return r;
184}