1 /* SPDX-License-Identifier: LGPL-2.1+ */
8 #include "alloc-util.h"
9 #include "device-enumerator-private.h"
10 #include "locale-util.h"
11 #include "path-util.h"
12 #include "string-util.h"
13 #include "sysfs-show.h"
14 #include "terminal-util.h"
17 static int show_sysfs_one(
35 if (flags
& OUTPUT_FULL_WIDTH
)
36 max_width
= (size_t) -1;
37 else if (n_columns
< 10)
40 max_width
= n_columns
;
42 while (*i_dev
< n_dev
) {
43 const char *sysfs
, *sn
, *name
= NULL
, *subsystem
, *sysname
;
44 _cleanup_free_
char *k
= NULL
, *l
= NULL
;
48 if (sd_device_get_syspath(dev_list
[*i_dev
], &sysfs
) < 0 ||
49 !path_startswith(sysfs
, sub
))
52 if (sd_device_get_property_value(dev_list
[*i_dev
], "ID_SEAT", &sn
) < 0 || isempty(sn
))
55 /* Explicitly also check for tag 'seat' here */
56 if (!streq(seat
, sn
) ||
57 sd_device_has_tag(dev_list
[*i_dev
], "seat") <= 0 ||
58 sd_device_get_subsystem(dev_list
[*i_dev
], &subsystem
) < 0 ||
59 sd_device_get_sysname(dev_list
[*i_dev
], &sysname
) < 0) {
64 is_master
= sd_device_has_tag(dev_list
[*i_dev
], "master-of-seat") > 0;
66 if (sd_device_get_sysattr_value(dev_list
[*i_dev
], "name", &name
) < 0)
67 (void) sd_device_get_sysattr_value(dev_list
[*i_dev
], "id", &name
);
69 /* Look if there's more coming after this */
70 for (lookahead
= *i_dev
+ 1; lookahead
< n_dev
; lookahead
++) {
71 const char *lookahead_sysfs
;
73 if (sd_device_get_syspath(dev_list
[lookahead
], &lookahead_sysfs
) < 0)
76 if (path_startswith(lookahead_sysfs
, sub
) &&
77 !path_startswith(lookahead_sysfs
, sysfs
)) {
78 const char *lookahead_sn
;
80 if (sd_device_get_property_value(dev_list
[lookahead
], "ID_SEAT", &lookahead_sn
) < 0 ||
81 isempty(lookahead_sn
))
82 lookahead_sn
= "seat0";
84 if (streq(seat
, lookahead_sn
) && sd_device_has_tag(dev_list
[lookahead
], "seat") > 0)
89 k
= ellipsize(sysfs
, max_width
, 20);
93 printf("%s%s%s\n", prefix
, special_glyph(lookahead
< n_dev
? SPECIAL_GLYPH_TREE_BRANCH
: SPECIAL_GLYPH_TREE_RIGHT
), k
);
97 is_master
? "[MASTER] " : "",
99 name
? " \"" : "", strempty(name
), name
? "\"" : "") < 0)
103 k
= ellipsize(l
, max_width
, 70);
107 printf("%s%s%s\n", prefix
, lookahead
< n_dev
? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL
) : " ", k
);
109 if (++(*i_dev
) < n_dev
) {
110 _cleanup_free_
char *p
= NULL
;
112 p
= strjoin(prefix
, lookahead
< n_dev
? special_glyph(SPECIAL_GLYPH_TREE_VERTICAL
) : " ");
116 r
= show_sysfs_one(seat
, dev_list
, i_dev
, n_dev
, sysfs
, p
,
117 n_columns
== (unsigned) -1 || n_columns
< 2 ? n_columns
: n_columns
- 2,
128 int show_sysfs(const char *seat
, const char *prefix
, unsigned n_columns
, OutputFlags flags
) {
129 _cleanup_(sd_device_enumerator_unrefp
) sd_device_enumerator
*e
= NULL
;
130 size_t n_dev
= 0, i
= 0;
131 sd_device
**dev_list
;
135 n_columns
= columns();
137 prefix
= strempty(prefix
);
142 r
= sd_device_enumerator_new(&e
);
146 r
= sd_device_enumerator_allow_uninitialized(e
);
150 r
= sd_device_enumerator_add_match_tag(e
, streq(seat
, "seat0") ? "seat" : seat
);
154 r
= device_enumerator_scan_devices(e
);
158 dev_list
= device_enumerator_get_devices(e
, &n_dev
);
160 if (dev_list
&& n_dev
> 0)
161 show_sysfs_one(seat
, dev_list
, &i
, n_dev
, "/", prefix
, n_columns
, flags
);
163 printf("%s%s%s\n", prefix
, special_glyph(SPECIAL_GLYPH_TREE_RIGHT
), "(none)");