This source file includes following definitions.
- pcmk__xe_is
- pcmk__xml_first_child
- pcmk__xml_next
- pcmk__xe_first_child
- pcmk__xe_next
- pcmk__xe_set_props
- pcmk__xml_attr_value
1
2
3
4
5
6
7
8
9
10 #ifndef PCMK__XML_INTERNAL__H
11 # define PCMK__XML_INTERNAL__H
12
13
14
15
16
17 # include <stdlib.h>
18 # include <stdio.h>
19 # include <string.h>
20
21 # include <crm/crm.h>
22 # include <crm/common/output_internal.h>
23
24 # include <libxml/relaxng.h>
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 #define PCMK__XML_LOG_BASE(priority, dechunk, postemit, prefix, fmt, ap) \
70 do { \
71 if (!(dechunk) && (prefix) == NULL) { \
72 qb_log_from_external_source_va(__func__, __FILE__, (fmt), \
73 (priority), __LINE__, 0, (ap)); \
74 (void) (postemit); \
75 } else { \
76 int CXLB_len = 0; \
77 char *CXLB_buf = NULL; \
78 static int CXLB_buffer_len = 0; \
79 static char *CXLB_buffer = NULL; \
80 static uint8_t CXLB_priority = 0; \
81 \
82 CXLB_len = vasprintf(&CXLB_buf, (fmt), (ap)); \
83 \
84 if (CXLB_len <= 0 || CXLB_buf[CXLB_len - 1] == '\n' || !(dechunk)) { \
85 if (CXLB_len < 0) { \
86 CXLB_buf = (char *) "LOG CORRUPTION HAZARD"; \
87 CXLB_priority = QB_MIN(CXLB_priority, LOG_ERR); \
88 } else if (CXLB_len > 0 \
89 && CXLB_buf[CXLB_len - 1] == '\n') { \
90 CXLB_buf[CXLB_len - 1] = '\0'; \
91 } \
92 if (CXLB_buffer) { \
93 qb_log_from_external_source(__func__, __FILE__, "%s%s%s", \
94 CXLB_priority, __LINE__, 0, \
95 (prefix) != NULL ? (prefix) : "", \
96 CXLB_buffer, CXLB_buf); \
97 free(CXLB_buffer); \
98 } else { \
99 qb_log_from_external_source(__func__, __FILE__, "%s%s", \
100 (priority), __LINE__, 0, \
101 (prefix) != NULL ? (prefix) : "", \
102 CXLB_buf); \
103 } \
104 if (CXLB_len < 0) { \
105 CXLB_buf = NULL; \
106 } \
107 CXLB_buffer = NULL; \
108 CXLB_buffer_len = 0; \
109 (void) (postemit); \
110 \
111 } else if (CXLB_buffer == NULL) { \
112 CXLB_buffer_len = CXLB_len; \
113 CXLB_buffer = CXLB_buf; \
114 CXLB_buf = NULL; \
115 CXLB_priority = (priority); \
116 \
117 } else { \
118 CXLB_buffer = realloc(CXLB_buffer, 1 + CXLB_buffer_len + CXLB_len); \
119 memcpy(CXLB_buffer + CXLB_buffer_len, CXLB_buf, CXLB_len); \
120 CXLB_buffer_len += CXLB_len; \
121 CXLB_buffer[CXLB_buffer_len] = '\0'; \
122 CXLB_priority = QB_MIN(CXLB_priority, (priority)); \
123 } \
124 free(CXLB_buf); \
125 } \
126 } while (0)
127
128
129
130
131
132 enum pcmk__xml_fmt_options {
133
134 pcmk__xml_fmt_filtered = (1 << 0),
135
136
137 pcmk__xml_fmt_pretty = (1 << 1),
138
139
140 pcmk__xml_fmt_open = (1 << 3),
141
142
143 pcmk__xml_fmt_children = (1 << 4),
144
145
146 pcmk__xml_fmt_close = (1 << 5),
147
148
149 pcmk__xml_fmt_text = (1 << 6),
150
151
152
153 pcmk__xml_fmt_diff_plus = (1 << 7),
154
155
156
157 pcmk__xml_fmt_diff_minus = (1 << 8),
158
159
160
161 pcmk__xml_fmt_diff_short = (1 << 9),
162 };
163
164 int pcmk__xml_show(pcmk__output_t *out, const char *prefix, const xmlNode *data,
165 int depth, uint32_t options);
166 int pcmk__xml_show_changes(pcmk__output_t *out, const xmlNode *xml);
167
168
169
170
171 #define PCMK__XP_MEMBER_NODE_CONFIG \
172 "//" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_NODES \
173 "/" XML_CIB_TAG_NODE "[not(@type) or @type='member']"
174
175
176 #define PCMK__XP_GUEST_NODE_CONFIG \
177 "//" XML_TAG_CIB "//" XML_CIB_TAG_CONFIGURATION "//" XML_CIB_TAG_RESOURCE \
178 "//" XML_TAG_META_SETS "//" XML_CIB_TAG_NVPAIR \
179 "[@name='" XML_RSC_ATTR_REMOTE_NODE "']"
180
181
182 #define PCMK__XP_REMOTE_NODE_CONFIG \
183 "//" XML_TAG_CIB "//" XML_CIB_TAG_CONFIGURATION "//" XML_CIB_TAG_RESOURCE \
184 "[@type='remote'][@provider='pacemaker']"
185
186
187 #define PCMK__XP_REMOTE_NODE_STATUS \
188 "//" XML_TAG_CIB "//" XML_CIB_TAG_STATUS "//" XML_CIB_TAG_STATE \
189 "[@" XML_NODE_IS_REMOTE "='true']"
190
191
192
193
194
195
196
197
198
199 int pcmk__xml2fd(int fd, xmlNode *cur);
200
201 enum pcmk__xml_artefact_ns {
202 pcmk__xml_artefact_ns_legacy_rng = 1,
203 pcmk__xml_artefact_ns_legacy_xslt,
204 pcmk__xml_artefact_ns_base_rng,
205 pcmk__xml_artefact_ns_base_xslt,
206 };
207
208 void pcmk__strip_xml_text(xmlNode *xml);
209 const char *pcmk__xe_add_last_written(xmlNode *xe);
210
211 xmlNode *pcmk__xe_match(const xmlNode *parent, const char *node_name,
212 const char *attr_n, const char *attr_v);
213
214 void pcmk__xe_remove_matching_attrs(xmlNode *element,
215 bool (*match)(xmlAttrPtr, void *),
216 void *user_data);
217
218 GString *pcmk__element_xpath(const xmlNode *xml);
219
220
221
222
223
224
225
226
227
228 char *
229 pcmk__xml_artefact_root(enum pcmk__xml_artefact_ns ns);
230
231
232
233
234
235
236
237
238
239
240 char *pcmk__xml_artefact_path(enum pcmk__xml_artefact_ns ns,
241 const char *filespec);
242
243
244
245
246
247
248
249
250
251
252 static inline bool
253 pcmk__xe_is(const xmlNode *xml, const char *name)
254 {
255 return (xml != NULL) && (xml->name != NULL) && (name != NULL)
256 && (strcmp((const char *) xml->name, name) == 0);
257 }
258
259
260
261
262
263
264
265
266
267 static inline xmlNode *
268 pcmk__xml_first_child(const xmlNode *parent)
269 {
270 xmlNode *child = (parent? parent->children : NULL);
271
272 while (child && (child->type == XML_TEXT_NODE)) {
273 child = child->next;
274 }
275 return child;
276 }
277
278
279
280
281
282
283
284
285
286 static inline xmlNode *
287 pcmk__xml_next(const xmlNode *child)
288 {
289 xmlNode *next = (child? child->next : NULL);
290
291 while (next && (next->type == XML_TEXT_NODE)) {
292 next = next->next;
293 }
294 return next;
295 }
296
297
298
299
300
301
302
303
304
305 static inline xmlNode *
306 pcmk__xe_first_child(const xmlNode *parent)
307 {
308 xmlNode *child = (parent? parent->children : NULL);
309
310 while (child && (child->type != XML_ELEMENT_NODE)) {
311 child = child->next;
312 }
313 return child;
314 }
315
316
317
318
319
320
321
322
323
324 static inline xmlNode *
325 pcmk__xe_next(const xmlNode *child)
326 {
327 xmlNode *next = child? child->next : NULL;
328
329 while (next && (next->type != XML_ELEMENT_NODE)) {
330 next = next->next;
331 }
332 return next;
333 }
334
335
336
337
338
339
340
341
342
343 void
344 pcmk__xe_set_propv(xmlNodePtr node, va_list pairs);
345
346
347
348
349
350
351
352
353
354
355
356 void
357 pcmk__xe_set_props(xmlNodePtr node, ...)
358 G_GNUC_NULL_TERMINATED;
359
360
361
362
363
364
365
366
367
368 static inline xmlAttr *
369 pcmk__xe_first_attr(const xmlNode *xe)
370 {
371 return (xe == NULL)? NULL : xe->properties;
372 }
373
374
375
376
377
378
379
380
381
382
383 char *
384 pcmk__xpath_node_id(const char *xpath, const char *node);
385
386
387
388 enum xml_private_flags {
389 pcmk__xf_none = 0x0000,
390 pcmk__xf_dirty = 0x0001,
391 pcmk__xf_deleted = 0x0002,
392 pcmk__xf_created = 0x0004,
393 pcmk__xf_modified = 0x0008,
394
395 pcmk__xf_tracking = 0x0010,
396 pcmk__xf_processed = 0x0020,
397 pcmk__xf_skip = 0x0040,
398 pcmk__xf_moved = 0x0080,
399
400 pcmk__xf_acl_enabled = 0x0100,
401 pcmk__xf_acl_read = 0x0200,
402 pcmk__xf_acl_write = 0x0400,
403 pcmk__xf_acl_deny = 0x0800,
404
405 pcmk__xf_acl_create = 0x1000,
406 pcmk__xf_acl_denied = 0x2000,
407 pcmk__xf_lazy = 0x4000,
408 };
409
410 void pcmk__set_xml_doc_flag(xmlNode *xml, enum xml_private_flags flag);
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432 int
433 pcmk__xe_foreach_child(xmlNode *xml, const char *child_element_name,
434 int (*handler)(xmlNode *xml, void *userdata),
435 void *userdata);
436
437 static inline const char *
438 pcmk__xml_attr_value(const xmlAttr *attr)
439 {
440 return ((attr == NULL) || (attr->children == NULL))? NULL
441 : (const char *) attr->children->content;
442 }
443
444 gboolean pcmk__validate_xml(xmlNode *xml_blob, const char *validation,
445 xmlRelaxNGValidityErrorFunc error_handler,
446 void *error_handler_context);
447
448 #endif