chiark / gitweb /
seat: udev - use ID_PATH_TAG instead of 'sed' hack
[elogind.git] / src / sysfs-show.c
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
9   under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
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
16   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
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"
28
29 static bool device_has_tag(struct udev_device *d, const char *tag) {
30         struct udev_list_entry *first, *item;
31
32         assert(d);
33         assert(tag);
34
35         /* FIXME */
36         udev_device_get_is_initialized(d);
37
38         first = udev_device_get_tags_list_entry(d);
39         udev_list_entry_foreach(item, first)
40                 if (streq(udev_list_entry_get_name(item), tag))
41                         return true;
42
43         return false;
44 }
45
46 static int show_sysfs_one(
47                 struct udev *udev,
48                 const char *seat,
49                 struct udev_list_entry **item,
50                 const char *sub,
51                 const char *prefix,
52                 unsigned n_columns) {
53
54         assert(udev);
55         assert(seat);
56         assert(item);
57         assert(prefix);
58
59         while (*item) {
60                 struct udev_list_entry *next, *lookahead;
61                 struct udev_device *d;
62                 const char *sn, *id, *name, *sysfs, *subsystem, *sysname;
63
64                 sysfs = udev_list_entry_get_name(*item);
65                 if (!path_startswith(sysfs, sub))
66                         return 0;
67
68                 d = udev_device_new_from_syspath(udev, sysfs);
69                 if (!d) {
70                         *item = udev_list_entry_get_next(*item);
71                         continue;
72                 }
73
74                 sn = udev_device_get_property_value(d, "ID_SEAT");
75                 if (isempty(sn))
76                         sn = "seat0";
77
78                 /* fixme, also check for tag 'seat' here */
79                 if (!streq(seat, sn) || !device_has_tag(d, "seat")) {
80                         udev_device_unref(d);
81                         *item = udev_list_entry_get_next(*item);
82                         continue;
83                 }
84
85                 id = udev_device_get_property_value(d, "ID_FOR_SEAT");
86                 name = udev_device_get_sysattr_value(d, "name");
87                 if (!name)
88                         name = udev_device_get_sysattr_value(d, "id");
89                 subsystem = udev_device_get_subsystem(d);
90                 sysname = udev_device_get_sysname(d);
91
92                 /* Look if there's more coming after this */
93                 lookahead = next = udev_list_entry_get_next(*item);
94                 while (lookahead) {
95                         const char *lookahead_sysfs;
96
97                         lookahead_sysfs = udev_list_entry_get_name(lookahead);
98
99                         if (path_startswith(lookahead_sysfs, sub) &&
100                             !path_startswith(lookahead_sysfs, sysfs)) {
101                                 struct udev_device *lookahead_d;
102
103                                 lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
104                                 if (lookahead_d) {
105                                         const char *lookahead_sn;
106                                         bool found;
107
108                                         lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
109                                         if (isempty(lookahead_sn))
110                                                 lookahead_sn = "seat0";
111
112                                         found = streq(seat, lookahead_sn) && device_has_tag(d, "seat");
113                                         udev_device_unref(lookahead_d);
114
115                                         if (found)
116                                                 break;
117                                 }
118                         }
119
120                         lookahead = udev_list_entry_get_next(lookahead);
121                 }
122
123                 printf("%s%s %s (%s:%s)", prefix, lookahead ? "\342\224\234" : "\342\224\224", id ? id : sysfs, subsystem, sysname);
124
125                 if (name)
126                         printf(" \"%s\"\n", name);
127                 else
128                         printf("\n");
129
130                 *item = next;
131                 if (*item) {
132                         char *p;
133
134                         p = strappend(prefix, lookahead ? "\342\224\202 " : "  ");
135                         show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
136                         free(p);
137                 }
138
139                 udev_device_unref(d);
140         }
141
142         return 0;
143 }
144
145 int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
146         struct udev *udev;
147         struct udev_list_entry *first = NULL;
148         struct udev_enumerate *e;
149         int r;
150
151         if (n_columns <= 0)
152                 n_columns = columns();
153
154         if (!prefix)
155                 prefix = "";
156
157         if (isempty(seat))
158                 seat = "seat0";
159
160         udev = udev_new();
161         if (!udev)
162                 return -ENOMEM;
163
164         e = udev_enumerate_new(udev);
165         if (!e) {
166                 r = -ENOMEM;
167                 goto finish;
168         }
169
170         if (!streq(seat, "seat0"))
171                 r = udev_enumerate_add_match_tag(e, seat);
172         else
173                 r = udev_enumerate_add_match_tag(e, "seat");
174
175         r = udev_enumerate_scan_devices(e);
176         if (r < 0)
177                 goto finish;
178
179         first = udev_enumerate_get_list_entry(e);
180         if (first)
181                 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
182
183 finish:
184         if (e)
185                 udev_enumerate_unref(e);
186
187         if (udev)
188                 udev_unref(udev);
189
190         return r;
191 }