19 #include <sys/types.h> 33 static char *crm_short_options = NULL;
35 static const char *crm_app_description = NULL;
36 static const char *crm_app_usage = NULL;
41 free(crm_short_options);
42 crm_short_options = NULL;
45 static struct option *
48 struct option *long_opts = NULL;
51 int index = 0, lpc = 0;
60 long_opts = pcmk__realloc(long_opts, (index + 1) *
sizeof(
struct option));
61 long_opts[index].name =
"__dummmy__";
62 long_opts[index].has_arg = 0;
63 long_opts[index].flag = 0;
64 long_opts[index].val =
'_';
69 for (lpc = 0; long_options[lpc].
name != NULL; lpc++) {
70 if (long_options[lpc].
name[0] ==
'-') {
74 long_opts = pcmk__realloc(long_opts, (index + 1) *
sizeof(
struct option));
77 long_opts[index].name = long_options[lpc].
name;
78 long_opts[index].has_arg = long_options[lpc].
has_arg;
79 long_opts[index].flag = long_options[lpc].
flag;
80 long_opts[index].val = long_options[lpc].
val;
85 long_opts = pcmk__realloc(long_opts, (index + 1) *
sizeof(
struct option));
86 long_opts[index].name = NULL;
87 long_opts[index].has_arg = 0;
88 long_opts[index].flag = 0;
89 long_opts[index].val = 0;
109 crm_short_options = strdup(short_options);
111 }
else if (long_options) {
113 int opt_string_len = 0;
114 char *local_short_options = NULL;
116 for (lpc = 0; long_options[lpc].
name != NULL; lpc++) {
117 if (long_options[lpc].val && long_options[lpc].val !=
'-' && long_options[lpc].val < UCHAR_MAX) {
118 local_short_options = pcmk__realloc(local_short_options,
120 local_short_options[opt_string_len++] = long_options[lpc].
val;
122 if (long_options[lpc].has_arg == optional_argument) {
123 local_short_options[opt_string_len++] =
':';
126 local_short_options[opt_string_len++] =
':';
128 local_short_options[opt_string_len] = 0;
131 crm_short_options = local_short_options;
132 crm_trace(
"Generated short option string: '%s'", local_short_options);
136 crm_long_options = long_options;
139 crm_app_description = app_desc;
142 crm_app_usage = app_usage;
150 static struct option *long_opts = NULL;
152 if (long_opts == NULL && crm_long_options) {
153 long_opts = create_long_opts(crm_long_options);
158 int flag = getopt_long(argc, argv, crm_short_options, long_opts, index);
162 if (long_opts[*index].val) {
163 return long_opts[*index].val;
164 }
else if (longname) {
165 *longname = long_opts[*index].name;
184 if (crm_short_options) {
185 return getopt(argc, argv, crm_short_options);
195 FILE *stream = (exit_code ? stderr : stdout);
197 if (cmd ==
'v' || cmd ==
'$') {
199 fprintf(stream,
"Written by Andrew Beekhof and " 200 "the Pacemaker project contributors\n");
215 if (crm_long_options) {
216 fprintf(stream,
"Options:\n");
217 for (i = 0; crm_long_options[i].
name != NULL; i++) {
221 fprintf(stream,
"%s\n\n", crm_long_options[i].desc);
224 fprintf(stream,
"\t#%s\n\n", crm_long_options[i].desc);
226 }
else if (crm_long_options[i].val ==
'-' && crm_long_options[i].desc) {
227 fprintf(stream,
"%s\n", crm_long_options[i].desc);
231 if (crm_long_options[i].val && crm_long_options[i].val <= UCHAR_MAX) {
232 fprintf(stream,
" -%c,", crm_long_options[i].val);
236 fprintf(stream,
" --%s%s\t%s\n", crm_long_options[i].
name,
237 crm_long_options[i].has_arg == optional_argument ?
"[=value]" :
239 crm_long_options[i].desc ? crm_long_options[i].desc :
"");
243 }
else if (crm_short_options) {
244 fprintf(stream,
"Usage: %s - %s\n",
crm_system_name, crm_app_description);
245 for (i = 0; crm_short_options[i] != 0; i++) {
248 if (crm_short_options[i + 1] ==
':') {
249 if (crm_short_options[i + 2] ==
':')
250 has_arg = optional_argument ;
255 fprintf(stream,
" -%c %s\n", crm_short_options[i],
256 has_arg == optional_argument ?
"[value]" :
289 const char *value = NULL;
291 snprintf(env_name,
NAME_MAX,
"PCMK_%s", option);
292 value = getenv(env_name);
294 crm_trace(
"Found %s = %s", env_name, value);
298 snprintf(env_name,
NAME_MAX,
"HA_%s", option);
299 value = getenv(env_name);
301 crm_trace(
"Found %s = %s", env_name, value);
305 crm_trace(
"Nothing found for %s", option);
323 snprintf(env_name,
NAME_MAX,
"PCMK_%s", option);
325 crm_trace(
"Setting %s to %s", env_name, value);
326 setenv(env_name, value, 1);
332 snprintf(env_name,
NAME_MAX,
"HA_%s", option);
334 crm_trace(
"Setting %s to %s", env_name, value);
335 setenv(env_name, value, 1);
421 if (stat(value, &
st) != 0) {
422 crm_err(
"Script %s does not exist", value);
426 if (S_ISREG(
st.st_mode) == 0) {
427 crm_err(
"Script %s is not a regular file", value);
431 if ((
st.st_mode & (S_IXUSR | S_IXGRP)) == 0) {
432 crm_err(
"Script %s is not executable", value);
443 long number = strtol(value, &end, 10);
445 if (end && (end[0] !=
'%')) {
464 cluster_option_value(GHashTable *options,
bool (*validate)(
const char *),
465 const char *
name,
const char *old_name,
466 const char *def_value)
468 const char *value = NULL;
469 char *new_value = NULL;
474 value = g_hash_table_lookup(options,
name);
476 if ((value == NULL) && old_name) {
477 value = g_hash_table_lookup(options, old_name);
480 "option '%s' is deprecated and will be " 481 "removed in a future release",
485 new_value = strdup(value);
486 g_hash_table_insert(options, strdup(
name), new_value);
491 if (value && validate && (validate(value) == FALSE)) {
493 "because '%s' is invalid",
name, value);
506 crm_trace(
"No value or default provided for cluster option '%s'",
513 crm_err(
"Bug: default value for cluster option '%s' is invalid",
name);
517 crm_trace(
"Using default value '%s' for cluster option '%s'",
520 new_value = strdup(value);
521 g_hash_table_insert(options, strdup(
name), new_value);
539 int len,
const char *
name)
541 const char *value = NULL;
543 for (
int lpc = 0; lpc < len; lpc++) {
545 value = cluster_option_value(options, option_list[lpc].is_valid,
546 option_list[lpc].
name,
547 option_list[lpc].alt_name,
548 option_list[lpc].default_value);
566 add_desc(GString *s,
const char *tag,
const char *desc,
const char *values,
const char *spaces)
570 g_string_append_printf(s,
"<%s lang=\"en\">%s",
572 if (values != NULL) {
573 g_string_append_printf(s,
" Allowed values: %s", values);
575 g_string_append_printf(s,
"</%s>\n", tag);
579 static const char *locale = NULL;
583 if (strcmp(escaped_en, localized) != 0) {
584 if (locale == NULL) {
585 locale = strtok(setlocale(LC_ALL, NULL),
"_");
588 if (spaces != NULL) {
589 g_string_append_printf(s,
"%s", spaces);
591 g_string_append_printf(s,
"<%s lang=\"%s\">%s",
592 tag, locale, localized);
593 if (values != NULL) {
594 g_string_append(s,
_(
" Allowed values: "));
595 g_string_append_printf(s,
"%s",
_(values));
597 g_string_append_printf(s,
"</%s>\n", tag);
608 const char *desc_long,
613 GString *s = g_string_sized_new(13000);
616 g_string_append_printf(s,
"<?xml version=\"1.0\"?>" 617 "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" 618 "<resource-agent name=\"%s\">\n" 619 " <version>%s</version>\n",
622 g_string_append(s,
" ");
623 add_desc(s,
"longdesc", desc_long, NULL,
" ");
625 g_string_append(s,
" ");
626 add_desc(s,
"shortdesc", desc_short, NULL,
" ");
628 g_string_append(s,
" <parameters>\n");
630 for (lpc = 0; lpc < len; lpc++) {
633 if (long_desc == NULL) {
635 if (long_desc == NULL) {
640 g_string_append_printf(s,
" <parameter name=\"%s\">\n",
641 option_list[lpc].
name);
643 g_string_append(s,
" ");
644 add_desc(s,
"longdesc", long_desc, option_list[lpc].values,
" ");
646 g_string_append(s,
" ");
647 add_desc(s,
"shortdesc", option_list[lpc].description_short, NULL,
" ");
649 if (option_list[lpc].values && !strcmp(option_list[lpc].
type,
"select")) {
650 char *str = strdup(option_list[lpc].values);
652 char *ptr = strtok(str, delim);
654 g_string_append_printf(s,
" <content type=\"%s\" default=\"%s\">\n",
655 option_list[lpc].
type,
656 option_list[lpc].default_value);
658 while (ptr != NULL) {
659 g_string_append_printf(s,
" <option value=\"%s\" />\n", ptr);
660 ptr = strtok(NULL, delim);
663 g_string_append_printf(s,
" </content>\n");
667 g_string_append_printf(s,
" <content type=\"%s\" default=\"%s\"/>\n",
668 option_list[lpc].
type,
669 option_list[lpc].default_value
673 g_string_append_printf(s,
" </parameter>\n");
675 g_string_append_printf(s,
" </parameters>\n</resource-agent>\n");
678 g_string_free(s, FALSE);
686 for (
int lpc = 0; lpc < len; lpc++) {
687 cluster_option_value(options, option_list[lpc].is_valid,
688 option_list[lpc].
name,
689 option_list[lpc].alt_name,
690 option_list[lpc].default_value);
#define CRM_CHECK(expr, failure_action)
#define crm_notice(fmt, args...)
void pcmk__set_env_option(const char *option, const char *value)
Set or unset a Pacemaker environment variable option.
_Noreturn crm_exit_t crm_exit(crm_exit_t rc)
void pcmk__cli_help(char cmd, crm_exit_t exit_code)
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
bool pcmk__valid_script(const char *value)
#define pcmk__config_warn(fmt...)
bool pcmk__valid_interval_spec(const char *value)
#define pcmk__config_err(fmt...)
bool pcmk__valid_positive_number(const char *value)
#define required_argument
enum crm_exit_e crm_exit_t
Command line usage error.
enum crm_ais_msg_types type
#define PACEMAKER_VERSION
bool pcmk__valid_percentage(const char *value)
void pcmk__set_cli_options(const char *short_options, const char *app_usage, pcmk__cli_option_t *long_options, const char *app_desc)
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
int daemon(int nochdir, int noclose)
bool pcmk__valid_quorum(const char *value)
#define crm_trace(fmt, args...)
int setenv(const char *name, const char *value, int why)
char * pcmk__format_option_metadata(const char *name, const char *desc_short, const char *desc_long, pcmk__cluster_option_t *option_list, int len)
bool pcmk_str_is_infinity(const char *s)
int crm_str_to_boolean(const char *s, int *ret)
#define crm_err(fmt, args...)
bool pcmk_str_is_minus_infinity(const char *s)
char guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
int pcmk__next_cli_option(int argc, char **argv, int *index, const char **longname)
const char * description_short
void pcmk__validate_cluster_options(GHashTable *options, pcmk__cluster_option_t *option_list, int len)
const char * pcmk__cluster_option(GHashTable *options, pcmk__cluster_option_t *option_list, int len, const char *name)
#define PACKAGE_BUGREPORT
bool pcmk__env_option_enabled(const char *daemon, const char *option)
gboolean crm_is_true(const char *s)
const char * pcmk__env_option(const char *option)
bool pcmk__valid_number(const char *value)
char * crm_xml_escape(const char *text)
Replace special characters with their XML escape sequences.
bool pcmk__valid_boolean(const char *value)
void pcmk__cli_option_cleanup()
const char * description_long