+static bool device_has_tag(struct udev_device *d, const char *tag) {
+ struct udev_list_entry *first, *item;
+
+ assert(d);
+ assert(tag);
+
+ udev_device_get_is_initialized(d);
+
+ first = udev_device_get_tags_list_entry(d);
+ udev_list_entry_foreach(item, first)
+ if (streq(udev_list_entry_get_name(item), tag))
+ return true;
+
+ return false;
+}
+
+static int attach_device(Manager *m, const char *seat, const char *sysfs) {
+ struct udev_device *d;
+ char *rule = NULL, *file = NULL;
+ const char *id_for_seat;
+ int r;
+ struct udev_enumerate *e;
+ struct udev_list_entry *first, *item;
+
+ assert(m);
+ assert(seat);
+ assert(sysfs);
+
+ d = udev_device_new_from_syspath(m->udev, sysfs);
+ if (!d)
+ return -ENODEV;
+
+ if (!device_has_tag(d, "seat")) {
+ r = -ENODEV;
+ goto finish;
+ }
+
+ id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
+ if (!id_for_seat) {
+ r = -ENODEV;
+ goto finish;
+ }
+
+ if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ mkdir_p("/etc/udev/rules.d", 0755);
+ r = write_one_line_file(file, rule);
+ if (r < 0)
+ goto finish;
+
+ e = udev_enumerate_new(m->udev);
+ if (!e) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (udev_enumerate_scan_devices(e) < 0) {
+ r = -EIO;
+ goto finish;
+ }
+
+ first = udev_enumerate_get_list_entry(e);
+ udev_list_entry_foreach(item, first) {
+ char *t;
+ const char *p;
+
+ p = udev_list_entry_get_name(item);
+ if (!path_startswith(p, sysfs))
+ continue;
+
+ t = strappend(p, "/uevent");
+ if (!t) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ write_one_line_file(t, "change");
+ free(t);
+ }
+
+finish:
+ free(rule);
+ free(file);
+
+ if (d)
+ udev_device_unref(d);
+
+ if (e)
+ udev_enumerate_unref(e);
+
+ return r;
+}
+