]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
integritysetup: use dispatch_verb() 36072/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 18 Jan 2025 20:17:14 +0000 (05:17 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 20 Jan 2025 18:42:38 +0000 (03:42 +0900)
src/integritysetup/integritysetup.c

index a602886cb3e9fe6a610efdb5f0883cbdc25c1871..56c02d4ad890b99090d4d99d4edcdc10df6781f4 100644 (file)
@@ -18,6 +18,7 @@
 #include "process-util.h"
 #include "string-util.h"
 #include "terminal-util.h"
+#include "verbs.h"
 
 static uint32_t arg_activate_flags;
 static int arg_percent;
@@ -86,118 +87,118 @@ static const char *integrity_algorithm_select(const void *key_file_buf) {
         return "crc32c";
 }
 
-static int run(int argc, char *argv[]) {
+static int verb_attach(int argc, char *argv[], void *userdata) {
         _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
-        char *verb, *volume;
+        crypt_status_info status;
+        _cleanup_(erase_and_freep) void *key_buf = NULL;
+        size_t key_buf_size = 0;
         int r;
 
-        if (argv_looks_like_help(argc, argv))
-                return help();
+        /* attach name device optional_key_file optional_options */
 
-        if (argc < 3)
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires at least two arguments.");
+        assert(argc >= 3 && argc <= 5);
 
-        verb = argv[1];
-        volume = argv[2];
+        const char *volume = argv[1],
+                *device = argv[2],
+                *key_file = mangle_none(argc > 3 ? argv[3] : NULL),
+                *options = mangle_none(argc > 4 ? argv[4] : NULL);
 
-        log_setup();
+        if (!filename_is_valid(volume))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
 
-        cryptsetup_enable_logging(NULL);
+        if (key_file) {
+                r = load_key_file(key_file, &key_buf, &key_buf_size);
+                if (r < 0)
+                        return r;
+        }
 
-        umask(0022);
+        if (options) {
+                r = parse_integrity_options(options, &arg_activate_flags, &arg_percent,
+                                            &arg_commit_time, &arg_existing_data_device, &arg_integrity_algorithm);
+                if (r < 0)
+                        return r;
+        }
 
-        if (streq(verb, "attach")) {
-                /* attach name device optional_key_file optional_options */
+        r = crypt_init(&cd, device);
+        if (r < 0)
+                return log_error_errno(r, "Failed to open integrity device %s: %m", device);
 
-                crypt_status_info status;
-                _cleanup_(erase_and_freep) void *key_buf = NULL;
-                const char *device, *key_file, *options;
-                size_t key_buf_size = 0;
+        cryptsetup_enable_logging(cd);
 
-                if (argc < 4)
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach requires at least three arguments.");
+        status = crypt_status(cd, volume);
+        if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
+                log_info("Volume %s already active.", volume);
+                return 0;
+        }
 
-                if (argc > 6)
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "attach has a maximum of five arguments.");
+        r = crypt_load(cd,
+                       CRYPT_INTEGRITY,
+                       &(struct crypt_params_integrity) {
+                               .journal_watermark = arg_percent,
+                               .journal_commit_time = DIV_ROUND_UP(arg_commit_time, USEC_PER_SEC),
+                               .integrity = integrity_algorithm_select(key_buf),
+                       });
+        if (r < 0)
+                return log_error_errno(r, "Failed to load integrity superblock: %m");
 
-                device = argv[3];
-                key_file = mangle_none(argc > 4 ? argv[4] : NULL);
-                options = mangle_none(argc > 5 ? argv[5] : NULL);
+        if (!isempty(arg_existing_data_device)) {
+                r = crypt_set_data_device(cd, arg_existing_data_device);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to add separate data device: %m");
+        }
 
-                if (!filename_is_valid(volume))
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
+        r = crypt_activate_by_volume_key(cd, volume, key_buf, key_buf_size, arg_activate_flags);
+        if (r < 0)
+                return log_error_errno(r, "Failed to set up integrity device: %m");
 
-                if (key_file) {
-                        r = load_key_file(key_file, &key_buf, &key_buf_size);
-                        if (r < 0)
-                                return r;
-                }
+        return 0;
+}
 
-                if (options) {
-                        r = parse_integrity_options(options, &arg_activate_flags, &arg_percent,
-                                                    &arg_commit_time, &arg_existing_data_device, &arg_integrity_algorithm);
-                        if (r < 0)
-                                return r;
-                }
+static int verb_detach(int argc, char *argv[], void *userdata) {
+        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
+        int r;
 
-                r = crypt_init(&cd, device);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to open integrity device %s: %m", device);
-
-                cryptsetup_enable_logging(cd);
-
-                status = crypt_status(cd, volume);
-                if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
-                        log_info("Volume %s already active.", volume);
-                        return 0;
-                }
-
-                r = crypt_load(cd,
-                        CRYPT_INTEGRITY,
-                        &(struct crypt_params_integrity) {
-                                .journal_watermark = arg_percent,
-                                .journal_commit_time = DIV_ROUND_UP(arg_commit_time, USEC_PER_SEC),
-                                .integrity = integrity_algorithm_select(key_buf),
-                        });
-                if (r < 0)
-                        return log_error_errno(r, "Failed to load integrity superblock: %m");
+        assert(argc == 2);
 
-                if (!isempty(arg_existing_data_device)) {
-                        r = crypt_set_data_device(cd, arg_existing_data_device);
-                        if (r < 0)
-                                return log_error_errno(r, "Failed to add separate data device: %m");
-                }
+        const char *volume = argv[1];
 
-                r = crypt_activate_by_volume_key(cd, volume, key_buf, key_buf_size, arg_activate_flags);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to set up integrity device: %m");
+        if (!filename_is_valid(volume))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
 
-        } else if (streq(verb, "detach")) {
+        r = crypt_init_by_name(&cd, volume);
+        if (r == -ENODEV) {
+                log_info("Volume %s already inactive.", volume);
+                return 0;
+        }
+        if (r < 0)
+                return log_error_errno(r, "crypt_init_by_name() failed: %m");
 
-                if (argc > 3)
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "detach has a maximum of two arguments.");
+        cryptsetup_enable_logging(cd);
 
-                if (!filename_is_valid(volume))
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
+        r = crypt_deactivate(cd, volume);
+        if (r < 0)
+                return log_error_errno(r, "Failed to deactivate: %m");
 
-                r = crypt_init_by_name(&cd, volume);
-                if (r == -ENODEV) {
-                        log_info("Volume %s already inactive.", volume);
-                        return 0;
-                }
-                if (r < 0)
-                        return log_error_errno(r, "crypt_init_by_name() failed: %m");
+        return 0;
+}
 
-                cryptsetup_enable_logging(cd);
+static int run(int argc, char *argv[]) {
+        if (argv_looks_like_help(argc, argv))
+                return help();
 
-                r = crypt_deactivate(cd, volume);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to deactivate: %m");
+        log_setup();
 
-        } else
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", verb);
+        cryptsetup_enable_logging(NULL);
 
-        return 0;
+        umask(0022);
+
+        static const Verb verbs[] = {
+                { "attach", 3, 5, 0, verb_attach },
+                { "detach", 2, 2, 0, verb_detach },
+                {}
+        };
+
+        return dispatch_verb(argc, argv, verbs, NULL);
 }
 
 DEFINE_MAIN_FUNCTION(run);