pacemaker  2.0.3-4b1f869f0f
Scalable High-Availability cluster resource manager
output.c
Go to the documentation of this file.
1 /*
2  * Copyright 2019 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  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 0;
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, NULL, 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 int
109 pcmk__call_message(pcmk__output_t *out, const char *message_id, ...) {
110  va_list args;
111  int rc = 0;
113 
114  fn = g_hash_table_lookup(out->messages, message_id);
115  if (fn == NULL) {
116  return -EINVAL;
117  }
118 
119  va_start(args, message_id);
120  rc = fn(out, args);
121  va_end(args);
122 
123  return rc;
124 }
125 
126 void
127 pcmk__register_message(pcmk__output_t *out, const char *message_id,
128  pcmk__message_fn_t fn) {
129  g_hash_table_replace(out->messages, strdup(message_id), fn);
130 }
131 
132 void
134  pcmk__message_entry_t *entry;
135 
136  for (entry = table; entry->message_id != NULL; entry++) {
137  if (safe_str_eq(out->fmt_name, entry->fmt_name)) {
138  pcmk__register_message(out, entry->message_id, entry->fn);
139  }
140  }
141 }
pcmk__output_s::free_priv
void(* free_priv)(pcmk__output_t *out)
Definition: output.h:223
pcmk__output_s::messages
GHashTable * messages
Custom messages that are currently registered on this formatter.
Definition: output.h:187
pcmk__message_entry_s::fmt_name
const char * fmt_name
The format type this handler is for.
Definition: output.h:90
pcmk__output_s::request
char * request
A copy of the request that generated this output.
Definition: output.h:162
pcmk__register_format
int pcmk__register_format(GOptionGroup *group, const char *name, pcmk__output_factory_t create, GOptionEntry *options)
Definition: output.c:77
crm_str_hash
#define crm_str_hash
Definition: util.h:62
safe_str_eq
#define safe_str_eq(a, b)
Definition: util.h:61
xml.h
Wrappers for and extensions to libxml2.
pcmk__output_free
void pcmk__output_free(pcmk__output_t *out)
Definition: output.c:19
pcmk__register_messages
void pcmk__register_messages(pcmk__output_t *out, pcmk__message_entry_t *table)
Definition: output.c:133
pcmk__message_fn_t
int(* pcmk__message_fn_t)(pcmk__output_t *out, va_list args)
Definition: output.h:60
pcmk_err_unknown_format
#define pcmk_err_unknown_format
Definition: results.h:81
pcmk__call_message
int pcmk__call_message(pcmk__output_t *out, const char *message_id,...)
Definition: output.c:109
pcmk__output_factory_t
pcmk__output_t *(* pcmk__output_factory_t)(char **argv)
Definition: output.h:44
pcmk__output_s
This structure contains everything that makes up a single output formatter.
Definition: output.h:150
pcmk__output_new
int pcmk__output_new(pcmk__output_t **out, const char *fmt_name, const char *filename, char **argv)
Definition: output.c:31
pcmk__supported_format_s::options
GOptionEntry * options
Format-specific command line options. This can be NULL if no command line options should be supported...
Definition: output.h:120
pcmk__message_entry_s
Definition: output.h:73
pcmk__output_s::fmt_name
const char * fmt_name
The name of this output formatter.
Definition: output.h:154
pcmk__message_entry_s::fn
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
pcmk__supported_format_s::create
pcmk__output_factory_t create
A function that creates a pcmk__output_t.
Definition: output.h:114
pcmk__supported_format_s
Definition: output.h:104
internal.h
pcmk__supported_format_s::name
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
pcmk__message_entry_s::message_id
const char * message_id
The message to be handled.
Definition: output.h:80
pcmk__register_message
void pcmk__register_message(pcmk__output_t *out, const char *message_id, pcmk__message_fn_t fn)
Definition: output.c:127
util.h
Utility functions.
pcmk__register_formats
void pcmk__register_formats(GOptionGroup *group, pcmk__supported_format_t *formats)
Definition: output.c:96
output.h
Formatted output for pacemaker tools.