This source file includes following definitions.
- result_type_cb
- build_arg_context
- main
1
2
3
4
5
6
7
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;
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,
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) {
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)
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
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
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
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 crm_exit(exit_code);
174 }