- static const char *delay_device_list[] = {
- "*/md*",
- "*/dm-*",
- NULL
- };
- int i;
-
- for (i = 0; delay_device_list[i] != NULL; i++)
- if (fnmatch(delay_device_list[i], syspath, 0) == 0)
- return 1;
- return 0;
-}
-
-static int device_list_insert(struct udev *udev, const char *path)
-{
- char filename[UTIL_PATH_SIZE];
- struct stat statbuf;
-
- dbg(udev, "add '%s'\n" , path);
-
- /* we only have a device, if we have an uevent file */
- util_strlcpy(filename, path, sizeof(filename));
- util_strlcat(filename, "/uevent", sizeof(filename));
- if (stat(filename, &statbuf) < 0)
- return -1;
- if (!(statbuf.st_mode & S_IWUSR))
- return -1;
-
- /* resolve possible link to real target */
- util_strlcpy(filename, path, sizeof(filename));
- if (lstat(filename, &statbuf) < 0)
- return -1;
- if (S_ISLNK(statbuf.st_mode))
- if (util_resolve_sys_link(udev, filename, sizeof(filename)) != 0)
- return -1;
-
- name_list_add(udev, &device_list, filename, 1);
- return 0;
-}
-
-static void trigger_uevent(struct udev *udev, const char *syspath, const char *action)
-{
- char filename[UTIL_PATH_SIZE];
- int fd;
-
- util_strlcpy(filename, syspath, sizeof(filename));
- util_strlcat(filename, "/uevent", sizeof(filename));
-
- if (verbose)
- printf("%s\n", syspath);
-
- if (dry_run)
- return;
-
- fd = open(filename, O_WRONLY);
- if (fd < 0) {
- dbg(udev, "error on opening %s: %s\n", filename, strerror(errno));
- return;
- }
-
- if (write(fd, action, strlen(action)) < 0)
- info(udev, "error writing '%s' to '%s': %s\n", action, filename, strerror(errno));
-
- close(fd);
-}
-
-static int pass_to_socket(struct udev *udev, const char *syspath, const char *action, const char *env)
-{
- struct udevice *udevice;
- struct name_entry *name_loop;
- char buf[4096];
- size_t bufpos = 0;
- ssize_t count;
- char path[UTIL_PATH_SIZE];
- int fd;
- char link_target[UTIL_PATH_SIZE];
- int len;
- const char *devpath = &syspath[strlen(udev_get_sys_path(udev))];
- int err = 0;
-
- if (verbose)
- printf("%s\n", devpath);
-
- udevice = udev_device_init(udev);
- if (udevice == NULL)
- return -1;
- udev_db_get_device(udevice, 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 */
- util_strlcpy(path, udev_get_sys_path(udev), sizeof(path));
- util_strlcat(path, devpath, sizeof(path));
- util_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, &udevice->symlink_list, node) {
- util_strlcat(path, udev_get_dev_path(udev), sizeof(path));
- util_strlcat(path, "/", sizeof(path));
- util_strlcat(path, name_loop->name, sizeof(path));
- util_strlcat(path, " ", sizeof(path));
- }
- util_remove_trailing_chars(path, ' ');
- if (path[0] != '\0') {
- bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "DEVLINKS=%s", path);
- bufpos++;
- }
- if (udevice->name[0] != '\0') {
- util_strlcpy(path, udev_get_dev_path(udev), sizeof(path));
- util_strlcat(path, "/", sizeof(path));
- util_strlcat(path, udevice->name, sizeof(path));
- bufpos += snprintf(&buf[bufpos], sizeof(buf)-1, "DEVNAME=%s", path);
- bufpos++;
- }
-
- /* add keys from device "uevent" file */
- util_strlcpy(path, syspath, sizeof(path));
- util_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 += util_strlcpy(&buf[bufpos], key, sizeof(buf) - bufpos-1);
- bufpos++;
- key = &next[1];
- }
- }
- }
-
- /* add keys from database */
- list_for_each_entry(name_loop, &udevice->env_list, node) {
- bufpos += util_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(struct udev *udev, 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(udev, loop_device->name, action, env);
- else
- trigger_uevent(udev, loop_device->name, action);
- list_del(&loop_device->node);
- free(loop_device);
- }