chiark / gitweb /
simplify rules file overwrite logic
[elogind.git] / udev / udevadm-info.c
index a231fd8d0b37d0a32a3b309cab816c5b60b53da0..87c1c32314b2d0784c9d9cf2e0745ad72dc166e4 100644 (file)
@@ -33,7 +33,7 @@
 
 static bool skip_attribute(const char *name)
 {
-       char *skip[] = {
+       static const char const *skip[] = {
                "uevent",
                "dev",
                "modalias",
@@ -200,64 +200,79 @@ static int export_devices(struct udev *udev)
        return 0;
 }
 
-static int convert_db(struct udev *udev)
+static void cleanup_dir(DIR *dir, mode_t mask, int depth)
 {
-       struct udev_enumerate *udev_enumerate;
-       struct udev_list_entry *list_entry;
+       struct dirent *dent;
 
-       udev_enumerate = udev_enumerate_new(udev);
-       if (udev_enumerate == NULL)
-               return -1;
-       udev_enumerate_scan_devices(udev_enumerate);
-       udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
-               struct udev_device *device;
+       if (depth <= 0)
+               return;
 
-               device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
-               if (device != NULL) {
-                       const char *id;
-                       struct stat stats;
-                       char to[UTIL_PATH_SIZE];
-                       char devpath[UTIL_PATH_SIZE];
-                       char from[UTIL_PATH_SIZE];
-
-                       id = udev_device_get_id_filename(device);
-                       if (id == NULL) {
-                               udev_device_unref(device);
-                               continue;
-                       }
-                       util_strscpyl(to, sizeof(to), udev_get_dev_path(udev), "/.udev/db/", id, NULL);
-
-                       /* find old database with $subsys:$sysname */
-                       util_strscpyl(from, sizeof(from), udev_get_dev_path(udev),
-                                    "/.udev/db/", udev_device_get_subsystem(device), ":",
-                                    udev_device_get_sysname(device), NULL);
-                       if (lstat(from, &stats) == 0) {
-                               if (lstat(to, &stats) == 0)
-                                       unlink(from);
-                               else
-                                       rename(from, to);
-                       }
+       for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
+               struct stat stats;
+
+               if (dent->d_name[0] == '.')
+                       continue;
+               if (fstatat(dirfd(dir), dent->d_name, &stats, AT_SYMLINK_NOFOLLOW) != 0)
+                       continue;
+               if ((stats.st_mode & mask) != 0)
+                       continue;
+               if (S_ISDIR(stats.st_mode)) {
+                       DIR *dir2;
 
-                       /* find old database with the encoded devpath */
-                       util_path_encode(udev_device_get_devpath(device), devpath, sizeof(devpath));
-                       util_strscpyl(from, sizeof(from), udev_get_dev_path(udev),
-                                     "/.udev/db/", devpath, NULL);
-                       if (lstat(from, &stats) == 0) {
-                               if (lstat(to, &stats) == 0)
-                                       unlink(from);
-                               else
-                                       rename(from, to);
+                       dir2 = fdopendir(openat(dirfd(dir), dent->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC));
+                       if (dir2 != NULL) {
+                               cleanup_dir(dir2, mask, depth-1);
+                               closedir(dir2);
                        }
+                       unlinkat(dirfd(dir), dent->d_name, AT_REMOVEDIR);
+               } else {
+                       unlinkat(dirfd(dir), dent->d_name, 0);
+               }
+       }
+}
 
-                       /* read the old database, and write out a new one */
-                       udev_device_read_db(device);
-                       udev_device_update_db(device);
+static void cleanup_db(struct udev *udev)
+{
+       char filename[UTIL_PATH_SIZE];
+       DIR *dir;
 
-                       udev_device_unref(device);
-               }
+       util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/queue.bin", NULL);
+       unlink(filename);
+
+       util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/data", NULL);
+       dir = opendir(filename);
+       if (dir != NULL) {
+               cleanup_dir(dir, S_ISVTX, 1);
+               closedir(dir);
+       }
+
+       util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/links", NULL);
+       dir = opendir(filename);
+       if (dir != NULL) {
+               cleanup_dir(dir, 0, 2);
+               closedir(dir);
+       }
+
+       util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/tags", NULL);
+       dir = opendir(filename);
+       if (dir != NULL) {
+               cleanup_dir(dir, 0, 2);
+               closedir(dir);
+       }
+
+       util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/watch", NULL);
+       dir = opendir(filename);
+       if (dir != NULL) {
+               cleanup_dir(dir, 0, 1);
+               closedir(dir);
+       }
+
+       util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/firmware-missing", NULL);
+       dir = opendir(filename);
+       if (dir != NULL) {
+               cleanup_dir(dir, 0, 1);
+               closedir(dir);
        }
-       udev_enumerate_unref(udev_enumerate);
-       return 0;
 }
 
 int udevadm_info(struct udev *udev, int argc, char *argv[])
@@ -276,9 +291,10 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
                { "path", required_argument, NULL, 'p' },
                { "query", required_argument, NULL, 'q' },
                { "attribute-walk", no_argument, NULL, 'a' },
+               { "cleanup-db", no_argument, NULL, 'c' },
                { "export-db", no_argument, NULL, 'e' },
-               { "convert-db", no_argument, NULL, 'C' },
                { "root", no_argument, NULL, 'r' },
+               { "run", no_argument, NULL, 'R' },
                { "device-id-of-file", required_argument, NULL, 'd' },
                { "export", no_argument, NULL, 'x' },
                { "export-prefix", required_argument, NULL, 'P' },
@@ -308,7 +324,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
                int option;
                struct stat statbuf;
 
-               option = getopt_long(argc, argv, "aed:n:p:q:rxP:Vh", options, NULL);
+               option = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL);
                if (option == -1)
                        break;
 
@@ -392,6 +408,9 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
                                action = ACTION_ROOT;
                        root = true;
                        break;
+               case 'R':
+                       printf("%s\n", udev_get_run_path(udev));
+                       goto exit;
                case 'd':
                        action = ACTION_DEVICE_ID_FILE;
                        util_strscpy(name, sizeof(name), optarg);
@@ -402,8 +421,8 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
                case 'e':
                        export_devices(udev);
                        goto exit;
-               case 'C':
-                       convert_db(udev);
+               case 'c':
+                       cleanup_db(udev);
                        goto exit;
                case 'x':
                        export = true;
@@ -431,7 +450,7 @@ int udevadm_info(struct udev *udev, int argc, char *argv[])
                               "  --export                   export key/value pairs\n"
                               "  --export-prefix            export the key name with a prefix\n"
                               "  --export-db                export the content of the udev database\n"
-                              "  --convert-db               convert older version of database without a reboot\n"
+                              "  --cleanup-db               cleanup the udev database\n"
                               "  --help\n\n");
                        goto exit;
                default: