Support infrastructure for simpler xml handler.
This commit is contained in:
parent
3ac71ba469
commit
3fe312ead6
175
src/xml-rpc.c
175
src/xml-rpc.c
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
@ -16,23 +17,142 @@
|
|||
#include "webserver.h"
|
||||
|
||||
/* typedefs */
|
||||
typedef struct tag_xmlstack {
|
||||
char *tag;
|
||||
struct tag_xmlstack *next;
|
||||
} XMLSTACK;
|
||||
|
||||
typedef struct tag_xmlstruct {
|
||||
WS_CONNINFO *pwsc;
|
||||
int stack_level;
|
||||
XMLSTACK stack;
|
||||
} XMLSTRUCT;
|
||||
|
||||
/* Forwards */
|
||||
void xml_get_stats(WS_CONNINFO *pwsc);
|
||||
char *xml_entity_encode(char *original);
|
||||
|
||||
XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header);
|
||||
void xml_push(XMLSTRUCT *pxml, char *term);
|
||||
void xml_pop(XMLSTRUCT *pxml);
|
||||
void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...);
|
||||
void xml_deinit(XMLSTRUCT *pxml);
|
||||
|
||||
/**
|
||||
* create an xml response structure, a helper struct for
|
||||
* building xml responses.
|
||||
*
|
||||
* @param pwsc the pwsc we are emitting to
|
||||
* @param emit_header whether or not to throw out html headers and xml header
|
||||
* @returns XMLSTRUCT on success, or NULL if failure
|
||||
*/
|
||||
XMLSTRUCT *xml_init(void) {
|
||||
XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header) {
|
||||
XMLSTRUCT *pxml;
|
||||
|
||||
pxml=(XMLSTRUCT*)malloc(sizeof(XMLSTRUCT));
|
||||
if(!pxml) {
|
||||
DPRINTF(E_FATAL,L_XML,"Malloc error\n");
|
||||
}
|
||||
|
||||
memset(pxml,0,sizeof(XMLSTRUCT));
|
||||
|
||||
pxml->pwsc = pwsc;
|
||||
|
||||
if(emit_header) {
|
||||
ws_addresponseheader(pwsc,"Content-Type","text/xml; charset=utf-8");
|
||||
ws_writefd(pwsc,"HTTP/1.0 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
ws_writefd(pwsc,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
||||
}
|
||||
|
||||
return pxml;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* push a new term on the stack
|
||||
*
|
||||
* @param pxml xml struct obtained from xml_init
|
||||
* @param term next xlm section to start
|
||||
*/
|
||||
void xml_push(XMLSTRUCT *pxml, char *term) {
|
||||
XMLSTACK *pstack;
|
||||
|
||||
pstack = (XMLSTACK *)malloc(sizeof(XMLSTACK));
|
||||
pstack->next=pxml->stack.next;
|
||||
pstack->tag=strdup(term);
|
||||
pxml->stack.next=pstack;
|
||||
|
||||
pxml->stack_level++;
|
||||
|
||||
ws_writefd(pxml->pwsc,"<%s>",term);
|
||||
}
|
||||
|
||||
/**
|
||||
* end an xml section
|
||||
*
|
||||
* @param pxml xml struct we are working with
|
||||
*/
|
||||
void xml_pop(XMLSTRUCT *pxml) {
|
||||
XMLSTACK *pstack;
|
||||
|
||||
pstack=pxml->stack.next;
|
||||
if(!pstack) {
|
||||
DPRINTF(E_LOG,L_XML,"xml_pop: tried to pop an empty stack\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pxml->stack.next = pstack->next;
|
||||
|
||||
ws_writefd(pxml->pwsc,"</%s>",pstack->tag);
|
||||
free(pstack->tag);
|
||||
free(pstack);
|
||||
|
||||
pxml->stack_level--;
|
||||
}
|
||||
|
||||
/**
|
||||
* output a string
|
||||
*/
|
||||
void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...) {
|
||||
va_list ap;
|
||||
char buf[256];
|
||||
char *output;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
output = xml_entity_encode(buf);
|
||||
if(section) {
|
||||
xml_push(pxml,section);
|
||||
}
|
||||
ws_writefd(pxml->pwsc,"%s",output);
|
||||
free(output);
|
||||
if(section) {
|
||||
xml_pop(pxml);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up an xml struct
|
||||
*
|
||||
* @param pxml xml struct to clean up
|
||||
*/
|
||||
void xml_deinit(XMLSTRUCT *pxml) {
|
||||
XMLSTACK *pstack;
|
||||
|
||||
if(pxml->stack.next) {
|
||||
DPRINTF(E_LOG,L_XML,"xml_deinit: entries still on stack (%s)\n",pxml->stack.next->tag);
|
||||
}
|
||||
|
||||
while((pstack=pxml->stack.next)) {
|
||||
pxml->stack.next=pstack->next;
|
||||
free(pstack->tag);
|
||||
free(pstack);
|
||||
}
|
||||
free(pxml);
|
||||
}
|
||||
|
||||
/**
|
||||
* main entrypoint for the xmlrpc functions.
|
||||
|
@ -66,39 +186,33 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
|
|||
SCAN_STATUS *pss;
|
||||
WSTHREADENUM wste;
|
||||
|
||||
|
||||
ws_addresponseheader(pwsc,"Content-Type","text/xml; charset=utf-8");
|
||||
ws_writefd(pwsc,"HTTP/1.0 200 OK\r\n");
|
||||
ws_emitheaders(pwsc);
|
||||
|
||||
ws_writefd(pwsc,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
||||
ws_writefd(pwsc,"<status>");
|
||||
|
||||
ws_writefd(pwsc,"<service_status>");
|
||||
/* enumerate services? */
|
||||
ws_writefd(pwsc,"</service_status>");
|
||||
XMLSTRUCT *pxml;
|
||||
|
||||
ws_writefd(pwsc,"<thread_status>");
|
||||
/* enumerate thread status */
|
||||
pxml=xml_init(pwsc,1);
|
||||
xml_push(pxml,"status");
|
||||
|
||||
xml_push(pxml,"service_status");
|
||||
xml_pop(pxml); /* service_status */
|
||||
|
||||
xml_push(pxml,"thread_status");
|
||||
|
||||
pci = ws_thread_enum_first(config.server,&wste);
|
||||
while(pci) {
|
||||
pss = ws_get_local_storage(pci);
|
||||
if(pss) {
|
||||
ws_writefd(pwsc,"<thread><id>%d</id><sourceip>%s</sourceip><action>%s</action></thread>",
|
||||
pss->thread,pss->host,pss->what);
|
||||
xml_push(pxml,"thread");
|
||||
xml_output(pxml,"id","%d",pss->thread);
|
||||
xml_output(pxml,"sourceip","%s",pss->host);
|
||||
xml_output(pxml,"action","%s",pss->what);
|
||||
xml_pop(pxml); /* thread */
|
||||
}
|
||||
pci=ws_thread_enum_next(config.server,&wste);
|
||||
}
|
||||
|
||||
|
||||
ws_writefd(pwsc,"</thread_status>");
|
||||
|
||||
ws_writefd(pwsc,"<statistics>");
|
||||
/* dump stats */
|
||||
|
||||
ws_writefd(pwsc,"<stat name=\"uptime\">");
|
||||
xml_pop(pxml); /* thread_status */
|
||||
|
||||
xml_push(pxml,"statistics");
|
||||
|
||||
r_secs=time(NULL)-config.stats.start_time;
|
||||
|
||||
r_days=r_secs/(3600 * 24);
|
||||
|
@ -126,11 +240,14 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
|
|||
sprintf((char*)&buf[strlen(buf)],"%d second%s ", r_secs,
|
||||
r_secs == 1 ? "" : "s");
|
||||
|
||||
ws_writefd(pwsc,"<name>Uptime</name>");
|
||||
ws_writefd(pwsc,"<value>%s</value>",buf);
|
||||
ws_writefd(pwsc,"</stat>");
|
||||
ws_writefd(pwsc,"</statistics>");
|
||||
ws_writefd(pwsc,"</status>");
|
||||
xml_push(pxml,"stat");
|
||||
xml_output(pxml,"name","Uptime");
|
||||
xml_output(pxml,"value","%s",buf);
|
||||
xml_pop(pxml); /* stat */
|
||||
xml_pop(pxml); /* statistics */
|
||||
xml_pop(pxml); /* status */
|
||||
|
||||
xml_deinit(pxml);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue