- if (dry_run)
- return;
-
- fd = open(filename, O_WRONLY);
- if (fd < 0) {
- dbg("error on opening %s: %s\n", filename, strerror(errno));
- return;
- }
-
- if (write(fd, action, strlen(action)) < 0)
- info("error writing '%s' to '%s': %s\n", action, filename, strerror(errno));
-
- close(fd);
-}
-
-static int pass_to_socket(const char *devpath, const char *action, const char *env)
-{
- struct udevice *udev;
- struct name_entry *name_loop;
- char buf[4096];
- size_t bufpos = 0;
- ssize_t count;
- char path[PATH_SIZE];
- int fd;
- char link_target[PATH_SIZE];
- int len;
- int err = 0;
-
- if (verbose)
- printf("%s\n", devpath);
-
- udev = udev_device_init();
- if (udev == NULL)
- return -1;
- udev_db_get_device(udev, devpath);
-
- /* add header */
- bufpos = snprintf(buf, sizeof(buf)-1, "%s@%s", action, devpath);
- bufpos++;
-
- /* add cookie */
- if (env != NULL) {
- bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "%s", env);
- bufpos++;
- }
-
- /* add standard keys */
- bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "DEVPATH=%s", devpath);
- bufpos++;
- bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "ACTION=%s", action);
- bufpos++;
-
- /* add subsystem */
- strlcpy(path, sysfs_path, sizeof(path));
- strlcat(path, devpath, sizeof(path));
- strlcat(path, "/subsystem", sizeof(path));
- len = readlink(path, link_target, sizeof(link_target));
- if (len > 0) {
- char *pos;
-
- link_target[len] = '\0';
- pos = strrchr(link_target, '/');
- if (pos != NULL) {
- bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "SUBSYSTEM=%s", &pos[1]);
- bufpos++;
- }
- }
-
- /* add symlinks and node name */
- path[0] = '\0';
- list_for_each_entry(name_loop, &udev->symlink_list, node) {
- strlcat(path, udev_root, sizeof(path));
- strlcat(path, "/", sizeof(path));
- strlcat(path, name_loop->name, sizeof(path));
- strlcat(path, " ", sizeof(path));
- }
- remove_trailing_chars(path, ' ');
- if (path[0] != '\0') {
- bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "DEVLINKS=%s", path);
- bufpos++;
- }
- if (udev->name[0] != '\0') {
- strlcpy(path, udev_root, sizeof(path));
- strlcat(path, "/", sizeof(path));
- strlcat(path, udev->name, sizeof(path));
- bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "DEVNAME=%s", path);
- bufpos++;
- }
-
- /* add keys from device "uevent" file */
- strlcpy(path, sysfs_path, sizeof(path));
- strlcat(path, devpath, sizeof(path));
- strlcat(path, "/uevent", sizeof(path));
- fd = open(path, O_RDONLY);
- if (fd >= 0) {
- char value[4096];
-
- count = read(fd, value, sizeof(value));
- close(fd);
- if (count > 0) {
- char *key;
-
- value[count] = '\0';
- key = value;
- while (key[0] != '\0') {
- char *next;
-
- next = strchr(key, '\n');
- if (next == NULL)
- break;
- next[0] = '\0';
- bufpos += strlcpy(&buf[bufpos], key, sizeof(buf) - bufpos-1);
- bufpos++;
- key = &next[1];
- }
- }
- }
-
- /* add keys from database */
- list_for_each_entry(name_loop, &udev->env_list, node) {
- bufpos += strlcpy(&buf[bufpos], name_loop->name, sizeof(buf) - bufpos-1);
- bufpos++;
- }
- if (bufpos > sizeof(buf))
- bufpos = sizeof(buf);
-
- count = sendto(sock, &buf, bufpos, 0, (struct sockaddr *)&saddr, saddrlen);
- if (count < 0)
- err = -1;
-
- return err;
-}
-
-static void exec_list(const char *action, const char *env)
-{
- struct name_entry *loop_device;
- struct name_entry *tmp_device;
-
- list_for_each_entry_safe(loop_device, tmp_device, &device_list, node) {
- if (delay_device(loop_device->name))
- continue;
- if (sock >= 0)
- pass_to_socket(loop_device->name, action, env);
- else
- trigger_uevent(loop_device->name, action);
- list_del(&loop_device->node);
- free(loop_device);
- }
-
- /* trigger remaining delayed devices */
- list_for_each_entry_safe(loop_device, tmp_device, &device_list, node) {
- if (sock >= 0)
- pass_to_socket(loop_device->name, action, env);
- else
- trigger_uevent(loop_device->name, action);
- list_del(&loop_device->node);
- free(loop_device);
- }
-}
-
-static int subsystem_filtered(const char *subsystem)
-{
- struct name_entry *loop_name;
-
- /* skip devices matching the listed subsystems */
- list_for_each_entry(loop_name, &filter_subsystem_nomatch_list, node)
- if (fnmatch(loop_name->name, subsystem, 0) == 0)
- return 1;
-
- /* skip devices not matching the listed subsystems */
- if (!list_empty(&filter_subsystem_match_list)) {
- list_for_each_entry(loop_name, &filter_subsystem_match_list, node)
- if (fnmatch(loop_name->name, subsystem, 0) == 0)
- return 0;
- return 1;
- }
-
- return 0;
-}
-
-static int attr_match(const char *path, const char *attr_value)
-{
- char attr[NAME_SIZE];
- char file[PATH_SIZE];
- char *match_value;
-
- strlcpy(attr, attr_value, sizeof(attr));
-
- /* separate attr and match value */
- match_value = strchr(attr, '=');
- if (match_value != NULL) {
- match_value[0] = '\0';
- match_value = &match_value[1];
- }
-
- strlcpy(file, path, sizeof(file));
- strlcat(file, "/", sizeof(file));
- strlcat(file, attr, sizeof(file));
-
- if (match_value != NULL) {
- /* match file content */
- char value[NAME_SIZE];