From 2be04db4d2d754f87ee8e3abbab443da51219158 Mon Sep 17 00:00:00 2001 From: Julien BLACHE Date: Sun, 3 May 2009 11:00:37 +0200 Subject: [PATCH] Remove RSP output plugin --- src/plugins/Makefile.am | 8 - src/plugins/rsp.c | 559 ---------------------------------------- src/plugins/rsp.h | 14 - src/plugins/xml-rpc.c | 391 ---------------------------- src/plugins/xml-rpc.h | 18 -- 5 files changed, 990 deletions(-) delete mode 100644 src/plugins/rsp.c delete mode 100644 src/plugins/rsp.h delete mode 100644 src/plugins/xml-rpc.c delete mode 100644 src/plugins/xml-rpc.h diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 949acb1b..e8ca5bc1 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -1,11 +1,3 @@ -rspdir = ${pkglibdir}/plugins - -rsp_LTLIBRARIES=rsp.la -rsp_la_LDFLAGS=-module -avoid-version -rsp_la_SOURCES = rsp.c xml-rpc.c - -EXTRA_DIST = rsp.h xml-rpc.h - AM_CFLAGS = -I.. diff --git a/src/plugins/rsp.c b/src/plugins/rsp.c deleted file mode 100644 index febeb51d..00000000 --- a/src/plugins/rsp.c +++ /dev/null @@ -1,559 +0,0 @@ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_STDINT_H -#include -#endif - -#include -#include -#include - -#include "ff-dbstruct.h" -#include "ff-plugins.h" -#include "rsp.h" -#include "xml-rpc.h" - -typedef struct tag_rsp_privinfo { - DB_QUERY dq; - int uri_count; - char *uri_sections[10]; -} PRIVINFO; - -/* Forwards */ -PLUGIN_INFO *plugin_info(void); -void plugin_handler(WS_CONNINFO *pwsc); -int plugin_can_handle(WS_CONNINFO *pwsc); -int plugin_auth(WS_CONNINFO *pwsc, char *username, char *password); -void rsp_info(WS_CONNINFO *pwsc, PRIVINFO *ppi); -void rsp_db(WS_CONNINFO *pwsc, PRIVINFO *ppi); -void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi); -void rsp_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi); -void rsp_stream(WS_CONNINFO *pwsc, PRIVINFO *ppi); -void rsp_error(WS_CONNINFO *pwsc, PRIVINFO *ppi, int eno, char *estr); - -/* Globals */ -PLUGIN_OUTPUT_FN _pofn = { plugin_can_handle, plugin_handler, plugin_auth }; -PLUGIN_REND_INFO _pri[] = { - { "_rsp._tcp", NULL }, - { NULL, NULL } -}; - -PLUGIN_INFO _pi = { - PLUGIN_VERSION, /* version */ - PLUGIN_OUTPUT, /* type */ - "rsp/" VERSION, /* server */ - &_pofn, /* output fns */ - NULL, /* event fns */ - NULL, /* transcode fns */ - _pri, /* rend info */ - NULL /* transcode info */ -}; - -typedef struct tag_response { - char *uri[10]; - void (*dispatch)(WS_CONNINFO *, PRIVINFO *); -} PLUGIN_RESPONSE; - - -PLUGIN_RESPONSE rsp_uri_map[] = { - {{"rsp", "info",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }, rsp_info }, - {{"rsp", "db" ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }, rsp_db }, - {{"rsp", "db" , "*",NULL,NULL,NULL,NULL,NULL,NULL,NULL }, rsp_playlist }, - {{"rsp", "db" , "*", "*",NULL,NULL,NULL,NULL,NULL,NULL }, rsp_browse }, - {{"rsp","stream", "*",NULL,NULL,NULL,NULL,NULL,NULL,NULL }, rsp_stream } -}; - -#define E_RSP 0x0000 -#define E_DB 0x1000 - - -#define T_STRING 0 -#define T_INT 1 -#define T_DATE 2 - -#define F_FULL 1 -#define F_BROWSE 2 -#define F_ID 4 -#define F_DETAILED 8 - -typedef struct tag_fieldspec { - char *name; - int flags; /* 1: full, 2: browse, 4: id */ - int type; /* 0: string, 1: int, 2: date */ -} FIELDSPEC; - -FIELDSPEC rsp_playlist_fields[] = { - { "id" , 15, T_INT }, - { "title" , 11, T_STRING }, - { "type" , 8, T_INT }, - { "items" , 11, T_INT }, - { "query" , 8, T_STRING }, - { "db_timestamp" , 8, T_DATE }, - { "path" , 8, T_STRING }, - { "index" , 8, T_INT }, - { NULL , 0, 0 } -}; - -FIELDSPEC rsp_fields[] = { - { "id" , 15, T_INT }, - { "path" , 8, T_STRING }, - { "fname" , 8, T_STRING }, - { "title" , 15, T_STRING }, - { "artist" , 11, T_STRING }, - { "album" , 11, T_STRING }, - { "genre" , 9, T_STRING }, - { "comment" , 9, T_STRING }, - { "type" , 15, T_STRING }, - { "composer" , 9, T_STRING }, - { "orchestra" , 9, T_STRING }, - { "conductor" , 9, T_STRING }, - { "grouping" , 0, T_STRING }, - { "url" , 9, T_STRING }, - { "bitrate" , 9, T_INT }, - { "samplerate" , 9, T_INT }, - { "song_length" , 9, T_INT }, - { "file_size" , 9, T_INT }, - { "year" , 9, T_INT }, - { "track" , 11, T_INT }, - { "total_tracks" , 9, T_INT }, - { "disc" , 11, T_INT }, - { "total_discs" , 9, T_INT }, - { "bpm" , 9, T_INT }, - { "compilation" , 9, T_INT }, - { "rating" , 9, T_INT }, - { "play_count" , 9, T_INT }, - { "data_kind" , 8, T_INT }, - { "item_kind" , 8, T_INT }, - { "description" , 9, T_STRING }, - { "time_added" , 9, T_DATE }, - { "time_modified", 9, T_DATE }, - { "time_played" , 9, T_DATE }, - { "db_timestamp" , 8, T_DATE }, - { "disabled" , 15, T_INT }, - { "sample_count" , 8, T_INT }, - { "force_update" , 8, T_INT }, - { "codectype" , 15, T_INT }, - { "idx" , 8, T_INT }, - { "has_video" , 8, T_INT }, - { "contentrating", 8, T_INT }, - { NULL , 0 } -}; - -/** - * return info about this plugin module - */ -PLUGIN_INFO *plugin_info(void) { - return &_pi; -} - -/** - * see if the plugin should handle this request - */ -int plugin_can_handle(WS_CONNINFO *pwsc) { - pi_log(E_DBG,"Checking url %s\n",pi_ws_uri(pwsc)); - if(strncasecmp(pi_ws_uri(pwsc),"/rsp/",5) == 0) - return TRUE; - return FALSE; -} - -/** - * check for auth. Kind of a ham-handed implementation, but - * works. - */ -int plugin_auth(WS_CONNINFO *pwsc, char *username, char *password) { - return pi_ws_matchesrole(pwsc,username,password,"user"); -} - -/** - * dispatch handler for web stuff - */ -void plugin_handler(WS_CONNINFO *pwsc) { - char *string, *save, *token; - PRIVINFO *ppi; - int elements; - int index, part; - int found; - - pi_log(E_DBG,"Getting uri...\n"); - - string = pi_ws_uri(pwsc); - string++; - - pi_log(E_DBG,"Mallocing privinfo...\n"); - ppi = (PRIVINFO *)malloc(sizeof(PRIVINFO)); - if(ppi) { - memset(ppi,0,sizeof(PRIVINFO)); - } - - if(!ppi) { - pi_ws_returnerror(pwsc,500,"Malloc error in plugin_handler"); - return; - } - - memset((void*)&ppi->dq,0,sizeof(DB_QUERY)); - - pi_log(E_DBG,"Tokenizing url\n"); - save = NULL; - while((ppi->uri_count < 10) && (token=strtok_r(string,"/",&save))) { - string=NULL; - ppi->uri_sections[ppi->uri_count++] = token; - } - - elements = sizeof(rsp_uri_map) / sizeof(PLUGIN_RESPONSE); - pi_log(E_DBG,"Found %d elements\n",elements); - - index = 0; - found = 0; - - while((!found) && (index < elements)) { - /* test this set */ - pi_log(E_DBG,"Checking reponse %d\n",index); - part=0; - while(part < 10) { - if((rsp_uri_map[index].uri[part]) && (!ppi->uri_sections[part])) - break; - if((ppi->uri_sections[part]) && (!rsp_uri_map[index].uri[part])) - break; - - if((rsp_uri_map[index].uri[part]) && - (strcmp(rsp_uri_map[index].uri[part],"*") != 0)) { - if(strcmp(rsp_uri_map[index].uri[part], - ppi->uri_sections[part])!= 0) - break; - } - part++; - } - - if(part == 10) { - found = 1; - pi_log(E_DBG,"Found it! Index: %d\n",index); - } else { - index++; - } - } - - if(found) { - rsp_uri_map[index].dispatch(pwsc, ppi); - pi_ws_will_close(pwsc); - free(ppi); - return; - } - - rsp_error(pwsc, ppi, 1, "Bad path"); - pi_ws_will_close(pwsc); - free(ppi); - return; -} - -/** - * get server info - */ -void rsp_info(WS_CONNINFO *pwsc, PRIVINFO *ppi) { - XMLSTRUCT *pxml; - char servername[256]; - int size; - - pi_log(E_DBG,"Starting rsp_info\n"); - pi_config_set_status(pwsc,0,"Getting server info"); - - pxml = xml_init(pwsc,1); - - xml_push(pxml,"response"); - xml_push(pxml,"status"); - xml_output(pxml,"errorcode","0"); - xml_output(pxml,"errorstring",""); - xml_output(pxml,"records","0"); - xml_output(pxml,"totalrecords","0"); - xml_pop(pxml); /* status */ - - /* info block */ - xml_push(pxml,"info"); - xml_output(pxml,"count","%d",pi_db_count_items(COUNT_SONGS)); - xml_output(pxml,"rsp-version","%s",RSP_VERSION); - - xml_output(pxml,"server-version","%s",pi_server_ver()); - - size = sizeof(servername); - pi_server_name(servername,&size); - xml_output(pxml,"name","%s",servername); - xml_pop(pxml); /* info */ - - xml_pop(pxml); /* response */ - xml_deinit(pxml); - pi_config_set_status(pwsc,0,NULL); -} - -/** - * /rsp/db - * - * dump details about all playlists - */ -void rsp_db(WS_CONNINFO *pwsc, PRIVINFO *ppi) { - XMLSTRUCT *pxml; - char *pe; - int err; - char **row; - int rowindex; - - ppi->dq.query_type = QUERY_TYPE_PLAYLISTS; - - if((err=pi_db_enum_start(&pe,&ppi->dq)) != 0) { - rsp_error(pwsc, ppi, err | E_DB, pe); - pi_db_enum_dispose(NULL,&ppi->dq); - return; - } - - pi_config_set_status(pwsc,0,"Fetching playlist info"); - pxml = xml_init(pwsc,1); - - xml_push(pxml,"response"); - xml_push(pxml,"status"); - xml_output(pxml,"errorcode","0"); - xml_output(pxml,"errorstring",""); - xml_output(pxml,"records","%d",ppi->dq.totalcount); - xml_output(pxml,"totalrecords","%d",ppi->dq.totalcount); - xml_pop(pxml); /* status */ - - xml_push(pxml,"playlists"); - - while((pi_db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) { - xml_push(pxml,"playlist"); - rowindex=0; - while(rsp_playlist_fields[rowindex].name) { - if(rsp_playlist_fields[rowindex].flags & F_FULL) { - xml_output(pxml,rsp_playlist_fields[rowindex].name,"%s", - row[rowindex]); - } - rowindex++; - } - xml_pop(pxml); /* playlist */ - } - - pi_db_enum_end(NULL); - pi_db_enum_dispose(NULL,&ppi->dq); - - xml_pop(pxml); /* playlists */ - xml_pop(pxml); /* response */ - xml_deinit(pxml); - pi_config_set_status(pwsc,0,NULL); -} - -/** - * get all items under the playlist - */ -void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { - XMLSTRUCT *pxml; - char *pe; - int err; - char **row; - int rowindex; - int returned; - char *browse_type; - int type; - int transcode; - unsigned int samplerate; - int done = 0; - - ppi->dq.filter = pi_ws_getvar(pwsc,"query"); - ppi->dq.filter_type = FILTER_TYPE_FIREFLY; - - if(pi_ws_getvar(pwsc,"offset")) { - ppi->dq.offset = atoi(pi_ws_getvar(pwsc,"offset")); - } - if(pi_ws_getvar(pwsc,"limit")) { - ppi->dq.limit = atoi(pi_ws_getvar(pwsc,"limit")); - } - - browse_type = pi_ws_getvar(pwsc,"type"); - type = F_FULL; - - if(browse_type) { - if(strcasecmp(browse_type,"browse") == 0) { - type = F_BROWSE; - } else if(strcasecmp(browse_type,"id") == 0) { - type = F_ID; - } else if(strcasecmp(browse_type,"detailed") ==0) { - type = F_DETAILED; - } - } - - ppi->dq.query_type = QUERY_TYPE_ITEMS; - ppi->dq.playlist_id = atoi(ppi->uri_sections[2]); - - if((err=pi_db_enum_start(&pe,&ppi->dq)) != 0) { - rsp_error(pwsc, ppi, err | E_DB, pe); - pi_db_enum_dispose(NULL,&ppi->dq); - free(pe); - return; - } - - pi_config_set_status(pwsc,0,"Fetching playlist items"); - pxml = xml_init(pwsc,1); - - if(ppi->dq.offset > ppi->dq.totalcount) { - returned = 0; - } else { - returned = ppi->dq.limit; - if(returned > (ppi->dq.totalcount - ppi->dq.offset)) - returned = ppi->dq.totalcount - ppi->dq.offset; - } - - xml_push(pxml,"response"); - xml_push(pxml,"status"); - xml_output(pxml,"errorcode","0"); - xml_output(pxml,"errorstring",""); - xml_output(pxml,"records","%d",returned); - xml_output(pxml,"totalrecords","%d",ppi->dq.totalcount); - xml_pop(pxml); /* status */ - - xml_push(pxml,"items"); - - while((!done) && (pi_db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && - (row)) { - xml_push(pxml,"item"); - rowindex=0; - transcode = 0; - - transcode = pi_should_transcode(pwsc,row[37]); - - pi_log(E_DBG,"Transcode: %d, %s: %s\n",transcode,row[37],row[2]); - - while(rsp_fields[rowindex].name) { - if((rsp_fields[rowindex].flags & type) && - (row[rowindex] && strlen(row[rowindex]))) { - if(transcode) { - switch(rowindex) { - case 8: - xml_output(pxml,rsp_fields[rowindex].name,"%s","wav"); - break; - case 29: - xml_output(pxml,rsp_fields[rowindex].name,"%s", - "wav audio file"); - break; - case 14: /* bitrate */ - samplerate = atoi(row[15]); - if(samplerate) { - samplerate = (samplerate * 8) / 250; - } else { - samplerate = 1411; - } - xml_output(pxml,rsp_fields[rowindex].name,"%d", - samplerate); - break; - case 37: - xml_output(pxml,rsp_fields[rowindex].name,"%s","wav"); - xml_output(pxml,"original_codec","%s",row[37]); - break; - default: - xml_output(pxml,rsp_fields[rowindex].name,"%s", - row[rowindex]); - break; - } - } else { - /* check for pushing against closed socket */ - if(xml_output(pxml,rsp_fields[rowindex].name,"%s", - row[rowindex]) == -1) - done=1; - } - - } - rowindex++; - } - xml_pop(pxml); /* item */ - } - - pi_db_enum_end(NULL); - - xml_pop(pxml); /* items */ - xml_pop(pxml); /* response */ - xml_deinit(pxml); - pi_config_set_status(pwsc,0,NULL); -} - -void rsp_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) { - XMLSTRUCT *pxml; - char *pe; - int err; - char **row; - int returned; - - /* this might fail if an unsupported browse type */ - ppi->dq.query_type = QUERY_TYPE_DISTINCT; - ppi->dq.distinct_field = ppi->uri_sections[3]; - ppi->dq.filter = pi_ws_getvar(pwsc,"query"); - ppi->dq.filter_type = FILTER_TYPE_FIREFLY; - - if(pi_ws_getvar(pwsc,"offset")) { - ppi->dq.offset = atoi(pi_ws_getvar(pwsc,"offset")); - } - - if(pi_ws_getvar(pwsc,"limit")) { - ppi->dq.limit = atoi(pi_ws_getvar(pwsc,"limit")); - } - - ppi->dq.playlist_id = atoi(ppi->uri_sections[2]); - - if((err=pi_db_enum_start(&pe,&ppi->dq)) != 0) { - rsp_error(pwsc, ppi, err | E_DB, pe); - pi_db_enum_dispose(NULL,&ppi->dq); - return; - } - - pi_config_set_status(pwsc,0,"Browsing"); - pxml = xml_init(pwsc,1); - - if(ppi->dq.offset > ppi->dq.totalcount) { - returned = 0; - } else { - returned = ppi->dq.limit; - if(returned > (ppi->dq.totalcount - ppi->dq.offset)) - returned = ppi->dq.totalcount - ppi->dq.offset; - } - - xml_push(pxml,"response"); - xml_push(pxml,"status"); - xml_output(pxml,"errorcode","0"); - xml_output(pxml,"errorstring",""); - xml_output(pxml,"records","%d",returned); - xml_output(pxml,"totalrecords","%d",ppi->dq.totalcount); - xml_pop(pxml); /* status */ - - xml_push(pxml,"items"); - - while((pi_db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) { - xml_output(pxml,"item","%s",row[0]); - } - - pi_db_enum_end(NULL); - pi_db_enum_dispose(NULL,&ppi->dq); - - xml_pop(pxml); /* items */ - xml_pop(pxml); /* response */ - xml_deinit(pxml); - pi_config_set_status(pwsc,0,NULL); -} - -void rsp_stream(WS_CONNINFO *pwsc, PRIVINFO *ppi) { - pi_stream(pwsc, ppi->uri_sections[2]); - return; -} - -void rsp_error(WS_CONNINFO *pwsc, PRIVINFO *ppi, int eno, char *estr) { - XMLSTRUCT *pxml; - - pxml = xml_init(pwsc, 1); - xml_push(pxml,"response"); - xml_push(pxml,"status"); - xml_output(pxml,"errorcode","%d",eno); - xml_output(pxml,"errorstring","%s",estr); - xml_output(pxml,"records","0"); - xml_output(pxml,"totalrecords","0"); - xml_pop(pxml); /* status */ - xml_pop(pxml); /* response */ - xml_deinit(pxml); - pi_ws_will_close(pwsc); -} - diff --git a/src/plugins/rsp.h b/src/plugins/rsp.h deleted file mode 100644 index 5c9db346..00000000 --- a/src/plugins/rsp.h +++ /dev/null @@ -1,14 +0,0 @@ - -#ifndef _RSP_H_ -#define _RSP_H_ - -#define RSP_VERSION "1.0" - -extern PLUGIN_INFO _pi; - -#ifndef TRUE -# define TRUE 1 -# define FALSE 0 -#endif - -#endif /* _RSP_H_ */ diff --git a/src/plugins/xml-rpc.c b/src/plugins/xml-rpc.c deleted file mode 100644 index 4b00301e..00000000 --- a/src/plugins/xml-rpc.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * This really isn't xmlrpc. It's xmlrpc-ish. Emphasis on -ish. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_STDINT_H -#include -#endif - -#include -#include -#include -#include -#include -#include - -#include "ff-dbstruct.h" -#include "ff-plugins.h" -#include "rsp.h" -#include "xml-rpc.h" - - -/* typedefs */ -typedef struct tag_xmlstack { - char *tag; - struct tag_xmlstack *next; -} XMLSTACK; - -#define XML_STREAM_BLOCK 4096 -typedef struct tag_xml_streambuffer { - z_stream strm; - unsigned char *in_buffer; - unsigned char *out_buffer; -} XML_STREAMBUFFER; - -struct tag_xmlstruct { - WS_CONNINFO *pwsc; - int stack_level; - XMLSTACK stack; - XML_STREAMBUFFER *psb; -}; - -/* Forwards */ -void xml_get_stats(WS_CONNINFO *pwsc); -void xml_set_config(WS_CONNINFO *pwsc); -void xml_return_error(WS_CONNINFO *pwsc, int errno, char *errstr); -char *xml_entity_encode(char *original); - -XML_STREAMBUFFER *xml_stream_open(void); -int xml_stream_write(XMLSTRUCT *pxml, char *out); -int xml_stream_close(XMLSTRUCT *pxml); - -int xml_write(XMLSTRUCT *pxml, char *fmt, ...) { - char buffer[1024]; - va_list ap; - int result=0; - - va_start(ap, fmt); - vsnprintf(buffer, 1024, fmt, ap); - va_end(ap); - - if(pxml->psb) { - result=xml_stream_write(pxml, buffer); - if(!result) - result = -1; - } else { - result=pi_ws_writefd(pxml->pwsc,"%s",buffer); - } - - return result; -} - -void xml_return_error(WS_CONNINFO *pwsc, int errno, char *errstr) { - XMLSTRUCT *pxml; - - pxml=xml_init(pwsc,TRUE); - xml_push(pxml,"results"); - - xml_output(pxml,"status","%d",errno); - xml_output(pxml,"statusstring","%s",errstr); - - xml_pop(pxml); /* results */ - xml_deinit(pxml); - return; -} - - -/** - * open a gzip stream - */ -XML_STREAMBUFFER *xml_stream_open(void) { - XML_STREAMBUFFER *psb; - - psb = (XML_STREAMBUFFER*) malloc(sizeof(XML_STREAMBUFFER)); - if(!psb) { - pi_log(E_FATAL,"xml_stream_open: malloc\n"); - } - - psb->out_buffer = (unsigned char*) malloc(XML_STREAM_BLOCK); - psb->in_buffer = (unsigned char*) malloc(XML_STREAM_BLOCK); - - if((!psb->out_buffer) || (!psb->in_buffer)) { - pi_log(E_FATAL,"xml_stream_open: malloc\n"); - } - - psb->strm.zalloc = Z_NULL; - psb->strm.zfree = Z_NULL; - psb->strm.opaque = Z_NULL; - - psb->strm.next_in = psb->in_buffer; - psb->strm.next_out = psb->out_buffer; - - deflateInit2(&psb->strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, - 24, 8, Z_DEFAULT_STRATEGY); - return psb; -} - -/** - * write a block to the stream - */ -int xml_stream_write(XMLSTRUCT *pxml, char *out) { - int done = 0; - int result; - XML_STREAMBUFFER *psb = pxml->psb; - - if((!out)||(!strlen(out))) - return TRUE; - - if(strlen(out) > 1024) - return TRUE; - - memcpy(psb->in_buffer,out,(int)strlen(out)); - psb->strm.avail_in = (int)strlen(out); - psb->strm.next_in = psb->in_buffer; - psb->strm.next_out = psb->out_buffer; - psb->strm.avail_out = XML_STREAM_BLOCK; - - while(!done) { - result = deflate(&psb->strm, Z_NO_FLUSH); - if(result != Z_OK) { - pi_log(E_FATAL,"Error in zlib: %d\n",result); - } - pi_ws_writebinary(pxml->pwsc,(char*)psb->out_buffer, - XML_STREAM_BLOCK-psb->strm.avail_out); - if(psb->strm.avail_out != 0) { - done=1; - } else { - psb->strm.avail_out = XML_STREAM_BLOCK; - psb->strm.next_out = psb->out_buffer; - } - } - return TRUE; -} - -/** - * close the stream - */ -int xml_stream_close(XMLSTRUCT *pxml) { - int done = 0; - XML_STREAMBUFFER *psb = pxml->psb; - - /* flush what's left */ - while(!done) { - psb->strm.avail_out = XML_STREAM_BLOCK; - psb->strm.next_out = psb->out_buffer; - psb->strm.avail_in = 0; - psb->strm.next_in = psb->in_buffer; - - deflate(&psb->strm,Z_FINISH); - pi_ws_writebinary(pxml->pwsc,(char*)psb->out_buffer, - XML_STREAM_BLOCK - psb->strm.avail_out); - - if(psb->strm.avail_out != 0) - done=1; - } - - pi_log(E_DBG,"Done sending xml stream\n"); - deflateEnd(&psb->strm); - if(psb->out_buffer != NULL) - free(psb->out_buffer); - if(psb->in_buffer != NULL) - free(psb->in_buffer); - free(psb); - - return TRUE; -} - -/** - * 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(WS_CONNINFO *pwsc, int emit_header) { - XMLSTRUCT *pxml; - char *accept; - char *nogzip; - - pxml=(XMLSTRUCT*)malloc(sizeof(XMLSTRUCT)); - if(!pxml) { - pi_log(E_FATAL,"Malloc error\n"); - } - - memset(pxml,0,sizeof(XMLSTRUCT)); - - pxml->pwsc = pwsc; - - /* should we compress output? */ - nogzip = pi_ws_getvar(pwsc,"nogzip"); - accept = pi_ws_getrequestheader(pwsc,"accept-encoding"); - - if((!nogzip) && (accept) && (strcasestr(accept,"gzip"))) { - pi_log(E_DBG,"Gzipping output\n"); - pxml->psb = xml_stream_open(); - if(pxml->psb) { - pi_ws_addresponseheader(pwsc,"Content-Encoding","gzip"); - pi_ws_addresponseheader(pwsc,"Vary","Accept-Encoding"); - pi_ws_addresponseheader(pwsc,"Connection","Close"); - } - } - - /* the world would be a wonderful place without ie */ - pi_ws_addresponseheader(pwsc,"Cache-Control","no-cache"); - pi_ws_addresponseheader(pwsc,"Expires","-1"); - - if(emit_header) { - pi_ws_addresponseheader(pwsc,"Content-Type","text/xml; charset=utf-8"); - pi_ws_writefd(pwsc,"HTTP/1.0 200 OK\r\n"); - pi_ws_emitheaders(pwsc); - - - xml_write(pxml,""); - } - - 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++; - - xml_write(pxml,"<%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) { - pi_log(E_LOG,"xml_pop: tried to pop an empty stack\n"); - return; - } - - pxml->stack.next = pstack->next; - - xml_write(pxml,"",pstack->tag); - free(pstack->tag); - free(pstack); - - pxml->stack_level--; -} - -/* FIXME: Fixed at 256? And can't I get an expandable sprintf/cat? */ - -/** - * output a string - */ -int xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...) { - va_list ap; - char buf[256]; - char *output; - int result=0; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - - output = xml_entity_encode(buf); - if(section) { - xml_push(pxml,section); - } - - result = xml_write(pxml,"%s",output); - free(output); - if(section) { - xml_pop(pxml); - } - - return result; -} - -/** - * clean up an xml struct - * - * @param pxml xml struct to clean up - */ -void xml_deinit(XMLSTRUCT *pxml) { - XMLSTACK *pstack; - - if(pxml->stack.next) { - pi_log(E_LOG,"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); - } - - if(pxml->psb) { - xml_stream_close(pxml); - } - - free(pxml); -} - -/** - * xml entity encoding, stupid style - */ -char *xml_entity_encode(char *original) { - char *new; - char *s, *d; - int destsize; - - destsize = 6*(int)strlen(original)+1; - new=(char *)malloc(destsize); - if(!new) return NULL; - - memset(new,0x00,destsize); - - s=original; - d=new; - - while(*s) { - switch(*s) { - case '>': - strcat(d,">"); - d += 4; - s++; - break; - case '<': - strcat(d,"<"); - d += 4; - s++; - break; - case '"': - strcat(d,"""); - d += 6; - s++; - break; - case '\'': - strcat(d,"'"); - d += 6; - s++; - break; - case '&': - strcat(d,"&"); - d += 5; - s++; - break; - default: - *d++ = *s++; - } - } - - return new; -} diff --git a/src/plugins/xml-rpc.h b/src/plugins/xml-rpc.h deleted file mode 100644 index 97fa2b4a..00000000 --- a/src/plugins/xml-rpc.h +++ /dev/null @@ -1,18 +0,0 @@ - -#ifndef _XMLRPC_H_ -#define _XMLRPC_H_ - -#include "ff-plugins.h" - -struct tag_xmlstruct; -typedef struct tag_xmlstruct XMLSTRUCT; -typedef struct tag_ws_conninfo WS_CONNINFO; - -extern XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header); -extern void xml_push(XMLSTRUCT *pxml, char *term); -extern void xml_pop(XMLSTRUCT *pxml); -extern int xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...); -extern void xml_deinit(XMLSTRUCT *pxml); - - -#endif /* _XMLRPC_H_ */