1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
7 #include "alloc-util.h"
8 #include "device-enumerator-private.h"
9 #include "locale-util.h"
10 #include "path-util.h"
11 #include "string-util.h"
12 #include "sysfs-show.h"
13 #include "terminal-util.h"
16 static int show_sysfs_one(
34 if (flags
& OUTPUT_FULL_WIDTH
)
35 max_width
= (size_t) -1;
36 else if (n_columns
< 10)
39 max_width
= n_columns
;
41 while (*i_dev
< n_dev
) {
42 const char *sysfs
, *sn
, *name
= NULL
, *subsystem
, *sysname
;
43 _cleanup_free_
char *k
= NULL
, *l
= NULL
;
47 if (sd_device_get_syspath(dev_list
[*i_dev
], &sysfs
) < 0 ||
48 !path_startswith(sysfs
, sub
))
51 if (sd_device_get_property_value(dev_list
[*i_dev
], "ID_SEAT", &sn
) < 0 || isempty(sn
))
54 /* Explicitly also check for tag 'seat' here */
55 if (!streq(seat
, sn
) ||
56 sd_device_has_current_tag(dev_list
[*i_dev
], "seat") <= 0 ||
57 sd_device_get_subsystem(dev_list
[*i_dev
], &subsystem
) < 0 ||
58 sd_device_get_sysname(dev_list
[*i_dev
], &sysname
) < 0) {
63 is_master
= sd_device_has_current_tag(dev_list
[*i_dev
], "master-of-seat") > 0;
65 if (sd_device_get_sysattr_value(dev_list
[*i_dev
], "name", &name
) < 0)
66 (void) sd_device_get_sysattr_value(dev_list
[*i_dev
], "id", &name
);
68 /* Look if there's more coming after this */
69 for (lookahead
= *i_dev
+ 1; lookahead
< n_dev
; lookahead
++) {
70 const char *lookahead_sysfs
;
72 if (sd_device_get_syspath(dev_list
[lookahead
], &lookahead_sysfs
) < 0)
75 if (path_startswith(lookahead_sysfs
, sub
) &&
76 !path_startswith(lookahead_sysfs
, sysfs
)) {
77 const char *lookahead_sn
;
79 if (sd_device_get_property_value(dev_list
[lookahead
], "ID_SEAT", &lookahead_sn
) < 0 ||
80 isempty(lookahead_sn
))
81 lookahead_sn
= "seat0";
83 if (streq(seat
, lookahead_sn
) && sd_device_has_current_tag(dev_list
[lookahead
], "seat") > 0)
88 k
= ellipsize(sysfs
, max_width
, 20);
92 printf("%s%s%s\n", prefix
, special_glyph(lookahead
< n_dev
? SPECIAL_GLYPH_TREE_BRANCH
: SPECIAL_GLYPH_TREE_RIGHT
), k
);
96 is_master
? "[MASTER] " : "",
98 name
? " \"" : "", strempty(name
), name
? "\"" : "") < 0)
102 k
= ellipsize(l
, max_width
, 70);
106 printf("%s%s%s\n", prefix
, lookahead
< n_dev
? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL
) : " ", k
);
108 if (++(*i_dev
) < n_dev
) {
109 _cleanup_free_
char *p
= NULL
;
111 p
= strjoin(prefix
, lookahead
< n_dev
? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL
) : " ");
115 r
= show_sysfs_one(seat
, dev_list
, i_dev
, n_dev
, sysfs
, p
,
116 n_columns
== (unsigned) -1 || n_columns
< 2 ? n_columns
: n_columns
- 2,
127 int show_sysfs(const char *seat
, const char *prefix
, unsigned n_columns
, OutputFlags flags
) {
128 _cleanup_(sd_device_enumerator_unrefp
) sd_device_enumerator
*e
= NULL
;
129 size_t n_dev
= 0, i
= 0;
130 sd_device
**dev_list
;
134 n_columns
= columns();
136 prefix
= strempty(prefix
);
141 r
= sd_device_enumerator_new(&e
);
145 r
= sd_device_enumerator_allow_uninitialized(e
);
149 r
= sd_device_enumerator_add_match_tag(e
, streq(seat
, "seat0") ? "seat" : seat
);
153 r
= device_enumerator_scan_devices(e
);
157 dev_list
= device_enumerator_get_devices(e
, &n_dev
);
159 if (dev_list
&& n_dev
> 0)
160 show_sysfs_one(seat
, dev_list
, &i
, n_dev
, "/", prefix
, n_columns
, flags
);
162 printf("%s%s%s\n", prefix
, special_glyph(SPECIAL_GLYPH_TREE_RIGHT
), "(none)");