From 5c4fa7b9b228e80e914b9db4639a2f75608647a2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 19 Jan 2025 05:17:14 +0900 Subject: [PATCH] integritysetup: use dispatch_verb() --- src/integritysetup/integritysetup.c | 171 ++++++++++++++-------------- 1 file changed, 86 insertions(+), 85 deletions(-) diff --git a/src/integritysetup/integritysetup.c b/src/integritysetup/integritysetup.c index a602886cb3e..56c02d4ad89 100644 --- a/src/integritysetup/integritysetup.c +++ b/src/integritysetup/integritysetup.c @@ -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); -- 2.47.3