- struct name_entry *name_loop, *name_tmp;
- LIST_HEAD(name_list);
-
- dbg("parse rules directory '%s'", udev_rules_dir);
- retval = add_matching_files(&name_list, udev_rules_dir, RULESFILE_SUFFIX);
-
- list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) {
- if (stat(name_loop->name, &stats) == 0) {
- if (stats.st_size)
- parse_file(rules, name_loop->name);
- else
- dbg("empty rules file '%s'", name_loop->name);
- } else
- err("could not read '%s': %s", name_loop->name, strerror(errno));
- list_del(&name_loop->node);
- free(name_loop);
+ /* read default rules */
+ add_matching_files(&name_list, RULES_LIB_DIR, RULESFILE_SUFFIX);
+
+ /* read user/custom rules */
+ add_matching_files(&sort_list, RULES_ETC_DIR, RULESFILE_SUFFIX);
+
+ /* read dynamic/temporary rules */
+ strlcpy(filename, udev_root, sizeof(filename));
+ strlcat(filename, "/"RULES_DYN_DIR, sizeof(filename));
+ if (stat(filename, &statbuf) != 0) {
+ create_path(filename);
+ selinux_setfscreatecon(filename, NULL, S_IFDIR|0755);
+ mkdir(filename, 0755);
+ selinux_resetfscreatecon();
+ }
+ add_matching_files(&sort_list, filename, RULESFILE_SUFFIX);
+
+ /* sort all rules files by basename into list of files */
+ list_for_each_entry_safe(sort_loop, sort_tmp, &sort_list, node) {
+ const char *sort_base = strrchr(sort_loop->name, '/');
+
+ if (sort_base == NULL)
+ continue;
+
+ list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) {
+ const char *name_base = strrchr(name_loop->name, '/');
+
+ if (name_base == NULL)
+ continue;
+
+ if (strcmp(name_base, sort_base) > 0)
+ break;
+ }
+ list_move_tail(&sort_loop->node, &name_loop->node);