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\n");
214 if (crm_long_options) {
215 fprintf(stream,
"Options:\n");
216 for (i = 0; crm_long_options[i].
name != NULL; i++) {
220 fprintf(stream,
"%s\n\n", crm_long_options[i].desc);
223 fprintf(stream,
"\t#%s\n\n", crm_long_options[i].desc);
225 }
else if (crm_long_options[i].val ==
'-' && crm_long_options[i].desc) {
226 fprintf(stream,
"%s\n", crm_long_options[i].desc);
230 if (crm_long_options[i].val && crm_long_options[i].val <= UCHAR_MAX) {
231 fprintf(stream,
" -%c,", crm_long_options[i].val);
235 fprintf(stream,
" --%s%s\t%s\n", crm_long_options[i].
name,
236 crm_long_options[i].has_arg == optional_argument ?
"[=value]" :
238 crm_long_options[i].desc ? crm_long_options[i].desc :
"");
242 }
else if (crm_short_options) {
243 fprintf(stream,
"Usage: %s - %s\n",
crm_system_name, crm_app_description);
244 for (i = 0; crm_short_options[i] != 0; i++) {
247 if (crm_short_options[i + 1] ==
':') {
248 if (crm_short_options[i + 2] ==
':')
249 has_arg = optional_argument ;
254 fprintf(stream,
" -%c %s\n", crm_short_options[i],
255 has_arg == optional_argument ?
"[value]" :
288 const char *value = NULL;
290 snprintf(env_name,
NAME_MAX,
"PCMK_%s", option);
291 value = getenv(env_name);
293 crm_trace(
"Found %s = %s", env_name, value);
297 snprintf(env_name,
NAME_MAX,
"HA_%s", option);
298 value = getenv(env_name);
300 crm_trace(
"Found %s = %s", env_name, value);
304 crm_trace(
"Nothing found for %s", option);
322 snprintf(env_name,
NAME_MAX,
"PCMK_%s", option);
324 crm_trace(
"Setting %s to %s", env_name, value);
325 setenv(env_name, value, 1);
331 snprintf(env_name,
NAME_MAX,
"HA_%s", option);
333 crm_trace(
"Setting %s to %s", env_name, value);
334 setenv(env_name, value, 1);
420 if (stat(value, &
st) != 0) {
421 crm_err(
"Script %s does not exist", value);
425 if (S_ISREG(
st.st_mode) == 0) {
426 crm_err(
"Script %s is not a regular file", value);
430 if ((
st.st_mode & (S_IXUSR | S_IXGRP)) == 0) {
431 crm_err(
"Script %s is not executable", value);
442 long number = strtol(value, &end, 10);
444 if (end && (end[0] !=
'%')) {
463 cluster_option_value(GHashTable *options,
bool (*validate)(
const char *),
464 const char *
name,
const char *old_name,
465 const char *def_value)
467 const char *value = NULL;
468 char *new_value = NULL;
473 value = g_hash_table_lookup(options,
name);
475 if ((value == NULL) && old_name) {
476 value = g_hash_table_lookup(options, old_name);
479 "option '%s' is deprecated and will be "
480 "removed in a future release",
484 new_value = strdup(value);
485 g_hash_table_insert(options, strdup(
name), new_value);
490 if (value && validate && (validate(value) == FALSE)) {
492 "because '%s' is invalid",
name, value);
505 crm_trace(
"No value or default provided for cluster option '%s'",
512 crm_err(
"Bug: default value for cluster option '%s' is invalid",
name);
516 crm_trace(
"Using default value '%s' for cluster option '%s'",
519 new_value = strdup(value);
520 g_hash_table_insert(options, strdup(
name), new_value);
538 int len,
const char *
name)
540 const char *value = NULL;
542 for (
int lpc = 0; lpc < len; lpc++) {
544 value = cluster_option_value(options, option_list[lpc].is_valid,
545 option_list[lpc].
name,
546 option_list[lpc].alt_name,
547 option_list[lpc].default_value);
557 const char *desc_short,
const char *desc_long,
562 fprintf(stdout,
"<?xml version=\"1.0\"?>"
563 "<!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n"
564 "<resource-agent name=\"%s\">\n"
565 " <version>%s</version>\n"
566 " <longdesc lang=\"en\">%s</longdesc>\n"
567 " <shortdesc lang=\"en\">%s</shortdesc>\n"
568 " <parameters>\n",
name,
version, desc_long, desc_short);
570 for (lpc = 0; lpc < len; lpc++) {
571 if ((option_list[lpc].description_long == NULL)
572 && (option_list[lpc].description_short == NULL)) {
575 fprintf(stdout,
" <parameter name=\"%s\" unique=\"0\">\n"
576 " <shortdesc lang=\"en\">%s</shortdesc>\n"
577 " <content type=\"%s\" default=\"%s\"/>\n"
578 " <longdesc lang=\"en\">%s%s%s</longdesc>\n"
580 option_list[lpc].
name,
581 option_list[lpc].description_short,
582 option_list[lpc].
type,
583 option_list[lpc].default_value,
584 option_list[lpc].description_long?
585 option_list[lpc].description_long :
586 option_list[lpc].description_short,
587 (option_list[lpc].values?
" Allowed values: " :
""),
588 (option_list[lpc].values? option_list[lpc].values :
""));
590 fprintf(stdout,
" </parameters>\n</resource-agent>\n");
597 for (
int lpc = 0; lpc < len; lpc++) {
598 cluster_option_value(options, option_list[lpc].is_valid,
599 option_list[lpc].
name,
600 option_list[lpc].alt_name,
601 option_list[lpc].default_value);