+ memset(rules, 0x00, sizeof(struct udev_rules));
+ rules->resolve_names = resolve_names;
+
+ if (udev_rules_dir[0] != '\0') {
+ /* custom rules location for testing */
+ add_matching_files(&name_list, udev_rules_dir, RULESFILE_SUFFIX);
+ } else {
+ /* 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);