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

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