modprobe: do not descend into /etc/modprobe.d/DIR/. Closes 8686
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 6 Apr 2017 13:22:24 +0000 (15:22 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 6 Apr 2017 13:23:26 +0000 (15:23 +0200)
Also expanded comments in recursive_action.c

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
libbb/recursive_action.c
modutils/modprobe.c

index b5cf7c0ab4c365b543be36b84730dcf6fff58662..8f2b8b9320f05e1b1cfda1287aef5bbeaf1171de 100644 (file)
@@ -30,24 +30,37 @@ static int FAST_FUNC true_action(const char *fileName UNUSED_PARAM,
        return TRUE;
 }
 
-/* fileAction return value of 0 on any file in directory will make
- * recursive_action() return 0, but it doesn't stop directory traversal
+/* fileName is (l)stat'ed (depending on ACTION_FOLLOWLINKS[_L0]).
+ *
+ * If it is a file: fileAction in run on it, its return value is returned.
+ *
+ * In case we are in a recursive invocation (see below):
+ * normally, fileAction should return 1 (TRUE) to indicate that
+ * everything is okay and processing should continue.
+ * fileAction return value of 0 (FALSE) on any file in directory will make
+ * recursive_action() also return 0, but it doesn't stop directory traversal
  * (fileAction/dirAction will be called on each file).
  *
- * If !ACTION_RECURSE, dirAction is called on the directory and its
+ * [TODO: maybe introduce -1 to mean "stop traversal NOW and return"]
+ *
+ * If it is a directory:
+ *
+ * If !ACTION_RECURSE, dirAction is called and its
  * return value is returned from recursive_action(). No recursion.
  *
- * If ACTION_RECURSE, recursive_action() is called on each directory.
+ * If ACTION_RECURSE, directory is opened, and recursive_action() is called
+ * on each file/subdirectory.
  * If any one of these calls returns 0, current recursive_action() returns 0.
  *
+ * If !ACTION_DEPTHFIRST, dirAction is called before recurse.
+ * Return value of 0 (FALSE) is an error: prevents recursion,
+ * the warning is printed (unless ACTION_QUIET) and recursive_action() returns 0.
+ * Return value of 2 (SKIP) prevents recursion, instead recursive_action()
+ * returns 1 (TRUE, no error).
+ *
  * If ACTION_DEPTHFIRST, dirAction is called after recurse.
  * If it returns 0, the warning is printed and recursive_action() returns 0.
  *
- * If !ACTION_DEPTHFIRST, dirAction is called before we recurse.
- * Return value of 0 (FALSE) or 2 (SKIP) prevents recursion
- * into that directory, instead recursive_action() returns 0 (if FALSE)
- * or 1 (if SKIP)
- *
  * ACTION_FOLLOWLINKS mainly controls handling of links to dirs.
  * 0: lstat(statbuf). Calls fileAction on link name even if points to dir.
  * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir.
@@ -105,7 +118,7 @@ int FAST_FUNC recursive_action(const char *fileName,
 
        if (!(flags & ACTION_DEPTHFIRST)) {
                status = dirAction(fileName, &statbuf, userData, depth);
-               if (!status)
+               if (status == FALSE)
                        goto done_nak_warn;
                if (status == SKIP)
                        return TRUE;
@@ -121,24 +134,23 @@ int FAST_FUNC recursive_action(const char *fileName,
        status = TRUE;
        while ((next = readdir(dir)) != NULL) {
                char *nextFile;
+               int s;
 
                nextFile = concat_subpath_file(fileName, next->d_name);
                if (nextFile == NULL)
                        continue;
+
                /* process every file (NB: ACTION_RECURSE is set in flags) */
-               if (!recursive_action(nextFile, flags, fileAction, dirAction,
-                                               userData, depth + 1))
+               s = recursive_action(nextFile, flags, fileAction, dirAction,
+                                               userData, depth + 1);
+               if (s == FALSE)
                        status = FALSE;
-//             s = recursive_action(nextFile, flags, fileAction, dirAction,
-//                                             userData, depth + 1);
                free(nextFile);
-//#define RECURSE_RESULT_ABORT 3
+//#define RECURSE_RESULT_ABORT -1
 //             if (s == RECURSE_RESULT_ABORT) {
 //                     closedir(dir);
 //                     return s;
 //             }
-//             if (s == FALSE)
-//                     status = FALSE;
        }
        closedir(dir);
 
index c82eaa8d85f07efae6153ca6c7e2d44b34a4cc0b..51ede9204c73842fcd92f813d5e88d4772212b7b 100644 (file)
@@ -252,6 +252,15 @@ static int FAST_FUNC config_file_action(const char *filename,
        if (base[0] == '.')
                goto error;
 
+       /* "man modprobe.d" from kmod version 22 suggests
+        * that we shouldn't recurse into /etc/modprobe.d/dir/
+        * _subdirectories_:
+        */
+       if (depth > 1)
+               return SKIP; /* stop recursing */
+//TODO: instead, can use dirAction in recursive_action() to SKIP dirs
+//on depth == 1 level. But that's more code...
+
        /* In dir recursion, skip files that do not end with a ".conf"
         * depth==0: read_config("modules.{symbols,alias}") must work,
         * "include FILE_NOT_ENDING_IN_CONF" must work too.