]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/client/xml_writer.c
client: add show interfaces command (#240)
[thirdparty/lldpd.git] / src / client / xml_writer.c
1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3 * Copyright (c) 2010 Andreas Hofmeister <andi@collax.com>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #if defined(__clang__)
23 #pragma clang diagnostic push
24 #pragma clang diagnostic ignored "-Wdocumentation"
25 #endif
26 #include <libxml/encoding.h>
27 #include <libxml/xmlwriter.h>
28 #if defined(__clang__)
29 #pragma clang diagnostic pop
30 #endif
31
32 #include "writer.h"
33 #include "../log.h"
34
35 struct xml_writer_private {
36 FILE *fh;
37 ssize_t depth;
38 xmlTextWriterPtr xw;
39 xmlDocPtr doc;
40 };
41
42 void xml_new_writer(struct xml_writer_private *priv)
43 {
44 priv->xw = xmlNewTextWriterDoc(&(priv->doc), 0);
45 if (!priv->xw)
46 fatalx("lldpctl", "cannot create xml writer");
47
48 xmlTextWriterSetIndent(priv->xw, 4);
49
50 if (xmlTextWriterStartDocument(priv->xw, NULL, "UTF-8", NULL) < 0 )
51 fatalx("lldpctl", "cannot start xml document");
52 }
53
54 void xml_start(struct writer *w , const char *tag, const char *descr ) {
55 struct xml_writer_private *p = w->priv;
56
57 if (p->depth == 0)
58 xml_new_writer(p);
59
60 if (xmlTextWriterStartElement(p->xw, BAD_CAST tag) < 0)
61 log_warnx("lldpctl", "cannot start '%s' element", tag);
62
63 if (descr && (strlen(descr) > 0)) {
64 if (xmlTextWriterWriteFormatAttribute(p->xw, BAD_CAST "label", "%s", descr) < 0)
65 log_warnx("lldpctl", "cannot add attribute 'label' to element %s", tag);
66 }
67
68 p->depth++;
69 }
70
71 void xml_attr(struct writer *w, const char *tag, const char *descr, const char *value ) {
72 struct xml_writer_private *p = w->priv;
73
74 if (xmlTextWriterWriteFormatAttribute(p->xw, BAD_CAST tag, "%s", value?value:"") < 0)
75 log_warnx("lldpctl", "cannot add attribute %s with value %s", tag, value?value:"(none)");
76 }
77
78 void xml_data(struct writer *w, const char *data) {
79 struct xml_writer_private *p = w->priv;
80 if (xmlTextWriterWriteString(p->xw, BAD_CAST (data?data:"")) < 0 )
81 log_warnx("lldpctl", "cannot add '%s' as data to element", data?data:"(none)");
82 }
83
84 void xml_end(struct writer *w) {
85 struct xml_writer_private *p = w->priv;
86
87 if (xmlTextWriterEndElement(p->xw) < 0 )
88 log_warnx("lldpctl", "cannot end element");
89
90 if (--p->depth == 0) {
91 int failed = 0;
92
93 if (xmlTextWriterEndDocument(p->xw) < 0 ) {
94 log_warnx("lldpctl", "cannot finish document");
95 failed = 1;
96 }
97
98 xmlFreeTextWriter(p->xw);
99 if (!failed) {
100 xmlDocDump(p->fh, p->doc);
101 fflush(p->fh);
102 }
103 xmlFreeDoc(p->doc);
104 }
105 }
106
107 void xml_finish(struct writer *w) {
108 struct xml_writer_private *p = w->priv;
109 if (p->depth != 0) {
110 log_warnx("lldpctl", "unbalanced tags");
111 /* memory leak... */
112 }
113
114 free(p);
115 free(w);
116 }
117
118 struct writer *xml_init(FILE *fh) {
119
120 struct writer *result;
121 struct xml_writer_private *priv;
122
123 priv = malloc(sizeof(*priv));
124 if (!priv) {
125 fatalx("lldpctl", "out of memory");
126 return NULL;
127 }
128 priv->fh = fh;
129 priv->depth = 0;
130
131 result = malloc(sizeof(struct writer));
132 if (!result)
133 fatalx("lldpctl", "out of memory");
134
135 result->priv = priv;
136 result->start = xml_start;
137 result->attr = xml_attr;
138 result->data = xml_data;
139 result->end = xml_end;
140 result->finish= xml_finish;
141
142 return result;
143 }