kmod-modprobe: implement --dump-modversions
diff --git a/TODO b/TODO
index e6451af..0708a7e 100644
--- a/TODO
+++ b/TODO
@@ -18,7 +18,6 @@
 * Add functions list all modules known by modules.dep
 
 * provide 1:1 compatibility with module-init-tools's modprobe
-   - show modversions (needs elf manipulation)
    - dump configuration
 
 * provide modules.archive, a cache file with all modules compressed
diff --git a/tools/kmod-modprobe.c b/tools/kmod-modprobe.c
index 4680a58..f7fbaff 100644
--- a/tools/kmod-modprobe.c
+++ b/tools/kmod-modprobe.c
@@ -232,15 +232,30 @@
 
 static int show_modversions(struct kmod_ctx *ctx, const char *filename)
 {
-	ERR("TODO - modversions is missing in kmod.\n");
-	/*
-	  needs:
-	    struct kmod_list *kmod_module_get_modversions(struct kmod_module *mod);
-	    kmod_module_modversion_get_address() [needs better naming?]
-	    kmod_module_modversion_get_name() [needs better naming?]
-	    kmod_module_modversion_unref_list()
-	 */
-	return -ENOENT;
+	struct kmod_list *l, *list = NULL;
+	struct kmod_module *mod;
+	int err = kmod_module_new_from_path(ctx, filename, &mod);
+	if (err < 0) {
+		LOG("Module %s not found.\n", filename);
+		return err;
+	}
+
+	err = kmod_module_get_versions(mod, &list);
+	if (err < 0) {
+		LOG("Could not get modversions of %s: %s\n",
+			filename, strerror(-err));
+		kmod_module_unref(mod);
+		return err;
+	}
+
+	kmod_list_foreach(l, list) {
+		const char *symbol = kmod_module_version_get_symbol(l);
+		uint64_t crc = kmod_module_version_get_crc(l);
+		printf("0x%08"PRIx64"\t%s\n", crc, symbol);
+	}
+	kmod_module_versions_free_list(list);
+	kmod_module_unref(mod);
+	return 0;
 }
 
 static int command_do(struct kmod_module *module, const char *type, const char *command, const char *cmdline_opts)