root/tools/crm_error.c

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

DEFINITIONS

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

   1 /*
   2  * Copyright 2012-2021 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/common/cmdline_internal.h>
  12 #include <crm/common/output_internal.h>
  13 #include <crm/common/strings_internal.h>
  14 
  15 #include <crm/crm.h>
  16 
  17 #define SUMMARY "crm_error - display name or description of a Pacemaker error code"
  18 
  19 struct {
  20     gboolean as_exit_code;
  21     gboolean as_rc;
  22     gboolean with_name;
  23     gboolean do_list;
  24 } options;
  25 
  26 static GOptionEntry entries[] = {
  27     { "name", 'n', 0, G_OPTION_ARG_NONE, &options.with_name,
  28       "Show error's name with its description (useful for looking for sources "
  29       "of the error in source code)",
  30        NULL },
  31     { "list", 'l', 0, G_OPTION_ARG_NONE, &options.do_list,
  32       "Show all known errors",
  33       NULL },
  34     { "exit", 'X', 0, G_OPTION_ARG_NONE, &options.as_exit_code,
  35       "Interpret as exit code rather than legacy function return value",
  36       NULL },
  37     { "rc", 'r', 0, G_OPTION_ARG_NONE, &options.as_rc,
  38       "Interpret as return code rather than legacy function return value",
  39       NULL },
  40 
  41     { NULL }
  42 };
  43 
  44 static void
  45 get_strings(int rc, const char **name, const char **str)
     /* [previous][next][first][last][top][bottom][index][help] */
  46 {
  47     if (options.as_exit_code) {
  48         *str = crm_exit_str((crm_exit_t) rc);
  49         *name = crm_exit_name(rc);
  50     } else if (options.as_rc) {
  51         *str = pcmk_rc_str(rc);
  52         *name = pcmk_rc_name(rc);
  53     } else {
  54         *str = pcmk_strerror(rc);
  55         *name = pcmk_errorname(rc);
  56     }
  57 }
  58 
  59 
  60 static GOptionContext *
  61 build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
     /* [previous][next][first][last][top][bottom][index][help] */
  62     GOptionContext *context = NULL;
  63 
  64     context = pcmk__build_arg_context(args, NULL, group, "-- <rc> [...]");
  65     pcmk__add_main_args(context, entries);
  66     return context;
  67 }
  68 
  69 int
  70 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72     crm_exit_t exit_code = CRM_EX_OK;
  73     int rc = pcmk_rc_ok;
  74     int lpc;
  75     const char *name = NULL;
  76     const char *desc = NULL;
  77 
  78     GError *error = NULL;
  79 
  80     GOptionGroup *output_group = NULL;
  81     pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
  82     gchar **processed_args = pcmk__cmdline_preproc(argv, NULL);
  83     GOptionContext *context = build_arg_context(args, &output_group);
  84 
  85     if (!g_option_context_parse_strv(context, &processed_args, &error)) {
  86         exit_code = CRM_EX_USAGE;
  87         goto done;
  88     }
  89 
  90     pcmk__cli_init_logging("crm_error", args->verbosity);
  91 
  92     if (args->version) {
  93         g_strfreev(processed_args);
  94         pcmk__free_arg_context(context);
  95         /* FIXME:  When crm_error is converted to use formatted output, this can go. */
  96         pcmk__cli_help('v', CRM_EX_OK);
  97     }
  98 
  99     if (options.do_list) {
 100         int start, end, width;
 101 
 102         // 256 is a hacky magic number that "should" be enough
 103         if (options.as_rc) {
 104             start = pcmk_rc_error - 256;
 105             end = PCMK_CUSTOM_OFFSET;
 106             width = 4;
 107         } else {
 108             start = 0;
 109             end = 256;
 110             width = 3;
 111         }
 112 
 113         for (rc = start; rc < end; rc++) {
 114             if (rc == (pcmk_rc_error + 1)) {
 115                 // Values in between are reserved for callers, no use iterating
 116                 rc = pcmk_rc_ok;
 117             }
 118             get_strings(rc, &name, &desc);
 119             if (pcmk__str_eq(name, "Unknown", pcmk__str_null_matches) || !strcmp(name, "CRM_EX_UNKNOWN")) {
 120                 // Undefined
 121             } else if(options.with_name) {
 122                 printf("% .*d: %-26s  %s\n", width, rc, name, desc);
 123             } else {
 124                 printf("% .*d: %s\n", width, rc, desc);
 125             }
 126         }
 127 
 128     } else {
 129         if (g_strv_length(processed_args) < 2) {
 130             char *help = g_option_context_get_help(context, TRUE, NULL);
 131             fprintf(stderr, "%s", help);
 132             g_free(help);
 133             exit_code = CRM_EX_USAGE;
 134             goto done;
 135         }
 136 
 137         /* Skip #1 because that's the program name. */
 138         for (lpc = 1; processed_args[lpc] != NULL; lpc++) {
 139             pcmk__scan_min_int(processed_args[lpc], &rc, INT_MIN);
 140             get_strings(rc, &name, &desc);
 141             if (options.with_name) {
 142                 printf("%s - %s\n", name, desc);
 143             } else {
 144                 printf("%s\n", desc);
 145             }
 146         }
 147     }
 148 
 149  done:
 150     g_strfreev(processed_args);
 151     pcmk__free_arg_context(context);
 152 
 153     pcmk__output_and_clear_error(error, NULL);
 154     return exit_code;
 155 }

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