root/tools/crm_error.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. result_type_cb
  2. build_arg_context
  3. main

   1 /*
   2  * Copyright 2012-2023 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 #include <crm/msg_xml.h>
  12 #include <crm/common/cmdline_internal.h>
  13 #include <crm/common/output_internal.h>
  14 #include <crm/common/strings_internal.h>
  15 
  16 #include <crm/crm.h>
  17 
  18 #include <pacemaker-internal.h>
  19 
  20 #define SUMMARY "crm_error - display name or description of a Pacemaker error code"
  21 
  22 struct {
  23     gboolean with_name;
  24     gboolean do_list;
  25     enum pcmk_result_type result_type; // How to interpret result codes
  26 } options = {
  27     .result_type = pcmk_result_legacy,
  28 };
  29 
  30 static gboolean
  31 result_type_cb(const gchar *option_name, const gchar *optarg, gpointer data,
     /* [previous][next][first][last][top][bottom][index][help] */
  32                GError **error)
  33 {
  34     if (pcmk__str_any_of(option_name, "--exit", "-X", NULL)) {
  35         options.result_type = pcmk_result_exitcode;
  36     } else if (pcmk__str_any_of(option_name, "--rc", "-r", NULL)) {
  37         options.result_type = pcmk_result_rc;
  38     }
  39 
  40     return TRUE;
  41 }
  42 
  43 static GOptionEntry entries[] = {
  44     { "name", 'n', 0, G_OPTION_ARG_NONE, &options.with_name,
  45       "Show error's name with its description (useful for looking for sources "
  46       "of the error in source code)",
  47        NULL },
  48     { "list", 'l', 0, G_OPTION_ARG_NONE, &options.do_list,
  49       "Show all known errors (enabled by default if no rc is specified)",
  50       NULL },
  51     { "exit", 'X', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, result_type_cb,
  52       "Interpret as exit code rather than legacy function return value",
  53       NULL },
  54     { "rc", 'r', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, result_type_cb,
  55       "Interpret as return code rather than legacy function return value",
  56       NULL },
  57 
  58     { NULL }
  59 };
  60 
  61 static pcmk__supported_format_t formats[] = {
  62     PCMK__SUPPORTED_FORMAT_NONE,
  63     PCMK__SUPPORTED_FORMAT_TEXT,
  64     PCMK__SUPPORTED_FORMAT_XML,
  65     { NULL, NULL, NULL }
  66 };
  67 
  68 static GOptionContext *
  69 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
     /* [previous][next][first][last][top][bottom][index][help] */
  70     GOptionContext *context = NULL;
  71 
  72     context = pcmk__build_arg_context(args, "text (default), xml", group,
  73                                       "[-- <rc> [<rc>...]]");
  74     pcmk__add_main_args(context, entries);
  75     return context;
  76 }
  77 
  78 int
  79 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81     crm_exit_t exit_code = CRM_EX_OK;
  82     int rc = pcmk_rc_ok;
  83 
  84     pcmk__output_t *out = NULL;
  85 
  86     GError *error = NULL;
  87 
  88     GOptionGroup *output_group = NULL;
  89     pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
  90     gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
  91     GOptionContext *context = build_arg_context(args, &output_group);
  92 
  93     pcmk__register_formats(output_group, formats);
  94     if (!g_option_context_parse_strv(context, &processed_args, &error)) {
  95         exit_code = CRM_EX_USAGE;
  96         goto done;
  97     }
  98 
  99     pcmk__cli_init_logging("crm_error", args->verbosity);
 100 
 101     rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
 102     if (rc != pcmk_rc_ok) {
 103         exit_code = CRM_EX_ERROR;
 104         g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
 105                     "Error creating output format %s: %s", args->output_ty,
 106                     pcmk_rc_str(rc));
 107         goto done;
 108     }
 109 
 110     if (g_strv_length(processed_args) < 2) {
 111         // If no result codes were specified, list them all
 112         options.do_list = TRUE;
 113     }
 114 
 115     if (args->version) {
 116         out->version(out, false);
 117         goto done;
 118     }
 119 
 120     pcmk__register_lib_messages(out);
 121 
 122     if (options.do_list) {
 123         uint32_t flags = pcmk_rc_disp_code|pcmk_rc_disp_desc;
 124 
 125         if (options.with_name) {
 126             flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE,
 127                                        "pcmk_rc_disp_flags",
 128                                        "pcmk__list_result_codes", flags,
 129                                        pcmk_rc_disp_name, "pcmk_rc_disp_name");
 130         }
 131         pcmk__list_result_codes(out, options.result_type, flags);
 132 
 133     } else {
 134         uint32_t flags = pcmk_rc_disp_desc;
 135 
 136         // For text output, print only "[name -] description" by default
 137         if (args->verbosity > 0) {
 138             flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE,
 139                                        "pcmk_rc_disp_flags",
 140                                        "pcmk__show_result_code", flags,
 141                                        pcmk_rc_disp_code, "pcmk_rc_disp_code");
 142         }
 143 
 144         if (options.with_name) {
 145             flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE,
 146                                        "pcmk_rc_disp_flags",
 147                                        "pcmk__show_result_code", flags,
 148                                        pcmk_rc_disp_name, "pcmk_rc_disp_name");
 149         }
 150 
 151         /* Skip #1 because that's the program name. */
 152         for (int lpc = 1; processed_args[lpc] != NULL; lpc++) {
 153             int code = 0;
 154 
 155             if (pcmk__str_eq(processed_args[lpc], "--", pcmk__str_none)) {
 156                 continue;
 157             }
 158             pcmk__scan_min_int(processed_args[lpc], &code, INT_MIN);
 159             pcmk__show_result_code(out, code, options.result_type, flags);
 160         }
 161     }
 162 
 163  done:
 164     g_strfreev(processed_args);
 165     pcmk__free_arg_context(context);
 166 
 167     pcmk__output_and_clear_error(&error, out);
 168 
 169     if (out != NULL) {
 170         out->finish(out, exit_code, true, NULL);
 171         pcmk__output_free(out);
 172     }
 173     pcmk__unregister_formats();
 174     crm_exit(exit_code);
 175 }

/* [previous][next][first][last][top][bottom][index][help] */