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;
107 const char *app_desc)
110 crm_short_options = strdup(short_options);
112 }
else if (long_options) {
114 int opt_string_len = 0;
115 char *local_short_options = NULL;
117 for (lpc = 0; long_options[lpc].
name != NULL; lpc++) {
118 if (long_options[lpc].val && long_options[lpc].val !=
'-' && long_options[lpc].val < UCHAR_MAX) {
119 local_short_options = pcmk__realloc(local_short_options,
121 local_short_options[opt_string_len++] = long_options[lpc].
val;
123 if (long_options[lpc].has_arg == optional_argument) {
124 local_short_options[opt_string_len++] =
':';
127 local_short_options[opt_string_len++] =
':';
129 local_short_options[opt_string_len] = 0;
132 crm_short_options = local_short_options;
133 crm_trace(
"Generated short option string: '%s'", local_short_options);
137 crm_long_options = long_options;
140 crm_app_description = app_desc;
143 crm_app_usage = app_usage;
151 static struct option *long_opts = NULL;
153 if (long_opts == NULL && crm_long_options) {
154 long_opts = create_long_opts(crm_long_options);
159 int flag = getopt_long(argc, argv, crm_short_options, long_opts, index);
163 if (long_opts[*index].val) {
164 return long_opts[*index].val;
165 }
else if (longname) {
166 *longname = long_opts[*index].name;
187 if (crm_short_options) {
188 return getopt(argc, argv, crm_short_options);
198 FILE *stream = (exit_code ? stderr : stdout);
200 if (cmd ==
'v' || cmd ==
'$') {
202 fprintf(stream,
"Written by Andrew Beekhof and " 203 "the Pacemaker project contributors\n");
218 if (crm_long_options) {
219 fprintf(stream,
"Options:\n");
220 for (i = 0; crm_long_options[i].
name != NULL; i++) {
224 fprintf(stream,
"%s\n\n", crm_long_options[i].desc);
227 fprintf(stream,
"\t#%s\n\n", crm_long_options[i].desc);
229 }
else if (crm_long_options[i].val ==
'-' && crm_long_options[i].desc) {
230 fprintf(stream,
"%s\n", crm_long_options[i].desc);
234 if (crm_long_options[i].val && crm_long_options[i].val <= UCHAR_MAX) {
235 fprintf(stream,
" -%c,", crm_long_options[i].val);
239 fprintf(stream,
" --%s%s\t%s\n", crm_long_options[i].
name,
240 crm_long_options[i].has_arg == optional_argument ?
"[=value]" :
242 crm_long_options[i].desc ? crm_long_options[i].desc :
"");
246 }
else if (crm_short_options) {
247 fprintf(stream,
"Usage: %s - %s\n",
crm_system_name, crm_app_description);
248 for (i = 0; crm_short_options[i] != 0; i++) {
251 if (crm_short_options[i + 1] ==
':') {
252 if (crm_short_options[i + 2] ==
':')
253 has_arg = optional_argument ;
258 fprintf(stream,
" -%c %s\n", crm_short_options[i],
259 has_arg == optional_argument ?
"[value]" :
292 const char *
const prefixes[] = {
"PCMK_",
"HA_"};
294 const char *value = NULL;
296 CRM_CHECK(!pcmk__str_empty(option),
return NULL);
299 int rv = snprintf(env_name,
NAME_MAX,
"%s%s", prefixes[i], option);
302 crm_err(
"Failed to write %s%s to buffer: %s", prefixes[i], option,
307 if (rv >=
sizeof(env_name)) {
308 crm_trace(
"\"%s%s\" is too long", prefixes[i], option);
312 value = getenv(env_name);
314 crm_trace(
"Found %s = %s", env_name, value);
319 crm_trace(
"Nothing found for %s", option);
335 const char *
const prefixes[] = {
"PCMK_",
"HA_"};
338 CRM_CHECK(!pcmk__str_empty(option) && (strchr(option,
'=') == NULL),
342 int rv = snprintf(env_name,
NAME_MAX,
"%s%s", prefixes[i], option);
345 crm_err(
"Failed to write %s%s to buffer: %s", prefixes[i], option,
350 if (rv >=
sizeof(env_name)) {
351 crm_trace(
"\"%s%s\" is too long", prefixes[i], option);
356 crm_trace(
"Setting %s to %s", env_name, value);
357 rv =
setenv(env_name, value, 1);
360 rv = unsetenv(env_name);
364 crm_err(
"Failed to %sset %s: %s", (value != NULL)?
"" :
"un",
388 return (value != NULL)
390 || ((
daemon != NULL) && (strstr(value,
daemon) != NULL)));
451 if (stat(value, &
st) != 0) {
452 crm_err(
"Script %s does not exist", value);
456 if (S_ISREG(
st.st_mode) == 0) {
457 crm_err(
"Script %s is not a regular file", value);
461 if ((
st.st_mode & (S_IXUSR | S_IXGRP)) == 0) {
462 crm_err(
"Script %s is not executable", value);
473 long number = strtol(value, &end, 10);
475 if (end && (end[0] !=
'%')) {
494 cluster_option_value(GHashTable *options,
bool (*validate)(
const char *),
495 const char *
name,
const char *old_name,
496 const char *def_value)
498 const char *value = NULL;
499 char *new_value = NULL;
504 value = g_hash_table_lookup(options,
name);
506 if ((value == NULL) && old_name) {
507 value = g_hash_table_lookup(options, old_name);
510 "option '%s' is deprecated and will be " 511 "removed in a future release",
515 new_value = strdup(value);
516 g_hash_table_insert(options, strdup(
name), new_value);
521 if (value && validate && (validate(value) == FALSE)) {
523 "because '%s' is invalid",
name, value);
536 crm_trace(
"No value or default provided for cluster option '%s'",
543 crm_err(
"Bug: default value for cluster option '%s' is invalid",
name);
547 crm_trace(
"Using default value '%s' for cluster option '%s'",
550 new_value = strdup(value);
551 g_hash_table_insert(options, strdup(
name), new_value);
570 int len,
const char *
name)
572 const char *value = NULL;
574 for (
int lpc = 0; lpc < len; lpc++) {
576 value = cluster_option_value(options, option_list[lpc].is_valid,
577 option_list[lpc].
name,
578 option_list[lpc].alt_name,
579 option_list[lpc].default_value);
599 add_desc(GString *s,
const char *tag,
const char *desc,
const char *values,
604 if (spaces != NULL) {
605 g_string_append(s, spaces);
609 if (values != NULL) {
616 static const char *locale = NULL;
620 if (strcmp(escaped_en, localized) != 0) {
621 if (locale == NULL) {
622 locale = strtok(setlocale(LC_ALL, NULL),
"_");
625 if (spaces != NULL) {
626 g_string_append(s, spaces);
631 if (values != NULL) {
645 const char *desc_long,
649 GString *s = g_string_sized_new(13000);
652 "<?xml version=\"1.0\"?>\n" 653 "<resource-agent name=\"",
name,
"\" " 657 add_desc(s,
"longdesc", desc_long, NULL,
" ");
658 add_desc(s,
"shortdesc", desc_short, NULL,
" ");
660 g_string_append(s,
" <parameters>\n");
662 for (
int lpc = 0; lpc < len; lpc++) {
663 const char *opt_name = option_list[lpc].
name;
664 const char *opt_type = option_list[lpc].
type;
665 const char *opt_values = option_list[lpc].
values;
671 CRM_ASSERT((opt_desc_short != NULL) || (opt_desc_long != NULL));
673 if (opt_desc_short == NULL) {
674 opt_desc_short = opt_desc_long;
675 }
else if (opt_desc_long == NULL) {
676 opt_desc_long = opt_desc_short;
682 pcmk__g_strcat(s,
" <parameter name=\"", opt_name,
"\">\n", NULL);
684 add_desc(s,
"longdesc", opt_desc_long, opt_values,
" ");
685 add_desc(s,
"shortdesc", opt_desc_short, NULL,
" ");
688 if (opt_default != NULL) {
692 if ((opt_values != NULL) && (strcmp(opt_type,
"select") == 0)) {
693 char *str = strdup(opt_values);
694 const char *delim =
", ";
695 char *ptr = strtok(str, delim);
697 g_string_append(s,
">\n");
699 while (ptr != NULL) {
702 ptr = strtok(NULL, delim);
704 g_string_append_printf(s,
" </content>\n");
708 g_string_append(s,
"/>\n");
711 g_string_append(s,
" </parameter>\n");
713 g_string_append(s,
" </parameters>\n</resource-agent>\n");
715 return g_string_free(s, FALSE);
722 for (
int lpc = 0; lpc < len; lpc++) {
723 cluster_option_value(options, option_list[lpc].is_valid,
724 option_list[lpc].
name,
725 option_list[lpc].alt_name,
726 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.
const char * default_value
char * strerror(int errnum)
#define PACEMAKER_VERSION
bool pcmk__valid_percentage(const char *value)
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
int daemon(int nochdir, int noclose)
const char * pcmk__cluster_option(GHashTable *options, const pcmk__cluster_option_t *option_list, int len, const char *name)
bool pcmk__valid_quorum(const char *value)
#define crm_trace(fmt, args...)
int setenv(const char *name, const char *value, int why)
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
bool pcmk_str_is_infinity(const char *s)
void pcmk__set_cli_options(const char *short_options, const char *app_usage, const pcmk__cli_option_t *long_options, const char *app_desc)
int crm_str_to_boolean(const char *s, int *ret)
void pcmk__cli_option_cleanup(void)
#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)
#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)
gchar * pcmk__format_option_metadata(const char *name, const char *desc_short, const char *desc_long, pcmk__cluster_option_t *option_list, int len)
const char * description_long