pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
output.c
Go to the documentation of this file.
1 /*
2  * Copyright 2019-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 Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <libxml/tree.h>
11 
12 #include <crm/common/util.h>
13 #include <crm/common/xml.h>
14 #include <crm/common/internal.h>
17 #include <libxml/tree.h>
18 
19 static GHashTable *formatters = NULL;
20 
21 void
23  out->free_priv(out);
24 
25  if (out->messages != NULL) {
26  g_hash_table_destroy(out->messages);
27  }
28 
29  g_free(out->request);
30  free(out);
31 }
32 
33 int
34 pcmk__output_new(pcmk__output_t **out, const char *fmt_name, const char *filename,
35  char **argv) {
36  pcmk__output_factory_t create = NULL;;
37 
38  if (formatters == NULL) {
39  return EINVAL;
40  }
41 
42  /* If no name was given, just try "text". It's up to each tool to register
43  * what it supports so this also may not be valid.
44  */
45  if (fmt_name == NULL) {
46  create = g_hash_table_lookup(formatters, "text");
47  } else {
48  create = g_hash_table_lookup(formatters, fmt_name);
49  }
50 
51  if (create == NULL) {
53  }
54 
55  *out = create(argv);
56  if (*out == NULL) {
57  return ENOMEM;
58  }
59 
60  if (pcmk__str_eq(filename, "-", pcmk__str_null_matches)) {
61  (*out)->dest = stdout;
62  } else {
63  (*out)->dest = fopen(filename, "w");
64  if ((*out)->dest == NULL) {
65  return errno;
66  }
67  }
68 
69  (*out)->quiet = false;
70 
71  (*out)->messages = g_hash_table_new_full(crm_str_hash, g_str_equal, free, NULL);
72 
73  if ((*out)->init(*out) == false) {
74  pcmk__output_free(*out);
75  return ENOMEM;
76  }
77 
78  return pcmk_rc_ok;
79 }
80 
81 int
82 pcmk__register_format(GOptionGroup *group, const char *name,
83  pcmk__output_factory_t create, GOptionEntry *options) {
84  if (create == NULL) {
85  return -EINVAL;
86  }
87 
88  if (formatters == NULL) {
89  formatters = g_hash_table_new_full(crm_str_hash, g_str_equal, free, NULL);
90  }
91 
92  if (options != NULL && group != NULL) {
93  g_option_group_add_entries(group, options);
94  }
95 
96  g_hash_table_insert(formatters, strdup(name), create);
97  return 0;
98 }
99 
100 void
101 pcmk__register_formats(GOptionGroup *group, pcmk__supported_format_t *formats) {
102  pcmk__supported_format_t *entry = NULL;
103 
104  if (formats == NULL) {
105  return;
106  }
107 
108  for (entry = formats; entry->name != NULL; entry++) {
109  pcmk__register_format(group, entry->name, entry->create, entry->options);
110  }
111 }
112 
113 void
115  if (formatters != NULL) {
116  g_hash_table_destroy(formatters);
117  }
118 }
119 
120 int
121 pcmk__call_message(pcmk__output_t *out, const char *message_id, ...) {
122  va_list args;
123  int rc = pcmk_rc_ok;
125 
126  fn = g_hash_table_lookup(out->messages, message_id);
127  if (fn == NULL) {
128  return EINVAL;
129  }
130 
131  va_start(args, message_id);
132  rc = fn(out, args);
133  va_end(args);
134 
135  return rc;
136 }
137 
138 void
139 pcmk__register_message(pcmk__output_t *out, const char *message_id,
140  pcmk__message_fn_t fn) {
141  g_hash_table_replace(out->messages, strdup(message_id), fn);
142 }
143 
144 void
146  pcmk__message_entry_t *entry;
147 
148  for (entry = table; entry->message_id != NULL; entry++) {
149  if (pcmk__strcase_any_of(entry->fmt_name, "default", out->fmt_name, NULL)) {
150  pcmk__register_message(out, entry->message_id, entry->fn);
151  }
152  }
153 }
int(* pcmk__message_fn_t)(pcmk__output_t *out, va_list args)
void pcmk__register_formats(GOptionGroup *group, pcmk__supported_format_t *formats)
Definition: output.c:101
pcmk__message_fn_t fn
The function to be called for message_id given a match on fmt_name. See comments on pcmk__message_fn_...
bool pcmk__strcase_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
Definition: strings.c:842
const char * fmt_name
The name of this output formatter.
GHashTable * messages
Custom messages that are currently registered on this formatter.
Formatted output for pacemaker tools.
void pcmk__register_messages(pcmk__output_t *out, pcmk__message_entry_t *table)
Definition: output.c:145
int rc
Definition: pcmk_fence.c:35
GOptionEntry * options
Format-specific command line options. This can be NULL if no command line options should be supported...
Utility functions.
const char * fmt_name
The format type this handler is for.
void(* free_priv)(pcmk__output_t *out)
Wrappers for and extensions to libxml2.
int pcmk__output_new(pcmk__output_t **out, const char *fmt_name, const char *filename, char **argv)
Definition: output.c:34
pcmk__output_factory_t create
A function that creates a pcmk__output_t.
int pcmk__call_message(pcmk__output_t *out, const char *message_id,...)
Definition: output.c:121
void pcmk__unregister_formats()
Definition: output.c:114
pcmk__output_t *(* pcmk__output_factory_t)(char **argv)
void pcmk__register_message(pcmk__output_t *out, const char *message_id, pcmk__message_fn_t fn)
Definition: output.c:139
void pcmk__output_free(pcmk__output_t *out)
Definition: output.c:22
const char * name
The name of this output formatter, which should match the fmt_name parameter in some pcmk__output_t s...
gchar * request
A copy of the request that generated this output.
This structure contains everything that makes up a single output formatter.
int pcmk__register_format(GOptionGroup *group, const char *name, pcmk__output_factory_t create, GOptionEntry *options)
Definition: output.c:82
#define crm_str_hash
Definition: util.h:62
char * name
Definition: pcmk_fence.c:31
const char * message_id
The message to be handled.