From: Andreas Hofmeister Date: Sun, 28 Feb 2010 14:32:01 +0000 (+0100) Subject: Implement an XML writer. X-Git-Tag: 0.5.0~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1480ce745f2383a6d59cdf62117707396f05d95a;p=thirdparty%2Flldpd.git Implement an XML writer. XML output can be enabled with the "--with-xml" configure option. libxml2 is used to create the actual XML output. --- diff --git a/configure.ac b/configure.ac index 700340e8..ae684b3f 100644 --- a/configure.ac +++ b/configure.ac @@ -204,6 +204,15 @@ if test x"$with_snmp" = x"yes"; then lldp_CHECK_SNMP fi +AC_ARG_WITH([xml], + AC_HELP_STRING( + [--with-xml], + [Enable XML output via libxml2 @<:@default=no:>@] + )) +if test x"$with_xml" = x"yes"; then + lldp_CHECK_XML2 +fi + # Privsep settings lldp_ARG_WITH([privsep-user], [Which user to use for privilege separation], [_lldpd]) lldp_ARG_WITH([privsep-group], [Which group to use for privilege separation], [_lldpd]) @@ -227,6 +236,7 @@ lldp_ARG_ENABLE([listenvlan], [listen on any VLAN], [no]) # Output results AM_CONDITIONAL([HAVE_CHECK], [test x"$have_check" = x"yes"]) AM_CONDITIONAL([USE_SNMP], [test x"$with_snmp" = x"yes"]) +AM_CONDITIONAL([USE_XML], [test x"$with_xml" = x"yes"]) AC_OUTPUT cat <p_med_location[i].data, - port->p_med_location[i].data_len, 20, ' ')); + tag_attr(w, "type", "", "unknown"); + tag_data(w, dump(port->p_med_location[i].data, + port->p_med_location[i].data_len, 20, ' ')); } tag_end(w); } @@ -922,7 +922,7 @@ display_age(struct lldpd_port *port) } void -display_interfaces(int s, int argc, char *argv[]) +display_interfaces(int s, const char * fmt, int argc, char *argv[]) { struct writer * w; int i, nb; @@ -935,7 +935,17 @@ display_interfaces(int s, int argc, char *argv[]) struct lldpd_port port; char sep[80]; - w = txt_init( stdout ); + if ( strcmp(fmt,"plain") == 0 ) { + w = txt_init( stdout ); + } +#ifdef USE_XML + else if ( strcmp(fmt,"xml") == 0 ) { + w = xml_init( stdout ); + } +#endif + else { + w = txt_init( stdout ); + } memset(sep, '-', 79); sep[79] = 0; diff --git a/src/lldpctl.c b/src/lldpctl.c index 38b32ce3..7480e81f 100644 --- a/src/lldpctl.c +++ b/src/lldpctl.c @@ -39,7 +39,7 @@ extern void get_interfaces(int s, struct interfaces *ifs); extern void -display_interfaces(int s, int argc, char *argv[]); +display_interfaces(int s, const char * fmt, int argc, char *argv[]); static void usage(void) @@ -294,17 +294,21 @@ int main(int argc, char *argv[]) { int ch, s, debug = 1; + char * fmt = "plain"; #define ACTION_SET_LOCATION 1 int action = 0; /* * Get and parse command line options */ - while ((ch = getopt(argc, argv, "dL:")) != -1) { + while ((ch = getopt(argc, argv, "df:L:")) != -1) { switch (ch) { case 'd': debug++; break; + case 'f': + fmt = optarg; + break; case 'L': #ifdef ENABLE_LLDPMED action = ACTION_SET_LOCATION; @@ -334,7 +338,7 @@ main(int argc, char *argv[]) break; #endif default: - display_interfaces(s, argc, argv); + display_interfaces(s, fmt, argc, argv); } close(s); diff --git a/src/writer.h b/src/writer.h index 4af13797..4b4b8912 100644 --- a/src/writer.h +++ b/src/writer.h @@ -36,4 +36,8 @@ struct writer { extern struct writer * txt_init( FILE * ); +#ifdef USE_XML +extern struct writer * xml_init( FILE * ); +#endif + #endif /* _WRITER_H */ diff --git a/src/xml_writer.c b/src/xml_writer.c new file mode 100644 index 00000000..e7d2eed6 --- /dev/null +++ b/src/xml_writer.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2010 Andreas Hofmeister + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include + +#include "writer.h" +#include "lldpd.h" + +struct xml_writer_private { + xmlTextWriterPtr xw; + xmlDocPtr doc; +}; + +void xml_start(struct writer * w , const char * tag, const char * descr ) { + struct xml_writer_private * p = w->priv; + + if (xmlTextWriterStartElement(p->xw, BAD_CAST tag) < 0) + LLOG_WARN("cannot start '%s' element\n", tag); +} + +void xml_attr(struct writer * w, const char * tag, const char * descr, const char * value ) { + struct xml_writer_private * p = w->priv; + + if (xmlTextWriterWriteFormatAttribute(p->xw, BAD_CAST tag, "%s", value) < 0) + LLOG_WARN("cannot add attribute %s with value %s\n", tag, value); +} + +void xml_data(struct writer * w, const char * data) { + struct xml_writer_private * p = w->priv; + + if (xmlTextWriterWriteString(p->xw, BAD_CAST data) < 0 ) + LLOG_WARN("cannot add '%s' as data to element\n", data); +} + +void xml_end(struct writer * w) { + struct xml_writer_private * p = w->priv; + + if (xmlTextWriterEndElement(p->xw) < 0 ) + LLOG_WARN("cannot end element\n"); +} + +#define MY_ENCODING "UTF-8" + +void xml_finish(struct writer * w) { + struct xml_writer_private * p = w->priv; + int failed = 0; + + if (xmlTextWriterEndDocument(p->xw) < 0 ) { + LLOG_WARN("cannot finish document\n"); + failed = 1; + } + + xmlFreeTextWriter(p->xw); + + if ( ! failed ) + xmlSaveFileEnc("-", p->doc, MY_ENCODING); + + xmlFreeDoc(p->doc); + + free( w->priv ); + free( w ); +} + +struct writer * xml_init(FILE * fh) { + + struct writer * result; + struct xml_writer_private * priv; + + priv = malloc( sizeof( *priv ) ); + if ( ! priv ) { + fatalx("out of memory\n"); + return NULL; + } + + priv->xw = xmlNewTextWriterDoc(&(priv->doc), 0); + if ( ! priv->xw ) { + fatalx("cannot create xml writer\n"); + return NULL; + } + + xmlTextWriterSetIndent(priv->xw, 4); + + if (xmlTextWriterStartDocument(priv->xw, NULL, MY_ENCODING, NULL) < 0 ) { + fatalx("cannot start xml document\n"); + return NULL; + } + + result = malloc( sizeof( struct writer ) ); + if ( ! result ) { + fatalx("out of memory\n"); + return NULL; + } + + result->priv = priv; + result->start = xml_start; + result->attr = xml_attr; + result->data = xml_data; + result->end = xml_end; + result->finish= xml_finish; + + return result; +} +