]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/login/sysfs-show.c
util-lib: split our string related calls from util.[ch] into its own file string...
[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>
24310c11 24
07630cea
LP
25#include "libudev.h"
26
9eb977db 27#include "path-util.h"
07630cea
LP
28#include "string-util.h"
29#include "sysfs-show.h"
288a74cc 30#include "terminal-util.h"
07630cea
LP
31#include "udev-util.h"
32#include "util.h"
24310c11 33
24310c11
LP
34static int show_sysfs_one(
35 struct udev *udev,
36 const char *seat,
37 struct udev_list_entry **item,
38 const char *sub,
39 const char *prefix,
40 unsigned n_columns) {
41
42 assert(udev);
43 assert(seat);
44 assert(item);
45 assert(prefix);
46
47 while (*item) {
06acf2d4 48 _cleanup_udev_device_unref_ struct udev_device *d = NULL;
24310c11 49 struct udev_list_entry *next, *lookahead;
88e3dc90 50 const char *sn, *name, *sysfs, *subsystem, *sysname;
06acf2d4 51 _cleanup_free_ char *k = NULL, *l = NULL;
5d1fb81b 52 bool is_master;
24310c11
LP
53
54 sysfs = udev_list_entry_get_name(*item);
55 if (!path_startswith(sysfs, sub))
56 return 0;
57
58 d = udev_device_new_from_syspath(udev, sysfs);
59 if (!d) {
60 *item = udev_list_entry_get_next(*item);
61 continue;
62 }
63
64 sn = udev_device_get_property_value(d, "ID_SEAT");
65 if (isempty(sn))
66 sn = "seat0";
67
d239d84a 68 /* Explicitly also check for tag 'seat' here */
309c2a2c 69 if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
24310c11
LP
70 *item = udev_list_entry_get_next(*item);
71 continue;
72 }
73
2d96536d 74 is_master = udev_device_has_tag(d, "master-of-seat");
d239d84a 75
24310c11
LP
76 name = udev_device_get_sysattr_value(d, "name");
77 if (!name)
78 name = udev_device_get_sysattr_value(d, "id");
79 subsystem = udev_device_get_subsystem(d);
80 sysname = udev_device_get_sysname(d);
81
82 /* Look if there's more coming after this */
83 lookahead = next = udev_list_entry_get_next(*item);
84 while (lookahead) {
85 const char *lookahead_sysfs;
86
87 lookahead_sysfs = udev_list_entry_get_name(lookahead);
88
89 if (path_startswith(lookahead_sysfs, sub) &&
90 !path_startswith(lookahead_sysfs, sysfs)) {
06acf2d4 91 _cleanup_udev_device_unref_ struct udev_device *lookahead_d = NULL;
24310c11
LP
92
93 lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
94 if (lookahead_d) {
95 const char *lookahead_sn;
24310c11
LP
96
97 lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
98 if (isempty(lookahead_sn))
99 lookahead_sn = "seat0";
100
06acf2d4 101 if (streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat"))
24310c11
LP
102 break;
103 }
104 }
105
106 lookahead = udev_list_entry_get_next(lookahead);
107 }
108
88e3dc90 109 k = ellipsize(sysfs, n_columns, 20);
06acf2d4
LP
110 if (!k)
111 return -ENOMEM;
112
113 printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT), k);
24310c11 114
88e3dc90 115 if (asprintf(&l,
5d1fb81b
LP
116 "%s%s:%s%s%s%s",
117 is_master ? "[MASTER] " : "",
88e3dc90 118 subsystem, sysname,
5cfee414 119 name ? " \"" : "", strempty(name), name ? "\"" : "") < 0)
88e3dc90 120 return -ENOMEM;
88e3dc90 121
88e3dc90 122 free(k);
06acf2d4
LP
123 k = ellipsize(l, n_columns, 70);
124 if (!k)
125 return -ENOMEM;
126
7c83910b 127 printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERTICAL) : " ", k);
24310c11
LP
128
129 *item = next;
130 if (*item) {
06acf2d4 131 _cleanup_free_ char *p = NULL;
24310c11 132
7c83910b 133 p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERTICAL) : " ");
06acf2d4
LP
134 if (!p)
135 return -ENOMEM;
24310c11 136
06acf2d4
LP
137 show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
138 }
24310c11
LP
139 }
140
141 return 0;
142}
143
144int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
1ca208fb 145 _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
06acf2d4 146 _cleanup_udev_unref_ struct udev *udev = NULL;
24310c11 147 struct udev_list_entry *first = NULL;
24310c11
LP
148 int r;
149
150 if (n_columns <= 0)
151 n_columns = columns();
152
153 if (!prefix)
154 prefix = "";
155
156 if (isempty(seat))
157 seat = "seat0";
158
159 udev = udev_new();
160 if (!udev)
161 return -ENOMEM;
162
163 e = udev_enumerate_new(udev);
1ca208fb 164 if (!e)
a051da35 165 return -ENOMEM;
24310c11
LP
166
167 if (!streq(seat, "seat0"))
168 r = udev_enumerate_add_match_tag(e, seat);
169 else
170 r = udev_enumerate_add_match_tag(e, "seat");
e1202047
LP
171 if (r < 0)
172 return r;
24310c11 173
e1202047 174 r = udev_enumerate_add_match_is_initialized(e);
3e085b6c 175 if (r < 0)
1ca208fb 176 return r;
3e085b6c 177
24310c11
LP
178 r = udev_enumerate_scan_devices(e);
179 if (r < 0)
1ca208fb 180 return r;
24310c11
LP
181
182 first = udev_enumerate_get_list_entry(e);
183 if (first)
184 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
ddae67fa
LP
185 else
186 printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT), "(none)");
24310c11 187
24310c11
LP
188 return r;
189}