Systemd/src/login/sysfs-show.c
Zbigniew Jędrzejewski-Szmek 11a1589223 tree-wide: drop license boilerplate
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.

I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
2018-04-06 18:58:55 +02:00

189 lines
6.2 KiB
C

/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
Copyright 2010 Lennart Poettering
***/
#include <errno.h>
#include <string.h>
#include "libudev.h"
#include "alloc-util.h"
#include "locale-util.h"
#include "path-util.h"
#include "string-util.h"
#include "sysfs-show.h"
#include "terminal-util.h"
#include "udev-util.h"
#include "util.h"
static int show_sysfs_one(
struct udev *udev,
const char *seat,
struct udev_list_entry **item,
const char *sub,
const char *prefix,
unsigned n_columns,
OutputFlags flags) {
size_t max_width;
assert(udev);
assert(seat);
assert(item);
assert(prefix);
if (flags & OUTPUT_FULL_WIDTH)
max_width = (size_t) -1;
else if (n_columns < 10)
max_width = 10;
else
max_width = n_columns;
while (*item) {
_cleanup_udev_device_unref_ struct udev_device *d = NULL;
struct udev_list_entry *next, *lookahead;
const char *sn, *name, *sysfs, *subsystem, *sysname;
_cleanup_free_ char *k = NULL, *l = NULL;
bool is_master;
sysfs = udev_list_entry_get_name(*item);
if (!path_startswith(sysfs, sub))
return 0;
d = udev_device_new_from_syspath(udev, sysfs);
if (!d) {
*item = udev_list_entry_get_next(*item);
continue;
}
sn = udev_device_get_property_value(d, "ID_SEAT");
if (isempty(sn))
sn = "seat0";
/* Explicitly also check for tag 'seat' here */
if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
*item = udev_list_entry_get_next(*item);
continue;
}
is_master = udev_device_has_tag(d, "master-of-seat");
name = udev_device_get_sysattr_value(d, "name");
if (!name)
name = udev_device_get_sysattr_value(d, "id");
subsystem = udev_device_get_subsystem(d);
sysname = udev_device_get_sysname(d);
/* Look if there's more coming after this */
lookahead = next = udev_list_entry_get_next(*item);
while (lookahead) {
const char *lookahead_sysfs;
lookahead_sysfs = udev_list_entry_get_name(lookahead);
if (path_startswith(lookahead_sysfs, sub) &&
!path_startswith(lookahead_sysfs, sysfs)) {
_cleanup_udev_device_unref_ struct udev_device *lookahead_d = NULL;
lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
if (lookahead_d) {
const char *lookahead_sn;
lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
if (isempty(lookahead_sn))
lookahead_sn = "seat0";
if (streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat"))
break;
}
}
lookahead = udev_list_entry_get_next(lookahead);
}
k = ellipsize(sysfs, max_width, 20);
if (!k)
return -ENOMEM;
printf("%s%s%s\n", prefix, special_glyph(lookahead ? TREE_BRANCH : TREE_RIGHT), k);
if (asprintf(&l,
"%s%s:%s%s%s%s",
is_master ? "[MASTER] " : "",
subsystem, sysname,
name ? " \"" : "", strempty(name), name ? "\"" : "") < 0)
return -ENOMEM;
free(k);
k = ellipsize(l, max_width, 70);
if (!k)
return -ENOMEM;
printf("%s%s%s\n", prefix, lookahead ? special_glyph(TREE_VERTICAL) : " ", k);
*item = next;
if (*item) {
_cleanup_free_ char *p = NULL;
p = strappend(prefix, lookahead ? special_glyph(TREE_VERTICAL) : " ");
if (!p)
return -ENOMEM;
show_sysfs_one(udev, seat, item, sysfs, p,
n_columns == (unsigned) -1 || n_columns < 2 ? n_columns : n_columns - 2,
flags);
}
}
return 0;
}
int show_sysfs(const char *seat, const char *prefix, unsigned n_columns, OutputFlags flags) {
_cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
_cleanup_udev_unref_ struct udev *udev = NULL;
struct udev_list_entry *first = NULL;
int r;
if (n_columns <= 0)
n_columns = columns();
prefix = strempty(prefix);
if (isempty(seat))
seat = "seat0";
udev = udev_new();
if (!udev)
return -ENOMEM;
e = udev_enumerate_new(udev);
if (!e)
return -ENOMEM;
if (!streq(seat, "seat0"))
r = udev_enumerate_add_match_tag(e, seat);
else
r = udev_enumerate_add_match_tag(e, "seat");
if (r < 0)
return r;
r = udev_enumerate_add_match_is_initialized(e);
if (r < 0)
return r;
r = udev_enumerate_scan_devices(e);
if (r < 0)
return r;
first = udev_enumerate_get_list_entry(e);
if (first)
show_sysfs_one(udev, seat, &first, "/", prefix, n_columns, flags);
else
printf("%s%s%s\n", prefix, special_glyph(TREE_RIGHT), "(none)");
return r;
}