|
Packit |
e9ba0d |
/* -*- mode: c; c-file-style: "openbsd" -*- */
|
|
Packit |
e9ba0d |
/*
|
|
Packit |
e9ba0d |
* Copyright (c) 2010 Andreas Hofmeister <andi@collax.com>
|
|
Packit |
e9ba0d |
*
|
|
Packit |
e9ba0d |
* Permission to use, copy, modify, and/or distribute this software for any
|
|
Packit |
e9ba0d |
* purpose with or without fee is hereby granted, provided that the above
|
|
Packit |
e9ba0d |
* copyright notice and this permission notice appear in all copies.
|
|
Packit |
e9ba0d |
*
|
|
Packit |
e9ba0d |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
Packit |
e9ba0d |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
Packit |
e9ba0d |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
Packit |
e9ba0d |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
Packit |
e9ba0d |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
Packit |
e9ba0d |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
Packit |
e9ba0d |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
Packit |
e9ba0d |
*/
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
#include <stdio.h>
|
|
Packit |
e9ba0d |
#include <stdlib.h>
|
|
Packit |
e9ba0d |
#include <string.h>
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
#if defined(__clang__)
|
|
Packit |
e9ba0d |
#pragma clang diagnostic push
|
|
Packit |
e9ba0d |
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
Packit |
e9ba0d |
#endif
|
|
Packit |
e9ba0d |
#include <libxml/encoding.h>
|
|
Packit |
e9ba0d |
#include <libxml/xmlwriter.h>
|
|
Packit |
e9ba0d |
#if defined(__clang__)
|
|
Packit |
e9ba0d |
#pragma clang diagnostic pop
|
|
Packit |
e9ba0d |
#endif
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
#include "writer.h"
|
|
Packit |
e9ba0d |
#include "../log.h"
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
struct xml_writer_private {
|
|
Packit |
e9ba0d |
FILE *fh;
|
|
Packit |
e9ba0d |
ssize_t depth;
|
|
Packit |
e9ba0d |
xmlTextWriterPtr xw;
|
|
Packit |
e9ba0d |
xmlDocPtr doc;
|
|
Packit |
e9ba0d |
};
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void xml_new_writer(struct xml_writer_private *priv)
|
|
Packit |
e9ba0d |
{
|
|
Packit |
e9ba0d |
priv->xw = xmlNewTextWriterDoc(&(priv->doc), 0);
|
|
Packit |
e9ba0d |
if (!priv->xw)
|
|
Packit |
e9ba0d |
fatalx("lldpctl", "cannot create xml writer");
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
xmlTextWriterSetIndent(priv->xw, 4);
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (xmlTextWriterStartDocument(priv->xw, NULL, "UTF-8", NULL) < 0 )
|
|
Packit |
e9ba0d |
fatalx("lldpctl", "cannot start xml document");
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void xml_start(struct writer *w , const char *tag, const char *descr ) {
|
|
Packit |
e9ba0d |
struct xml_writer_private *p = w->priv;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (p->depth == 0)
|
|
Packit |
e9ba0d |
xml_new_writer(p);
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (xmlTextWriterStartElement(p->xw, BAD_CAST tag) < 0)
|
|
Packit |
e9ba0d |
log_warnx("lldpctl", "cannot start '%s' element", tag);
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (descr && (strlen(descr) > 0)) {
|
|
Packit |
e9ba0d |
if (xmlTextWriterWriteFormatAttribute(p->xw, BAD_CAST "label", "%s", descr) < 0)
|
|
Packit |
e9ba0d |
log_warnx("lldpctl", "cannot add attribute 'label' to element %s", tag);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
p->depth++;
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void xml_attr(struct writer *w, const char *tag, const char *descr, const char *value ) {
|
|
Packit |
e9ba0d |
struct xml_writer_private *p = w->priv;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (xmlTextWriterWriteFormatAttribute(p->xw, BAD_CAST tag, "%s", value?value:"") < 0)
|
|
Packit |
e9ba0d |
log_warnx("lldpctl", "cannot add attribute %s with value %s", tag, value?value:"(none)");
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void xml_data(struct writer *w, const char *data) {
|
|
Packit |
e9ba0d |
struct xml_writer_private *p = w->priv;
|
|
Packit |
e9ba0d |
if (xmlTextWriterWriteString(p->xw, BAD_CAST (data?data:"")) < 0 )
|
|
Packit |
e9ba0d |
log_warnx("lldpctl", "cannot add '%s' as data to element", data?data:"(none)");
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void xml_end(struct writer *w) {
|
|
Packit |
e9ba0d |
struct xml_writer_private *p = w->priv;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (xmlTextWriterEndElement(p->xw) < 0 )
|
|
Packit |
e9ba0d |
log_warnx("lldpctl", "cannot end element");
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (--p->depth == 0) {
|
|
Packit |
e9ba0d |
int failed = 0;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
if (xmlTextWriterEndDocument(p->xw) < 0 ) {
|
|
Packit |
e9ba0d |
log_warnx("lldpctl", "cannot finish document");
|
|
Packit |
e9ba0d |
failed = 1;
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
xmlFreeTextWriter(p->xw);
|
|
Packit |
e9ba0d |
if (!failed) {
|
|
Packit |
e9ba0d |
xmlDocDump(p->fh, p->doc);
|
|
Packit |
e9ba0d |
fflush(p->fh);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
xmlFreeDoc(p->doc);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
void xml_finish(struct writer *w) {
|
|
Packit |
e9ba0d |
struct xml_writer_private *p = w->priv;
|
|
Packit |
e9ba0d |
if (p->depth != 0) {
|
|
Packit |
e9ba0d |
log_warnx("lldpctl", "unbalanced tags");
|
|
Packit |
e9ba0d |
/* memory leak... */
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
free(p);
|
|
Packit |
e9ba0d |
free(w);
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
struct writer *xml_init(FILE *fh) {
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
struct writer *result;
|
|
Packit |
e9ba0d |
struct xml_writer_private *priv;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
priv = malloc(sizeof(*priv));
|
|
Packit |
e9ba0d |
if (!priv) {
|
|
Packit |
e9ba0d |
fatalx("lldpctl", "out of memory");
|
|
Packit |
e9ba0d |
return NULL;
|
|
Packit |
e9ba0d |
}
|
|
Packit |
e9ba0d |
priv->fh = fh;
|
|
Packit |
e9ba0d |
priv->depth = 0;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
result = malloc(sizeof(struct writer));
|
|
Packit |
e9ba0d |
if (!result)
|
|
Packit |
e9ba0d |
fatalx("lldpctl", "out of memory");
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
result->priv = priv;
|
|
Packit |
e9ba0d |
result->start = xml_start;
|
|
Packit |
e9ba0d |
result->attr = xml_attr;
|
|
Packit |
e9ba0d |
result->data = xml_data;
|
|
Packit |
e9ba0d |
result->end = xml_end;
|
|
Packit |
e9ba0d |
result->finish= xml_finish;
|
|
Packit |
e9ba0d |
|
|
Packit |
e9ba0d |
return result;
|
|
Packit |
e9ba0d |
}
|