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