libmodprobe: add support to list modules

List the known modules with a name matching a given pattern.

Change-Id: I7f6bd1f09a688c66682f94c5837e61d7dc61c1f7
diff --git a/libmodprobe/include/modprobe/modprobe.h b/libmodprobe/include/modprobe/modprobe.h
index 03fb0a3..913a787 100644
--- a/libmodprobe/include/modprobe/modprobe.h
+++ b/libmodprobe/include/modprobe/modprobe.h
@@ -29,6 +29,7 @@
     bool LoadWithAliases(const std::string& module_name, bool strict,
                          const std::string& parameters = "");
     bool Remove(const std::string& module_name);
+    std::vector<std::string> ListModules(const std::string& pattern);
     void EnableBlacklist(bool enable);
 
   private:
diff --git a/libmodprobe/libmodprobe.cpp b/libmodprobe/libmodprobe.cpp
index 354ec7b..0106242 100644
--- a/libmodprobe/libmodprobe.cpp
+++ b/libmodprobe/libmodprobe.cpp
@@ -363,3 +363,16 @@
     }
     return true;
 }
+
+std::vector<std::string> Modprobe::ListModules(const std::string& pattern) {
+    std::vector<std::string> rv;
+    for (const auto& [module, deps] : module_deps_) {
+        // Attempt to match both the canonical module name and the module filename.
+        if (!fnmatch(pattern.c_str(), module.c_str(), 0)) {
+            rv.emplace_back(module);
+        } else if (!fnmatch(pattern.c_str(), basename(deps[0].c_str()), 0)) {
+            rv.emplace_back(deps[0]);
+        }
+    }
+    return rv;
+}