1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <unistd.h>
9
10 #include <Eeze.h>
11 #include "eeze_udev_private.h"
12
13 EAPI Eina_List *
eeze_udev_find_similar_from_syspath(const char * syspath)14 eeze_udev_find_similar_from_syspath(const char *syspath)
15 {
16 _udev_device *device;
17 _udev_list_entry *devs, *cur;
18 _udev_enumerate *en;
19 Eina_List *l, *ret = NULL;
20 const char *vendor, *model, *revision, *devname, *dev;
21
22 if (!syspath)
23 return NULL;
24
25 en = udev_enumerate_new(udev);
26
27 if (!en)
28 return NULL;
29
30 if (!(device = _new_device(syspath)))
31 {
32 udev_enumerate_unref(en);
33 return NULL;
34 }
35
36 vendor = udev_device_get_property_value(device, "ID_VENDOR_ID");
37
38 if (vendor)
39 udev_enumerate_add_match_property(en, "ID_VENDOR_ID", vendor);
40
41 model = udev_device_get_property_value(device, "ID_MODEL_ID");
42
43 if (model)
44 udev_enumerate_add_match_property(en, "ID_MODEL_ID", model);
45
46 revision = udev_device_get_property_value(device, "ID_REVISION");
47
48 if (revision)
49 udev_enumerate_add_match_property(en, "ID_REVISION", revision);
50
51 udev_enumerate_scan_devices(en);
52 udev_device_unref(device);
53 devs = udev_enumerate_get_list_entry(en);
54 udev_list_entry_foreach(cur, devs)
55 {
56 devname = udev_list_entry_get_name(cur);
57 /* verify unlisted device */
58
59 EINA_LIST_FOREACH(ret, l, dev)
60 if (!strcmp(dev, devname))
61 continue;
62
63 ret = eina_list_prepend(ret, eina_stringshare_add(devname));
64 device = udev_device_new_from_syspath(udev, devname);
65
66 /* only device roots have this sysattr,
67 * and we only need to check parents of the roots
68 */
69 if (udev_device_get_sysattr_value(device, "idVendor"))
70 ret = _get_unlisted_parents(ret, device);
71
72 udev_device_unref(device);
73 }
74 udev_enumerate_unref(en);
75 return ret;
76 }
77
78 EAPI Eina_List *
eeze_udev_find_unlisted_similar(Eina_List * list)79 eeze_udev_find_unlisted_similar(Eina_List *list)
80 {
81 _udev_device *device;
82 _udev_list_entry *devs, *cur;
83 _udev_enumerate *en;
84 Eina_List *l;
85 const char *vendor, *model, *revision, *devname, *dev;
86
87 if (!list)
88 return NULL;
89
90 EINA_LIST_FOREACH(list, l, dev)
91 {
92 en = udev_enumerate_new(udev);
93
94 if (!en)
95 return NULL;
96
97 device = _new_device(dev);
98 if (!device) continue;
99
100 if ((vendor = udev_device_get_property_value(device, "ID_VENDOR_ID")))
101 udev_enumerate_add_match_property(en, "ID_VENDOR_ID", vendor);
102 else if ((vendor = udev_device_get_property_value(device, "ID_VENDOR")))
103 udev_enumerate_add_match_property(en, "ID_VENDOR", vendor);
104 else if ((vendor = udev_device_get_sysattr_value(device, "vendor")))
105 udev_enumerate_add_match_sysattr(en, "vendor", vendor);
106 else if ((vendor = udev_device_get_sysattr_value(device, "manufacturer")))
107 udev_enumerate_add_match_sysattr(en, "manufacturer", vendor);
108
109 if ((model = udev_device_get_property_value(device, "ID_MODEL_ID")))
110 udev_enumerate_add_match_property(en, "ID_MODEL_ID", model);
111 else if ((model = udev_device_get_property_value(device, "ID_MODEL")))
112 udev_enumerate_add_match_property(en, "ID_MODEL", model);
113 else if ((model = udev_device_get_sysattr_value(device, "model")))
114 udev_enumerate_add_match_sysattr(en, "model", model);
115 else if ((model = udev_device_get_sysattr_value(device, "product")))
116 udev_enumerate_add_match_sysattr(en, "product", model);
117
118 if ((revision = udev_device_get_property_value(device, "ID_REVISION")))
119 udev_enumerate_add_match_property(en, "ID_REVISION", revision);
120 else if ((revision = udev_device_get_sysattr_value(device, "revision")))
121 udev_enumerate_add_match_sysattr(en, "revision", revision);
122
123 udev_enumerate_add_match_subsystem(en, udev_device_get_subsystem(device));
124
125 udev_enumerate_scan_devices(en);
126 udev_device_unref(device);
127 devs = udev_enumerate_get_list_entry(en);
128 udev_list_entry_foreach(cur, devs)
129 {
130 devname = udev_list_entry_get_name(cur);
131 device = udev_device_new_from_syspath(udev, devname);
132
133 /* only device roots have this sysattr,
134 * and we only need to check parents of the roots
135 */
136 if (udev_device_get_sysattr_value(device, "idVendor"))
137 list = _get_unlisted_parents(list, device);
138
139 udev_device_unref(device);
140 }
141 udev_enumerate_unref(en);
142 }
143 return list;
144 }
145
146 EAPI Eina_List *
eeze_udev_find_by_type(Eeze_Udev_Type etype,const char * name)147 eeze_udev_find_by_type(Eeze_Udev_Type etype,
148 const char *name)
149 {
150 _udev_enumerate *en;
151 _udev_list_entry *devs, *cur;
152 _udev_device *device, *parent;
153 const char *devname;
154 Eina_List *ret = NULL;
155
156 en = udev_enumerate_new(udev);
157
158 if (!en)
159 return NULL;
160
161 switch (etype)
162 {
163 case EEZE_UDEV_TYPE_NONE:
164 break;
165
166 case EEZE_UDEV_TYPE_KEYBOARD:
167 udev_enumerate_add_match_subsystem(en, "input");
168 udev_enumerate_add_match_property(en, "ID_INPUT_KEYBOARD", "1");
169 break;
170
171 case EEZE_UDEV_TYPE_MOUSE:
172 udev_enumerate_add_match_subsystem(en, "input");
173 udev_enumerate_add_match_property(en, "ID_INPUT_MOUSE", "1");
174 break;
175
176 case EEZE_UDEV_TYPE_TOUCHPAD:
177 udev_enumerate_add_match_subsystem(en, "input");
178 udev_enumerate_add_match_property(en, "ID_INPUT_TOUCHPAD", "1");
179 break;
180
181 case EEZE_UDEV_TYPE_JOYSTICK:
182 udev_enumerate_add_match_subsystem(en, "input");
183 udev_enumerate_add_match_property(en, "ID_INPUT_JOYSTICK", "1");
184 break;
185
186 case EEZE_UDEV_TYPE_DRIVE_MOUNTABLE:
187 udev_enumerate_add_match_subsystem(en, "block");
188 udev_enumerate_add_match_property(en, "ID_FS_USAGE", "filesystem");
189 break;
190
191 case EEZE_UDEV_TYPE_DRIVE_INTERNAL:
192 udev_enumerate_add_match_subsystem(en, "block");
193 udev_enumerate_add_match_property(en, "ID_TYPE", "disk");
194 udev_enumerate_add_match_property(en, "ID_BUS", "ata");
195 udev_enumerate_add_match_sysattr(en, "removable", "0");
196 break;
197
198 case EEZE_UDEV_TYPE_DRIVE_REMOVABLE:
199 udev_enumerate_add_match_sysattr(en, "removable", "1");
200 udev_enumerate_add_match_property(en, "ID_TYPE", "disk");
201 break;
202
203 case EEZE_UDEV_TYPE_DRIVE_CDROM:
204 udev_enumerate_add_match_property(en, "ID_CDROM", "1");
205 break;
206
207 case EEZE_UDEV_TYPE_POWER_AC:
208 udev_enumerate_add_match_subsystem(en, "power_supply");
209 udev_enumerate_add_match_sysattr(en, "type", "Mains");
210 break;
211
212 case EEZE_UDEV_TYPE_POWER_BAT:
213 udev_enumerate_add_match_subsystem(en, "power_supply");
214 udev_enumerate_add_match_sysattr(en, "type", "Battery");
215 udev_enumerate_add_match_sysattr(en, "present", "1");
216 break;
217
218 case EEZE_UDEV_TYPE_NET:
219 udev_enumerate_add_match_subsystem(en, "net");
220 break;
221
222 case EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR:
223 udev_enumerate_add_match_subsystem(en, "hwmon");
224 break;
225
226 /*
227 case EEZE_UDEV_TYPE_ANDROID:
228 udev_enumerate_add_match_subsystem(en, "block");
229 udev_enumerate_add_match_property(en, "ID_MODEL", "Android_*");
230 break;
231 */
232 case EEZE_UDEV_TYPE_V4L:
233 udev_enumerate_add_match_subsystem(en, "video4linux");
234 break;
235
236 case EEZE_UDEV_TYPE_BLUETOOTH:
237 udev_enumerate_add_match_subsystem(en, "bluetooth");
238 break;
239
240 case EEZE_UDEV_TYPE_DRM:
241 udev_enumerate_add_match_subsystem(en, "drm");
242 udev_enumerate_add_match_subsystem(en, "card[0-9]*");
243 break;
244
245 case EEZE_UDEV_TYPE_BACKLIGHT:
246 udev_enumerate_add_match_subsystem(en, "backlight");
247 break;
248
249 case EEZE_UDEV_TYPE_LEDS:
250 udev_enumerate_add_match_subsystem(en, "leds");
251 break;
252
253 case EEZE_UDEV_TYPE_GRAPHICS:
254 udev_enumerate_add_match_subsystem(en, "graphics");
255 break;
256
257 case EEZE_UDEV_TYPE_GPIO:
258 udev_enumerate_add_match_subsystem(en, "gpio");
259 break;
260
261 default:
262 break;
263 }
264
265 udev_enumerate_scan_devices(en);
266 devs = udev_enumerate_get_list_entry(en);
267 udev_list_entry_foreach(cur, devs)
268 {
269 devname = udev_list_entry_get_name(cur);
270 device = udev_device_new_from_syspath(udev, devname);
271
272
273 if (etype == EEZE_UDEV_TYPE_IS_IT_HOT_OR_IS_IT_COLD_SENSOR) /* ensure that temp input exists somewhere in this device chain */
274 {
275 Eina_Bool one, two;
276 const char *t;
277
278 one = _walk_parents_test_attr(device, "temp1_input", NULL);
279 two = _walk_parents_test_attr(device, "temp2_input", NULL);
280 if ((!one) && (!two)) goto out;
281
282 t = one ? "temp1_input" : "temp2_input";
283 /* if device is not the one which has the temp input, we must go up the chain */
284 if (!udev_device_get_sysattr_value(device, t))
285 {
286 devname = NULL;
287
288 for (parent = udev_device_get_parent(device); parent; parent = udev_device_get_parent(parent)) /*check for parent */
289 if ((udev_device_get_sysattr_value(parent, t)))
290 {
291 devname = udev_device_get_syspath(parent);
292 break;
293 }
294
295 if (!devname)
296 goto out;
297 }
298 }
299 else if (etype == EEZE_UDEV_TYPE_DRIVE_REMOVABLE)
300 {
301 /* this yields the actual hw device, not to be confused with the filesystem */
302 devname = udev_device_get_syspath(udev_device_get_parent(device));
303 }
304 else if (etype == EEZE_UDEV_TYPE_DRIVE_MOUNTABLE)
305 {
306 int devcheck;
307
308 devcheck = open(udev_device_get_devnode(device), O_RDONLY);
309 if (devcheck < 0) goto out;
310 close(devcheck);
311 }
312
313 if (name && (!strstr(devname, name)))
314 goto out;
315
316 ret = eina_list_append(ret, eina_stringshare_add(devname));
317 out:
318 udev_device_unref(device);
319 }
320 udev_enumerate_unref(en);
321 return ret;
322 }
323
324 EAPI Eina_List *
eeze_udev_find_by_filter(const char * subsystem,const char * type,const char * name)325 eeze_udev_find_by_filter(const char *subsystem,
326 const char *type,
327 const char *name)
328 {
329 _udev_enumerate *en;
330 _udev_list_entry *devs, *cur;
331 const char *devname;
332 Eina_List *ret = NULL;
333
334 if ((!subsystem) && (!type) && (!name))
335 return NULL;
336
337 en = udev_enumerate_new(udev);
338
339 if (!en)
340 return NULL;
341
342 if (subsystem)
343 udev_enumerate_add_match_subsystem(en, subsystem);
344
345 if (type)
346 udev_enumerate_add_match_property(en, type, "1");
347 udev_enumerate_scan_devices(en);
348 devs = udev_enumerate_get_list_entry(en);
349 udev_list_entry_foreach(cur, devs)
350 {
351 devname = udev_list_entry_get_name(cur);
352
353 if (name && (!strstr(devname, name)))
354 continue;
355
356 ret = eina_list_append(ret, eina_stringshare_add(devname));
357 }
358 udev_enumerate_unref(en);
359 return ret;
360 }
361
362 EAPI Eina_List *
eeze_udev_find_by_sysattr(const char * sysattr,const char * value)363 eeze_udev_find_by_sysattr(const char *sysattr,
364 const char *value)
365 {
366 _udev_enumerate *en;
367 _udev_list_entry *devs, *cur;
368 const char *devname;
369 Eina_List *ret = NULL;
370
371 if (!sysattr)
372 return NULL;
373
374 en = udev_enumerate_new(udev);
375
376 if (!en)
377 return NULL;
378
379 udev_enumerate_add_match_sysattr(en, sysattr, value);
380 udev_enumerate_scan_devices(en);
381 devs = udev_enumerate_get_list_entry(en);
382 udev_list_entry_foreach(cur, devs)
383 {
384 devname = udev_list_entry_get_name(cur);
385 ret = eina_list_append(ret, eina_stringshare_add(devname));
386 }
387 udev_enumerate_unref(en);
388 return ret;
389 }
390
391 EAPI Eina_List *
eeze_udev_find_by_subsystem_sysname(const char * subsystem,const char * sysname)392 eeze_udev_find_by_subsystem_sysname(const char *subsystem, const char *sysname)
393 {
394 _udev_enumerate *en;
395 _udev_list_entry *devs, *cur;
396 const char *devname;
397 Eina_List *ret = NULL;
398
399 en = udev_enumerate_new(udev);
400 if (!en) return NULL;
401
402 if (subsystem) udev_enumerate_add_match_subsystem(en, subsystem);
403 if (sysname) udev_enumerate_add_match_sysname(en, sysname);
404
405 udev_enumerate_scan_devices(en);
406 devs = udev_enumerate_get_list_entry(en);
407 udev_list_entry_foreach(cur, devs)
408 {
409 devname = udev_list_entry_get_name(cur);
410 ret = eina_list_append(ret, eina_stringshare_add(devname));
411 }
412 udev_enumerate_unref(en);
413 return ret;
414 }
415