]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/udev/udevadm.c
Merge pull request #11827 from keszybz/pkgconfig-variables
[thirdparty/systemd.git] / src / udev / udevadm.c
index 492b2f4c256496cd30b28872a102410d291bf65f..28194314de497484ef1b049e1c0e265de6bdcd8a 100644 (file)
@@ -1,99 +1,62 @@
-/*
- * Copyright (C) 2007-2012 Kay Sievers <kay@vrfy.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
+/* SPDX-License-Identifier: GPL-2.0+ */
 
 #include <errno.h>
 #include <getopt.h>
 #include <stddef.h>
 #include <stdio.h>
 
+#include "alloc-util.h"
+#include "main-func.h"
+#include "pretty-print.h"
 #include "selinux-util.h"
 #include "string-util.h"
-#include "udev.h"
+#include "udevadm.h"
+#include "udev-util.h"
+#include "verbs.h"
+#include "util.h"
+
+static int help(void) {
+        static const char * short_descriptions[][2] = {
+                { "info",         "Query sysfs or the udev database" },
+                { "trigger",      "Request events from the kernel"   },
+                { "settle",       "Wait for pending udev events"     },
+                { "control",      "Control the udev daemon"          },
+                { "monitor",      "Listen to kernel and udev events" },
+                { "test",         "Test an event run"                },
+                { "test-builtin", "Test a built-in command"          },
+        };
 
-static int adm_version(struct udev *udev, int argc, char *argv[]) {
-        printf("%s\n", PACKAGE_VERSION);
-        return 0;
-}
+        _cleanup_free_ char *link = NULL;
+        size_t i;
+        int r;
 
-static const struct udevadm_cmd udevadm_version = {
-        .name = "version",
-        .cmd = adm_version,
-};
-
-static int adm_help(struct udev *udev, int argc, char *argv[]);
-
-static const struct udevadm_cmd udevadm_help = {
-        .name = "help",
-        .cmd = adm_help,
-};
-
-static const struct udevadm_cmd *udevadm_cmds[] = {
-        &udevadm_info,
-        &udevadm_trigger,
-        &udevadm_settle,
-        &udevadm_control,
-        &udevadm_monitor,
-        &udevadm_hwdb,
-        &udevadm_test,
-        &udevadm_test_builtin,
-        &udevadm_version,
-        &udevadm_help,
-};
-
-static int adm_help(struct udev *udev, int argc, char *argv[]) {
-        unsigned int i;
+        r = terminal_urlify_man("udevadm", "8", &link);
+        if (r < 0)
+                return log_oom();
 
         printf("%s [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n\n"
                "Send control commands or test the device manager.\n\n"
                "Commands:\n"
                , program_invocation_short_name);
 
-        for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
-                if (udevadm_cmds[i]->help != NULL)
-                        printf("  %-12s  %s\n", udevadm_cmds[i]->name, udevadm_cmds[i]->help);
-        return 0;
-}
+        for (i = 0; i < ELEMENTSOF(short_descriptions); i++)
+                printf("  %-12s  %s\n", short_descriptions[i][0], short_descriptions[i][1]);
 
-static int run_command(struct udev *udev, const struct udevadm_cmd *cmd, int argc, char *argv[]) {
-        if (cmd->debug)
-                log_set_max_level(LOG_DEBUG);
-        log_debug("calling: %s", cmd->name);
-        return cmd->cmd(udev, argc, argv);
+        printf("\nSee the %s for details.\n", link);
+        return 0;
 }
 
-int main(int argc, char *argv[]) {
-        struct udev *udev;
+static int parse_argv(int argc, char *argv[]) {
         static const struct option options[] = {
-                { "debug", no_argument, NULL, 'd' },
-                { "help", no_argument, NULL, 'h' },
+                { "debug",   no_argument, NULL, 'd' },
+                { "help",    no_argument, NULL, 'h' },
                 { "version", no_argument, NULL, 'V' },
                 {}
         };
-        const char *command;
-        unsigned int i;
-        int rc = 1, c;
+        int c;
 
-        udev = udev_new();
-        if (udev == NULL)
-                goto out;
-
-        log_parse_environment();
-        log_open();
-        mac_selinux_init();
+        assert(argc >= 0);
+        assert(argv);
 
         while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
                 switch (c) {
@@ -103,35 +66,62 @@ int main(int argc, char *argv[]) {
                         break;
 
                 case 'h':
-                        rc = adm_help(udev, argc, argv);
-                        goto out;
+                        return help();
 
                 case 'V':
-                        rc = adm_version(udev, argc, argv);
-                        goto out;
+                        return print_version();
+
+                case '?':
+                        return -EINVAL;
 
                 default:
-                        goto out;
+                        assert_not_reached("Unhandled option");
                 }
 
-        command = argv[optind];
-
-        if (command != NULL)
-                for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
-                        if (streq(udevadm_cmds[i]->name, command)) {
-                                argc -= optind;
-                                argv += optind;
-                                /* we need '0' here to reset the internal state */
-                                optind = 0;
-                                rc = run_command(udev, udevadm_cmds[i], argc, argv);
-                                goto out;
-                        }
-
-        fprintf(stderr, "%s: missing or unknown command\n", program_invocation_short_name);
-        rc = 2;
-out:
-        mac_selinux_finish();
-        udev_unref(udev);
-        log_close();
-        return rc;
+        return 1; /* work to do */
+}
+
+static int version_main(int argc, char *argv[], void *userdata) {
+        return print_version();
+}
+
+static int help_main(int argc, char *argv[], void *userdata) {
+        return help();
 }
+
+static int udevadm_main(int argc, char *argv[]) {
+        static const Verb verbs[] = {
+                { "info",         VERB_ANY, VERB_ANY, 0, info_main    },
+                { "trigger",      VERB_ANY, VERB_ANY, 0, trigger_main },
+                { "settle",       VERB_ANY, VERB_ANY, 0, settle_main  },
+                { "control",      VERB_ANY, VERB_ANY, 0, control_main },
+                { "monitor",      VERB_ANY, VERB_ANY, 0, monitor_main },
+                { "hwdb",         VERB_ANY, VERB_ANY, 0, hwdb_main    },
+                { "test",         VERB_ANY, VERB_ANY, 0, test_main    },
+                { "test-builtin", VERB_ANY, VERB_ANY, 0, builtin_main },
+                { "version",      VERB_ANY, VERB_ANY, 0, version_main },
+                { "help",         VERB_ANY, VERB_ANY, 0, help_main    },
+                {}
+        };
+
+        return dispatch_verb(argc, argv, verbs, NULL);
+}
+
+static int run(int argc, char *argv[]) {
+        int r;
+
+        udev_parse_config();
+        log_parse_environment();
+        log_open();
+
+        r = parse_argv(argc, argv);
+        if (r <= 0)
+                return r;
+
+        log_set_max_level_realm(LOG_REALM_SYSTEMD, log_get_max_level());
+
+        mac_selinux_init();
+        return udevadm_main(argc, argv);
+}
+
+DEFINE_MAIN_FUNCTION(run);