1 /*
2  * Copyright (c) 2015, 2021 Vladimir Kondratyev <vladimir@kondratyev.su>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 #include "config.h"
27 
28 #include <sys/param.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #ifdef HAVE_SYSCTLBYNAME
32 #include <sys/sysctl.h>
33 #endif
34 
35 #include <assert.h>
36 #include <fcntl.h>
37 #include <fnmatch.h>
38 #include <stdbool.h>
39 #include <stdint.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 
45 #ifdef HAVE_DEV_HID_HIDRAW_H
46 #include <dev/hid/hidraw.h>
47 #endif
48 #ifdef HAVE_LINUX_INPUT_H
49 #include <linux/input.h>
50 #endif
51 
52 #include "libudev.h"
53 #include "udev-device.h"
54 #include "udev-list.h"
55 #include "udev-utils.h"
56 #include "utils.h"
57 #ifdef ENABLE_GPL
58 #include "utils-gpl.h"
59 #endif
60 
61 #ifdef HAVE_LINUX_INPUT_H
62 #ifndef	BTN_DPAD_UP
63 #define	BTN_DPAD_UP	0x220
64 #endif
65 #ifndef	BTN_DPAD_RIGHT
66 #define	BTN_DPAD_RIGHT	0x223
67 #endif
68 #ifndef	BTN_SOUTH
69 #define	BTN_SOUTH	0x130
70 #endif
71 #else	/* !HAVE_LINUX_INPUT_H */
72 #define	BUS_PCI		0x01
73 #define	BUS_USB		0x03
74 #define	BUS_VIRTUAL	0x06
75 #define	BUS_ISA		0x10
76 #define	BUS_I8042	0x11
77 #endif	/* !HAVE_LINUX_INPUT_H */
78 
79 #define	PS2_KEYBOARD_VENDOR		0x001
80 #define	PS2_KEYBOARD_PRODUCT		0x001
81 #define	PS2_MOUSE_VENDOR		0x002
82 #define	PS2_MOUSE_GENERIC_PRODUCT	0x001
83 
84 typedef void (create_node_handler_t)(struct udev_device *udev_device);
85 
86 #if defined(HAVE_LINUX_INPUT_H) || defined(HAVE_DEV_HID_HIDRAW_H)
87 static const char *virtual_sysname = "uinput";
88 #endif
89 
90 #ifdef HAVE_LINUX_INPUT_H
91 static create_node_handler_t	create_evdev_handler;
92 #endif
93 static create_node_handler_t	create_keyboard_handler;
94 static create_node_handler_t	create_mouse_handler;
95 static create_node_handler_t	create_joystick_handler;
96 static create_node_handler_t	create_touchpad_handler;
97 static create_node_handler_t	create_touchscreen_handler;
98 static create_node_handler_t	create_sysmouse_handler;
99 static create_node_handler_t	create_kbdmux_handler;
100 static create_node_handler_t	create_drm_handler;
101 #ifdef HAVE_DEV_HID_HIDRAW_H
102 static create_node_handler_t	create_hidraw_handler;
103 #endif
104 
105 struct devnum_scan_args {
106 	dev_t	devnum;
107 	char *	pattern;
108 	char *	path;
109 	size_t	len;
110 };
111 
112 struct subsystem_config {
113 	char *subsystem;
114 	char *syspath;
115 	char *symlink; /* If syspath is symlink, path it refers to */
116 	int flags; /* See SCFLAG_* below. */
117 	create_node_handler_t *create_handler;
118 };
119 
120 enum {
121 	IT_NONE,
122 	IT_KEYBOARD,
123 	IT_MOUSE,
124 	IT_TOUCHPAD,
125 	IT_TOUCHSCREEN,
126 	IT_JOYSTICK,
127 	IT_TABLET,
128 	IT_ACCELEROMETER,
129 	IT_SWITCH,
130 };
131 
132 /* Flag which in indicates a device should be skipped because it's
133  * already exposed through EVDEV when it's enabled. */
134 #define	SCFLAG_SKIP_IF_EVDEV	0x01
135 
136 static const struct subsystem_config subsystems[] = {
137 	{
138 #ifdef HAVE_LINUX_INPUT_H
139 		.subsystem = "input",
140 		.syspath = DEV_PATH_ROOT "/input/event[0-9]*",
141 		.create_handler = create_evdev_handler
142 	}, {
143 #endif
144 		.subsystem = "input",
145 		.syspath = DEV_PATH_ROOT "/ukbd[0-9]*",
146 		.flags = SCFLAG_SKIP_IF_EVDEV,
147 		.create_handler = create_keyboard_handler,
148 	}, {
149 		.subsystem = "input",
150 		.syspath = DEV_PATH_ROOT "/atkbd[0-9]*",
151 		.flags = SCFLAG_SKIP_IF_EVDEV,
152 		.create_handler = create_keyboard_handler,
153 	}, {
154 		.subsystem = "input",
155 		.syspath = DEV_PATH_ROOT "/kbdmux[0-9]*",
156 		.flags = SCFLAG_SKIP_IF_EVDEV,
157 		.create_handler = create_kbdmux_handler,
158 	}, {
159 		.subsystem = "input",
160 		.syspath = DEV_PATH_ROOT "/ums[0-9]*",
161 		.flags = SCFLAG_SKIP_IF_EVDEV,
162 		.create_handler = create_mouse_handler,
163 	}, {
164 		.subsystem = "input",
165 		.syspath = DEV_PATH_ROOT "/psm[0-9]*",
166 		.flags = SCFLAG_SKIP_IF_EVDEV,
167 		.create_handler = create_mouse_handler,
168 	}, {
169 		.subsystem = "input",
170 		.syspath = DEV_PATH_ROOT "/joy[0-9]*",
171 		.create_handler = create_joystick_handler,
172 	}, {
173 		.subsystem = "input",
174 		.syspath = DEV_PATH_ROOT "/atp[0-9]*",
175 		.create_handler = create_touchpad_handler,
176 	}, {
177 		.subsystem = "input",
178 		.syspath = DEV_PATH_ROOT "/wsp[0-9]*",
179 		.create_handler = create_touchpad_handler,
180 	}, {
181 		.subsystem = "input",
182 		.syspath = DEV_PATH_ROOT "/uep[0-9]*",
183 		.create_handler = create_touchscreen_handler,
184 	}, {
185 		.subsystem = "input",
186 		.syspath = DEV_PATH_ROOT "/sysmouse",
187 		.flags = SCFLAG_SKIP_IF_EVDEV,
188 		.create_handler = create_sysmouse_handler,
189 	}, {
190 		.subsystem = "input",
191 		.syspath = DEV_PATH_ROOT "/vboxguest",
192 		.create_handler = create_mouse_handler,
193 	}, {
194 		.subsystem = "drm",
195 		.syspath = DEV_PATH_ROOT "/dri/card[0-9]*",
196 		.symlink = DEV_PATH_ROOT "/drm/[0-9]*",
197 		.create_handler = create_drm_handler,
198 	},
199 #ifdef HAVE_DEV_HID_HIDRAW_H
200 	{
201 		.subsystem = "hidraw",
202 		.syspath = DEV_PATH_ROOT "/hidraw[0-9]*",
203 		.create_handler = create_hidraw_handler,
204 	},
205 #endif
206 };
207 
208 static const struct subsystem_config *
get_subsystem_config_by_syspath(const char * path)209 get_subsystem_config_by_syspath(const char *path)
210 {
211 	size_t i;
212 
213 	for (i = 0; i < nitems(subsystems); i++)
214 		if (fnmatch(subsystems[i].syspath, path, 0) == 0)
215 			return (&subsystems[i]);
216 
217 	return (NULL);
218 }
219 
220 static bool
kernel_has_evdev_enabled()221 kernel_has_evdev_enabled()
222 {
223 	static int enabled = -1;
224 #ifdef HAVE_SYSCTLBYNAME
225 	size_t len;
226 #endif
227 
228 	if (enabled != -1)
229 		return (enabled);
230 
231 #ifdef HAVE_SYSCTLBYNAME
232 	if (sysctlbyname("kern.features.evdev_support", &enabled, &len, NULL, 0) < 0)
233 		return (0);
234 #else
235 	enabled = 1;
236 #endif
237 
238 	TRC("() EVDEV enabled: %s", enabled ? "true" : "false");
239 	return (enabled);
240 }
241 
242 const char *
get_subsystem_by_syspath(const char * syspath)243 get_subsystem_by_syspath(const char *syspath)
244 {
245 	const struct subsystem_config *sc;
246 
247 	sc = get_subsystem_config_by_syspath(syspath);
248 	if (sc == NULL)
249 		return (UNKNOWN_SUBSYSTEM);
250 	if (sc->flags & SCFLAG_SKIP_IF_EVDEV && kernel_has_evdev_enabled()) {
251 		TRC("(%s) EVDEV enabled -> skipping device", syspath);
252 		return (UNKNOWN_SUBSYSTEM);
253 	}
254 
255 	return (sc->subsystem);
256 }
257 
258 const char *
get_sysname_by_syspath(const char * syspath)259 get_sysname_by_syspath(const char *syspath)
260 {
261 
262 	return (strbase(syspath));
263 }
264 
265 const char *
get_devpath_by_syspath(const char * syspath)266 get_devpath_by_syspath(const char *syspath)
267 {
268 
269 	return (syspath);
270 }
271 
272 const char *
get_syspath_by_devpath(const char * devpath)273 get_syspath_by_devpath(const char *devpath)
274 {
275 
276 	return (devpath);
277 }
278 
279 static int
get_syspath_by_devnum_cb(const char * path,mode_t type,void * args)280 get_syspath_by_devnum_cb(const char *path, mode_t type, void *args)
281 {
282 	struct devnum_scan_args *sa = args;
283 	struct stat st;
284 
285 	if (S_ISLNK(type) &&
286 	    fnmatch(sa->pattern, path, 0) == 0 &&
287 	    stat(path, &st) == 0 &&
288 	    st.ST_RDEV == sa->devnum) {
289 		strlcpy(sa->path, path, sa->len);
290 		return (-1);
291 	}
292 	return (0);
293 }
294 
295 const char *
get_syspath_by_devnum(dev_t devnum)296 get_syspath_by_devnum(dev_t devnum)
297 {
298 	char devpath[DEV_PATH_MAX] = DEV_PATH_ROOT "/";
299 	char linkdir[DEV_PATH_MAX];
300 	struct stat st;
301 	struct scan_ctx ctx;
302 	struct devnum_scan_args args;
303 	const char *linkbase;
304 	size_t dev_len, linkdir_len, i;
305 
306 	dev_len = strlen(devpath);
307 	devname_r(devnum, S_IFCHR, devpath + dev_len, sizeof(devpath) - dev_len);
308 	/* Recheck path as devname_r returns zero-terminated garbage on error */
309 	if (stat(devpath, &st) != 0 || st.ST_RDEV != devnum) {
310 		TRC("(%d) -> failed", (int)devnum);
311 		return NULL;
312 	}
313 	TRC("(%d) -> %s", (int)devnum, devpath);
314 
315 	/* Resolve symlink in reverse direction if necessary */
316 	for (i = 0; i < nitems(subsystems); i++) {
317 		if (subsystems[i].symlink != NULL &&
318 		    fnmatch(subsystems[i].symlink, devpath, 0) == 0) {
319 			linkbase = strbase(subsystems[i].syspath);
320 			assert(linkbase != NULL);
321 			linkdir_len = linkbase - subsystems[i].syspath;
322 			if (linkdir_len >= sizeof(linkdir))
323 				linkdir_len = sizeof(linkdir);
324 			strlcpy(linkdir, subsystems[i].syspath, linkdir_len + 1);
325 			args = (struct devnum_scan_args) {
326 				.devnum = devnum,
327 				.pattern = subsystems[i].syspath,
328 				.path = devpath,
329 				.len = sizeof(devpath),
330 			};
331 			ctx = (struct scan_ctx) {
332 				.recursive = false,
333 				.cb = get_syspath_by_devnum_cb,
334 				.args = &args,
335 			};
336 			if (scandir_recursive(linkdir, sizeof(linkdir), &ctx) == -1)
337 				break;
338 		}
339 	}
340 
341 	return (strdup(devpath));
342 }
343 
344 void
invoke_create_handler(struct udev_device * ud)345 invoke_create_handler(struct udev_device *ud)
346 {
347 	const char *path;
348 	const struct subsystem_config *sc;
349 
350 	path = udev_device_get_syspath(ud);
351 	sc = get_subsystem_config_by_syspath(path);
352 	if (sc == NULL || sc->create_handler == NULL)
353 		return;
354 	if (sc->flags & SCFLAG_SKIP_IF_EVDEV && kernel_has_evdev_enabled()) {
355 		TRC("(%p) EVDEV enabled -> skipping device", ud);
356 		return;
357 	}
358 
359 	sc->create_handler(ud);
360 }
361 
362 static int
set_input_device_type(struct udev_device * ud,int input_type)363 set_input_device_type(struct udev_device *ud, int input_type)
364 {
365 	struct udev_list *ul;
366 
367 	ul = udev_device_get_properties_list(ud);
368 	if (udev_list_insert(ul, "ID_INPUT", "1") < 0)
369 		return (-1);
370 	switch (input_type) {
371 	case IT_KEYBOARD:
372 		udev_list_insert(ul, "ID_INPUT_KEY", "1");
373 		udev_list_insert(ul, "ID_INPUT_KEYBOARD", "1");
374 		break;
375 	case IT_MOUSE:
376 		udev_list_insert(ul, "ID_INPUT_MOUSE", "1");
377 		break;
378 	case IT_TOUCHPAD:
379 		udev_list_insert(ul, "ID_INPUT_MOUSE", "1");
380 		udev_list_insert(ul, "ID_INPUT_TOUCHPAD", "1");
381 		break;
382 	case IT_TOUCHSCREEN:
383 		udev_list_insert(ul, "ID_INPUT_TOUCHSCREEN", "1");
384 		break;
385 	case IT_JOYSTICK:
386 		udev_list_insert(ul, "ID_INPUT_JOYSTICK", "1");
387 		break;
388 	case IT_TABLET:
389 		udev_list_insert(ul, "ID_INPUT_TABLET", "1");
390 		break;
391 	case IT_ACCELEROMETER:
392 		udev_list_insert(ul, "ID_INPUT_ACCELEROMETER", "1");
393 		break;
394 	case IT_SWITCH:
395 		udev_list_insert(ul, "ID_INPUT_SWITCH", "1");
396 		break;
397 	}
398 	return (0);
399 }
400 
401 static struct udev_device *
create_xorg_parent(struct udev_device * ud,const char * sysname,const char * name,const char * product,const char * pnp_id)402 create_xorg_parent(struct udev_device *ud, const char* sysname,
403     const char *name, const char *product, const char *pnp_id)
404 {
405 	struct udev_device *parent;
406 	struct udev *udev;
407 	struct udev_list *props, *sysattrs;
408 
409 	/* xorg-server gets device name and vendor string from parent device */
410 	udev = udev_device_get_udev(ud);
411 	parent = udev_device_new_common(udev, sysname, UD_ACTION_NONE);
412 	if (parent == NULL)
413 		return NULL;
414 
415 	props = udev_device_get_properties_list(parent);
416 	sysattrs = udev_device_get_sysattr_list(parent);
417 	udev_list_insert(props, "NAME", name);
418 	udev_list_insert(sysattrs, "name", name);
419 	if (product != NULL)
420 		udev_list_insert(props, "PRODUCT", product);
421 	if (pnp_id != NULL)
422 		udev_list_insert(sysattrs, "id", product);
423 
424 	return (parent);
425 }
426 
427 #ifdef HAVE_LINUX_INPUT_H
428 
429 #define	LONG_BITS	(sizeof(long) * 8)
430 #define	NLONGS(x)	(((x) + LONG_BITS - 1) / LONG_BITS)
431 
432 static inline bool
bit_is_set(const unsigned long * array,int bit)433 bit_is_set(const unsigned long *array, int bit)
434 {
435 	return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS)));
436 }
437 
438 static inline bool
bit_find(const unsigned long * array,int start,int stop)439 bit_find(const unsigned long *array, int start, int stop)
440 {
441 	int i;
442 
443 	for (i = start; i < stop; i++)
444 		if (bit_is_set(array, i))
445 			return true;
446 
447 	return false;
448 }
449 
450 static void
create_evdev_handler(struct udev_device * ud)451 create_evdev_handler(struct udev_device *ud)
452 {
453 	struct udev_device *parent;
454 	const char *sysname;
455 	char name[80], product[80], phys[80];
456 	int fd = -1, input_type = IT_NONE;
457 	bool opened = false;
458 	bool has_keys, has_buttons, has_lmr, has_dpad, has_joy_axes;
459 	bool has_rel_axes, has_abs_axes, has_mt, has_switches;
460 	unsigned long key_bits[NLONGS(KEY_CNT)];
461 	unsigned long rel_bits[NLONGS(REL_CNT)];
462 	unsigned long abs_bits[NLONGS(ABS_CNT)];
463 	unsigned long sw_bits[NLONGS(SW_CNT)];
464 	unsigned long prp_bits[NLONGS(INPUT_PROP_CNT)];
465 	struct input_id id;
466 #ifdef HAVE_SYSCTLBYNAME
467 	const char *unit;
468 	char mib[32];
469 	size_t len;
470 
471 	sysname = udev_device_get_sysname(ud);
472 	len = syspathlen_wo_units(sysname);
473 	unit = sysname + len;
474 
475 	snprintf(mib, sizeof(mib), "kern.evdev.input.%s.name", unit);
476 	len = sizeof(name);
477 	if (sysctlbyname(mib, name, &len, NULL, 0) < 0)
478 		goto use_ioctl;
479 
480 	snprintf(mib, sizeof(mib), "kern.evdev.input.%s.phys", unit);
481 	len = sizeof(phys);
482 	if (sysctlbyname(mib, phys, &len, NULL, 0) < 0)
483 		goto use_ioctl;
484 
485 	snprintf(mib, sizeof(mib), "kern.evdev.input.%s.id", unit);
486 	len = sizeof(id);
487 	if (sysctlbyname(mib, &id, &len, NULL, 0) < 0)
488 		goto use_ioctl;
489 
490 	snprintf(mib, sizeof(mib), "kern.evdev.input.%s.key_bits", unit);
491 	len = sizeof(key_bits);
492 	if (sysctlbyname(mib, key_bits, &len, NULL, 0) < 0)
493 		goto use_ioctl;
494 
495 	snprintf(mib, sizeof(mib), "kern.evdev.input.%s.rel_bits", unit);
496 	len = sizeof(rel_bits);
497 	if (sysctlbyname(mib, rel_bits, &len, NULL, 0) < 0)
498 		goto use_ioctl;
499 
500 	snprintf(mib, sizeof(mib), "kern.evdev.input.%s.abs_bits", unit);
501 	len = sizeof(abs_bits);
502 	if (sysctlbyname(mib, abs_bits, &len, NULL, 0) < 0)
503 		goto use_ioctl;
504 
505 	snprintf(mib, sizeof(mib), "kern.evdev.input.%s.sw_bits", unit);
506 	len = sizeof(sw_bits);
507 	if (sysctlbyname(mib, sw_bits, &len, NULL, 0) < 0)
508 		goto use_ioctl;
509 
510 	snprintf(mib, sizeof(mib), "kern.evdev.input.%s.props", unit);
511 	len = sizeof(prp_bits);
512 	if (sysctlbyname(mib, prp_bits, &len, NULL, 0) < 0)
513 		goto use_ioctl;
514 
515 	goto found_values;
516 
517 use_ioctl:
518 	ERR("sysctl not found, opening device and using ioctl");
519 #endif
520 
521 	fd = open(udev_device_get_devnode(ud), O_RDONLY | O_CLOEXEC);
522 	if (fd == -1) {
523 		fd = path_to_fd(udev_device_get_devnode(ud));
524 	} else {
525 		opened = true;
526 	}
527 	if (fd == -1)
528 		return;
529 
530 	if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) < 0 ||
531 	    (ioctl(fd, EVIOCGPHYS(sizeof(phys)), phys) < 0 && errno != ENOENT) ||
532 	    ioctl(fd, EVIOCGID, &id) < 0 ||
533 	    ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bits)), rel_bits) < 0 ||
534 	    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bits)), abs_bits) < 0 ||
535 	    ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bits)), key_bits) < 0 ||
536 	    ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bits)), sw_bits) < 0 ||
537 	    ioctl(fd, EVIOCGPROP(sizeof(prp_bits)), prp_bits) < 0) {
538 		ERR("could not query evdev");
539 		goto bail_out;
540 	}
541 
542 #ifdef HAVE_SYSCTLBYNAME
543 found_values:
544 #endif
545 	/* Derived from EvdevProbe() function of xf86-input-evdev driver */
546 	has_keys = bit_find(key_bits, 0, BTN_MISC);
547 	has_buttons = bit_find(key_bits, BTN_MISC, BTN_JOYSTICK);
548 	has_lmr = bit_find(key_bits, BTN_LEFT, BTN_MIDDLE + 1);
549 	has_dpad = bit_find(key_bits, BTN_DPAD_UP, BTN_DPAD_RIGHT + 1);
550 	has_joy_axes = bit_find(abs_bits, ABS_RX, ABS_HAT3Y + 1);
551 	has_rel_axes = bit_find(rel_bits, 0, REL_CNT);
552 	has_abs_axes = bit_find(abs_bits, 0, ABS_CNT);
553 	has_switches = bit_find(sw_bits, 0, SW_CNT);
554 	has_mt = bit_find(abs_bits, ABS_MT_SLOT, ABS_CNT);
555 
556 	if (has_abs_axes) {
557 		if (has_mt && !has_buttons) {
558 			if (bit_is_set(key_bits, BTN_JOYSTICK)) {
559 				input_type = IT_JOYSTICK;
560 				goto detected;
561 			} else {
562 				has_buttons = true;
563 			}
564 		}
565 
566 		if (bit_is_set(abs_bits, ABS_X) &&
567 		    bit_is_set(abs_bits, ABS_Y)) {
568 			if (bit_is_set(key_bits, BTN_TOOL_PEN) ||
569 			    bit_is_set(key_bits, BTN_STYLUS) ||
570 			    bit_is_set(key_bits, BTN_STYLUS2)) {
571 				input_type = IT_TABLET;
572 				goto detected;
573 			} else if (has_joy_axes ||
574 				   bit_is_set(key_bits, BTN_JOYSTICK)) {
575 			        /* Device is a joystick */
576 				input_type = IT_JOYSTICK;
577 				goto detected;
578 			} else if (bit_is_set(key_bits, BTN_SOUTH) ||
579 			           has_dpad ||
580 			           bit_is_set(abs_bits, ABS_HAT0X) ||
581 			           bit_is_set(abs_bits, ABS_HAT0Y) ||
582 			           bit_is_set(key_bits, BTN_THUMBL) ||
583 			           bit_is_set(key_bits, BTN_THUMBR)) {
584 			        /* Device is a gamepad */
585 				input_type = IT_JOYSTICK;
586 				goto detected;
587 			} else if (bit_is_set(abs_bits, ABS_PRESSURE) ||
588 			           bit_is_set(key_bits, BTN_TOUCH)) {
589 				if (has_lmr ||
590 				    bit_is_set(key_bits, BTN_TOOL_FINGER)) {
591 					input_type = IT_TOUCHPAD;
592 				} else {
593 					input_type = IT_TOUCHSCREEN;
594 				}
595 				goto detected;
596 			} else if (!(bit_is_set(rel_bits, REL_X) &&
597 			             bit_is_set(rel_bits, REL_Y)) &&
598 			             has_lmr) {
599 				input_type = IT_MOUSE;
600 				goto detected;
601 			}
602 		}
603 	}
604 
605 	if (bit_is_set(prp_bits, INPUT_PROP_ACCELEROMETER))
606 		input_type = IT_ACCELEROMETER;
607 	else if (has_keys)
608 		input_type = IT_KEYBOARD;
609 	else if (bit_is_set(prp_bits, INPUT_PROP_POINTER) || has_rel_axes || has_abs_axes || has_buttons)
610 		input_type = IT_MOUSE;
611 	else if (has_switches)
612 		input_type = IT_SWITCH;
613 
614 	if (input_type == IT_NONE)
615 		goto bail_out;
616 
617 detected:
618 	set_input_device_type(ud, input_type);
619 
620 	sysname = phys[0] == 0 ? virtual_sysname : phys;
621 
622 	*(strchrnul(name, ',')) = '\0';	/* strip name */
623 
624 	snprintf(product, sizeof(product), "%x/%x/%x/%x",
625 	    id.bustype, id.vendor, id.product, id.version);
626 
627 	parent = create_xorg_parent(ud, sysname, name, product, NULL);
628 	if (parent != NULL)
629 		udev_device_set_parent(ud, parent);
630 
631 bail_out:
632 	if (opened)
633 		close(fd);
634 }
635 #endif
636 
637 size_t
syspathlen_wo_units(const char * path)638 syspathlen_wo_units(const char *path) {
639 	size_t len;
640 
641 	len = strlen(path);
642 	while (len > 0) {
643 		if (path[len-1] < '0' || path[len-1] > '9')
644 			break;
645 		--len;
646 	}
647 	return len;
648 }
649 
650 static void
set_parent(struct udev_device * ud)651 set_parent(struct udev_device *ud)
652 {
653 	struct udev_device *parent;
654 	const char *sysname;
655 	char product[80], name[80];
656 	char *pnp_id = NULL;
657 	size_t len;
658 	uint32_t bus = BUS_VIRTUAL, prod = 0, vendor = 0;
659 #ifdef HAVE_SYSCTLBYNAME
660 	char devname[DEV_PATH_MAX], mib[32], pnpinfo[1024], parentname[80];
661 	const char *unit, *vendorstr, *prodstr, *devicestr;
662 	size_t vendorlen, prodlen, devicelen, pnplen;
663 #endif
664 
665 	sysname = udev_device_get_sysname(ud);
666 	len = syspathlen_wo_units(sysname);
667 	/* Check if device unit number found */
668 	if (strlen(sysname) == len)
669 		return;
670 
671 #ifdef HAVE_SYSCTLBYNAME
672 	snprintf(devname, len + 1, "%s", sysname);
673 	unit = sysname + len;
674 
675 	snprintf(mib, sizeof(mib), "dev.%.17s.%.3s.%%desc", devname, unit);
676 	len = sizeof(name);
677 	if (sysctlbyname(mib, name, &len, NULL, 0) < 0)
678 		return;
679 	*(strchrnul(name, ',')) = '\0';	/* strip name */
680 
681 	snprintf(mib, sizeof(mib), "dev.%.14s.%.3s.%%pnpinfo", devname, unit);
682 	len = sizeof(pnpinfo);
683 	if (sysctlbyname(mib, pnpinfo, &len, NULL, 0) < 0)
684 		return;
685 
686 	snprintf(mib, sizeof(mib), "dev.%.15s.%.3s.%%parent", devname, unit);
687 	len = sizeof(parentname);
688 	if (sysctlbyname(mib, parentname, &len, NULL, 0) < 0)
689 		return;
690 
691 	vendorstr = get_kern_prop_value(pnpinfo, "vendor", &vendorlen);
692 	prodstr = get_kern_prop_value(pnpinfo, "product", &prodlen);
693 	devicestr = get_kern_prop_value(pnpinfo, "device", &devicelen);
694 	pnp_id = get_kern_prop_value(pnpinfo, "_HID", &pnplen);
695 	if (pnp_id != NULL && pnplen == 4 && strncmp(pnp_id, "none", 4) == 0)
696 		pnp_id = NULL;
697 	if (pnp_id != NULL)
698 		pnp_id[pnplen] = '\0';
699 	if (prodstr != NULL && vendorstr != NULL) {
700 		/* XXX: should parent be compared to uhub* to detect usb? */
701 		vendor = strtol(vendorstr, NULL, 0);
702 		prod = strtol(prodstr, NULL, 0);
703 		bus = BUS_USB;
704 	} else if (devicestr != NULL && vendorstr != NULL) {
705 		vendor = strtol(vendorstr, NULL, 0);
706 		prod = strtol(devicestr, NULL, 0);
707 		bus = BUS_PCI;
708 	} else if (strcmp(parentname, "atkbdc0") == 0) {
709 		if (strcmp(devname, "atkbd") == 0) {
710 			vendor = PS2_KEYBOARD_VENDOR;
711 			prod = PS2_KEYBOARD_PRODUCT;
712 		} else if (strcmp(devname, "psm") == 0) {
713 			vendor = PS2_MOUSE_VENDOR;
714 			prod = PS2_MOUSE_GENERIC_PRODUCT;
715 		} else {
716 			vendor = 0;
717 			prod = 0;
718 		}
719 		bus = BUS_I8042;
720 	}
721 #else
722 	strlcpy(name, sysname, sizeof(name));
723 #endif
724 	snprintf(product, sizeof(product), "%x/%x/%x/0", bus, vendor, prod);
725 	parent = create_xorg_parent(ud, sysname, name, product, pnp_id);
726 	if (parent != NULL)
727 		udev_device_set_parent(ud, parent);
728 
729 	return;
730 }
731 
732 static void
create_keyboard_handler(struct udev_device * ud)733 create_keyboard_handler(struct udev_device *ud)
734 {
735 
736 	set_input_device_type(ud, IT_KEYBOARD);
737 	set_parent(ud);
738 }
739 
740 static void
create_mouse_handler(struct udev_device * ud)741 create_mouse_handler(struct udev_device *ud)
742 {
743 
744 	set_input_device_type(ud, IT_MOUSE);
745 	set_parent(ud);
746 }
747 
748 static void
create_kbdmux_handler(struct udev_device * ud)749 create_kbdmux_handler(struct udev_device *ud)
750 {
751 	struct udev_device *parent;
752 	const char* sysname;
753 
754 	set_input_device_type(ud, IT_KEYBOARD);
755 	sysname = udev_device_get_sysname(ud);
756 	parent = create_xorg_parent(ud, sysname,
757 	    "System keyboard multiplexor", "6/1/1/0", NULL);
758 	if (parent != NULL)
759 		udev_device_set_parent(ud, parent);
760 }
761 
762 static void
create_sysmouse_handler(struct udev_device * ud)763 create_sysmouse_handler(struct udev_device *ud)
764 {
765 	struct udev_device *parent;
766 	const char* sysname;
767 
768 	set_input_device_type(ud, IT_MOUSE);
769 	sysname = udev_device_get_sysname(ud);
770 	parent = create_xorg_parent(ud, sysname,
771 	    "System mouse", "6/2/1/0", NULL);
772 	if (parent != NULL)
773 		udev_device_set_parent(ud, parent);
774 }
775 
776 static void
create_joystick_handler(struct udev_device * ud)777 create_joystick_handler(struct udev_device *ud)
778 {
779 
780 	set_input_device_type(ud, IT_JOYSTICK);
781 	set_parent(ud);
782 }
783 
784 static void
create_touchpad_handler(struct udev_device * ud)785 create_touchpad_handler(struct udev_device *ud)
786 {
787 
788 	set_input_device_type(ud, IT_TOUCHPAD);
789 	set_parent(ud);
790 }
791 
792 static void
create_touchscreen_handler(struct udev_device * ud)793 create_touchscreen_handler(struct udev_device *ud)
794 {
795 
796 	set_input_device_type(ud, IT_TOUCHSCREEN);
797 	set_parent(ud);
798 }
799 
800 static void
create_drm_handler(struct udev_device * ud)801 create_drm_handler(struct udev_device *ud)
802 {
803 	const char *sysname, *devpath;
804 	struct udev_device *parent;
805 #ifdef HAVE_SYSCTLBYNAME
806 	char devbuf[PATH_MAX], buf[32], *devbufptr;
807 	size_t buflen = sizeof(devbuf);
808 #endif
809 
810 	udev_list_insert(udev_device_get_properties_list(ud), "HOTPLUG", "1");
811 	devpath = udev_device_get_devnode(ud);
812 	if (devpath == NULL)
813 		return;
814 
815 	sysname = udev_device_get_sysname(ud);
816 	parent = create_xorg_parent(ud, sysname, "drm parent", NULL, NULL);
817 	if (parent == NULL)
818 		return;
819 
820 	udev_device_set_parent(ud, parent);
821 
822 #ifdef HAVE_SYSCTLBYNAME
823 	realpath(devpath, devbuf);
824 	devbufptr = devbuf + 1;
825 	devbufptr = strchrnul(devbufptr, '/');
826 	while (*devbufptr != '\0') {
827 		*devbufptr = '.';
828 		devbufptr = strchrnul(devbufptr, '/');
829 	}
830 	snprintf(buf, sizeof(buf), "%.24s.PCI_ID", devbuf + 1);
831 	if (sysctlbyname(buf, devbuf, &buflen, NULL, 0) == 0){
832 		udev_list_insert(
833 		    udev_device_get_properties_list(parent), "PCI_ID", devbuf);}
834 #endif
835 }
836 
837 #ifdef HAVE_DEV_HID_HIDRAW_H
838 static void
create_hidraw_handler(struct udev_device * ud)839 create_hidraw_handler(struct udev_device *ud)
840 {
841 	char name[80], phys[80], uniq[32];
842 	const char *sysname;
843 	char *uevent;
844 	struct hidraw_devinfo info;
845 	struct udev_device *parent;
846 	struct udev *udev;
847 	struct udev_list *sysattrs;
848 	int fd = -1;
849 	bool opened = false;
850 
851 	fd = path_to_fd(udev_device_get_devnode(ud));
852 	if (fd == -1) {
853 		fd = open(udev_device_get_devnode(ud), O_RDONLY | O_CLOEXEC);
854 		opened = true;
855 	}
856 	if (fd == -1)
857 		return;
858 
859 	if (ioctl(fd, HIDIOCGRAWNAME(sizeof(name)), name) < 0 ||
860 	    ioctl(fd, HIDIOCGRAWPHYS(sizeof(phys)), phys) < 0 ||
861 	    ioctl(fd, HIDIOCGRAWUNIQ(sizeof(uniq)), uniq) < 0 ||
862 	    ioctl(fd, HIDIOCGRAWINFO, &info) < 0) {
863 		ERR("could not query hidraw");
864 		goto bail_out;
865 	}
866 
867 	sysname = phys[0] == 0 ? virtual_sysname : phys;
868 	udev = udev_device_get_udev(ud);
869 	parent = udev_device_new_common(udev, sysname, UD_ACTION_NONE);
870 	if (parent == NULL)
871 		goto bail_out;
872 
873 	sysattrs = udev_device_get_sysattr_list(parent);
874 	asprintf(&uevent,
875 	    "HID_ID=%04X:%08X:%08X\nHID_NAME=%s\nHID_PHYS=%s\nHID_UNIQ=%s",
876 	    info.bustype, info.vendor, info.product, name, phys, uniq);
877 	udev_list_insert(sysattrs, "uevent", uevent);
878 	free(uevent);
879 
880 bail_out:
881 	if (opened)
882 		close(fd);
883 }
884 #endif
885 
886 LIBUDEV_EXPORT int
udev_util_encode_string(const char * str,char * str_enc,size_t len)887 udev_util_encode_string(const char *str, char *str_enc, size_t len)
888 {
889 #ifdef ENABLE_GPL
890 	return (encode_devnode_name(str, str_enc, len));
891 #else
892 	return (strlcpy(str_enc, str, len) < len ? 0 : -EINVAL);
893 #endif
894 }
895