add ffmpeg-based transcoding

This commit is contained in:
Ron Pedde
2006-05-28 04:06:14 +00:00
parent da8f1a6f8f
commit 0f64686356
16 changed files with 708 additions and 413 deletions

View File

@@ -2,6 +2,7 @@
#
rspdir = ${pkgdatadir}/plugins
ssc_ffmpegdir = ${pkgdatadir}/plugins
ssc_scriptdir = ${pkgdatadir}/plugins
rsp_LTLIBRARIES=rsp.la
rsp_la_LDFLAGS=-module -avoid-version
@@ -13,7 +14,11 @@ ssc_ffmpeg_la_LDFLAGS=-module -avoid-version
ssc_ffmpeg_la_SOURCES=ssc-ffmpeg.c
endif
EXTRA_DIST = compat.h rsp.h mtd-plugins.h xml-rpc.h ssc-ffmpeg.c
ssc_script_LTLIBRARIES=ssc-script.la
ssc_script_la_LDFLAGS=-module -avoid-version
ssc_script_la_SOURCES=ssc-script.c
EXTRA_DIST = compat.h rsp.h mtd-plugins.h xml-rpc.h ssc-ffmpeg.c ssc-script.c
AM_CFLAGS = -I..

View File

@@ -22,7 +22,7 @@ typedef struct tag_rsp_privinfo {
} PRIVINFO;
/* Forwards */
PLUGIN_INFO *plugin_info(void);
PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *);
void plugin_handler(WS_CONNINFO *pwsc);
int plugin_auth(WS_CONNINFO *pwsc, char *username, char *pw);
void rsp_info(WS_CONNINFO *pwsc, PRIVINFO *ppi);
@@ -39,6 +39,8 @@ PLUGIN_REND_INFO _pri[] = {
{ NULL, NULL }
};
PLUGIN_INPUT_FN *_ppi;
PLUGIN_INFO _pi = {
PLUGIN_VERSION, /* version */
PLUGIN_OUTPUT, /* type */
@@ -47,7 +49,6 @@ PLUGIN_INFO _pi = {
&_pofn, /* output fns */
NULL, /* event fns */
NULL, /* transcode fns */
NULL, /* ff functions */
_pri, /* rend info */
NULL /* transcode info */
};
@@ -145,7 +146,8 @@ FIELDSPEC rsp_fields[] = {
/**
* return info about this plugin module
*/
PLUGIN_INFO *plugin_info(void) {
PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) {
_ppi = ppi;
return &_pi;
}
@@ -168,7 +170,7 @@ void plugin_handler(WS_CONNINFO *pwsc) {
int index, part;
int found;
string = infn->ws_uri(pwsc);
string = _ppi->ws_uri(pwsc);
string++;
ppi = (PRIVINFO *)malloc(sizeof(PRIVINFO));
@@ -177,27 +179,27 @@ void plugin_handler(WS_CONNINFO *pwsc) {
}
if(!ppi) {
infn->ws_returnerror(pwsc,500,"Malloc error in plugin_handler");
_ppi->ws_returnerror(pwsc,500,"Malloc error in plugin_handler");
return;
}
memset((void*)&ppi->dq,0,sizeof(DB_QUERY));
infn->log(E_DBG,"Tokenizing url\n");
_ppi->log(E_DBG,"Tokenizing url\n");
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);
infn->log(E_DBG,"Found %d elements\n",elements);
_ppi->log(E_DBG,"Found %d elements\n",elements);
index = 0;
found = 0;
while((!found) && (index < elements)) {
/* test this set */
infn->log(E_DBG,"Checking reponse %d\n",index);
_ppi->log(E_DBG,"Checking reponse %d\n",index);
part=0;
while(part < 10) {
if((rsp_uri_map[index].uri[part]) && (!ppi->uri_sections[part]))
@@ -216,7 +218,7 @@ void plugin_handler(WS_CONNINFO *pwsc) {
if(part == 10) {
found = 1;
infn->log(E_DBG,"Found it! Index: %d\n",index);
_ppi->log(E_DBG,"Found it! Index: %d\n",index);
} else {
index++;
}
@@ -224,13 +226,13 @@ void plugin_handler(WS_CONNINFO *pwsc) {
if(found) {
rsp_uri_map[index].dispatch(pwsc, ppi);
infn->ws_close(pwsc);
_ppi->ws_close(pwsc);
free(ppi);
return;
}
rsp_error(pwsc, ppi, 1, "Bad path");
infn->ws_close(pwsc);
_ppi->ws_close(pwsc);
free(ppi);
return;
}
@@ -243,7 +245,7 @@ void rsp_info(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
char servername[256];
int size;
infn->log(E_DBG,"Starting rsp_info\n");
_ppi->log(E_DBG,"Starting rsp_info\n");
pxml = xml_init(pwsc,1);
@@ -257,13 +259,13 @@ void rsp_info(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
/* info block */
xml_push(pxml,"info");
xml_output(pxml,"count","%d",infn->db_count());
xml_output(pxml,"count","%d",_ppi->db_count());
xml_output(pxml,"rsp-version",RSP_VERSION);
xml_output(pxml,"server-version",infn->server_ver());
xml_output(pxml,"server-version",_ppi->server_ver());
size = sizeof(servername);
infn->server_name(servername,&size);
_ppi->server_name(servername,&size);
xml_output(pxml,"name",servername);
xml_pop(pxml); /* info */
@@ -285,9 +287,9 @@ void rsp_db(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
ppi->dq.query_type = QUERY_TYPE_PLAYLISTS;
if((err=infn->db_enum_start(&pe,&ppi->dq)) != 0) {
if((err=_ppi->db_enum_start(&pe,&ppi->dq)) != 0) {
rsp_error(pwsc, ppi, err | E_DB, pe);
infn->db_enum_dispose(NULL,&ppi->dq);
_ppi->db_enum_dispose(NULL,&ppi->dq);
return;
}
@@ -303,7 +305,7 @@ void rsp_db(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
xml_push(pxml,"playlists");
while((infn->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) {
while((_ppi->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) {
xml_push(pxml,"playlist");
rowindex=0;
while(rsp_playlist_fields[rowindex].name) {
@@ -316,8 +318,8 @@ void rsp_db(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
xml_pop(pxml); /* playlist */
}
infn->db_enum_end(NULL);
infn->db_enum_dispose(NULL,&ppi->dq);
_ppi->db_enum_end(NULL);
_ppi->db_enum_dispose(NULL,&ppi->dq);
xml_pop(pxml); /* playlists */
xml_pop(pxml); /* response */
@@ -343,7 +345,7 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
// char *user_agent;
/*
user_agent = infn->ws_getrequestheader(pwsc,"user-agent");
user_agent = _ppi->ws_getrequestheader(pwsc,"user-agent");
if(user_agent) {
if(strncmp(user_agent,"iTunes",6)==0) {
trancode_codecs = "wma,ogg,flac,mpc";
@@ -355,17 +357,17 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
}
*/
ppi->dq.filter = infn->ws_getvar(pwsc,"query");
ppi->dq.filter = _ppi->ws_getvar(pwsc,"query");
ppi->dq.filter_type = FILTER_TYPE_FIREFLY;
if(infn->ws_getvar(pwsc,"offset")) {
ppi->dq.offset = atoi(infn->ws_getvar(pwsc,"offset"));
if(_ppi->ws_getvar(pwsc,"offset")) {
ppi->dq.offset = atoi(_ppi->ws_getvar(pwsc,"offset"));
}
if(infn->ws_getvar(pwsc,"limit")) {
ppi->dq.limit = atoi(infn->ws_getvar(pwsc,"limit"));
if(_ppi->ws_getvar(pwsc,"limit")) {
ppi->dq.limit = atoi(_ppi->ws_getvar(pwsc,"limit"));
}
browse_type = infn->ws_getvar(pwsc,"type");
browse_type = _ppi->ws_getvar(pwsc,"type");
type = F_FULL;
if(browse_type) {
@@ -378,9 +380,9 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
ppi->dq.query_type = QUERY_TYPE_ITEMS;
ppi->dq.playlist_id = atoi(ppi->uri_sections[2]);
if((err=infn->db_enum_start(&pe,&ppi->dq)) != 0) {
if((err=_ppi->db_enum_start(&pe,&ppi->dq)) != 0) {
rsp_error(pwsc, ppi, err | E_DB, pe);
infn->db_enum_dispose(NULL,&ppi->dq);
_ppi->db_enum_dispose(NULL,&ppi->dq);
free(pe);
return;
}
@@ -395,7 +397,7 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
returned = ppi->dq.totalcount - ppi->dq.offset;
}
transcode_codecs = infn->conf_alloc_string("general","ssc_codectypes","");
transcode_codecs = _ppi->conf_alloc_string("general","ssc_codectypes","");
xml_push(pxml,"response");
xml_push(pxml,"status");
@@ -407,7 +409,7 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
xml_push(pxml,"items");
while((infn->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) {
while((_ppi->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) {
xml_push(pxml,"item");
rowindex=0;
transcode = 0;
@@ -453,8 +455,8 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
xml_pop(pxml); /* item */
}
infn->db_enum_end(NULL);
infn->conf_dispose_string(transcode_codecs);
_ppi->db_enum_end(NULL);
_ppi->conf_dispose_string(transcode_codecs);
xml_pop(pxml); /* items */
xml_pop(pxml); /* response */
@@ -471,22 +473,22 @@ void rsp_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
/* 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 = infn->ws_getvar(pwsc,"query");
ppi->dq.filter = _ppi->ws_getvar(pwsc,"query");
ppi->dq.filter_type = FILTER_TYPE_FIREFLY;
if(infn->ws_getvar(pwsc,"offset")) {
ppi->dq.offset = atoi(infn->ws_getvar(pwsc,"offset"));
if(_ppi->ws_getvar(pwsc,"offset")) {
ppi->dq.offset = atoi(_ppi->ws_getvar(pwsc,"offset"));
}
if(infn->ws_getvar(pwsc,"limit")) {
ppi->dq.limit = atoi(infn->ws_getvar(pwsc,"limit"));
if(_ppi->ws_getvar(pwsc,"limit")) {
ppi->dq.limit = atoi(_ppi->ws_getvar(pwsc,"limit"));
}
ppi->dq.playlist_id = atoi(ppi->uri_sections[2]);
if((err=infn->db_enum_start(&pe,&ppi->dq)) != 0) {
if((err=_ppi->db_enum_start(&pe,&ppi->dq)) != 0) {
rsp_error(pwsc, ppi, err | E_DB, pe);
infn->db_enum_dispose(NULL,&ppi->dq);
_ppi->db_enum_dispose(NULL,&ppi->dq);
return;
}
@@ -510,12 +512,12 @@ void rsp_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
xml_push(pxml,"items");
while((infn->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) {
while((_ppi->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) {
xml_output(pxml,"item",row[0]);
}
infn->db_enum_end(NULL);
infn->db_enum_dispose(NULL,&ppi->dq);
_ppi->db_enum_end(NULL);
_ppi->db_enum_dispose(NULL,&ppi->dq);
xml_pop(pxml); /* items */
xml_pop(pxml); /* response */
@@ -523,7 +525,7 @@ void rsp_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
}
void rsp_stream(WS_CONNINFO *pwsc, PRIVINFO *ppi) {
infn->stream(pwsc, ppi->uri_sections[2]);
_ppi->stream(pwsc, ppi->uri_sections[2]);
return;
}
@@ -540,6 +542,6 @@ void rsp_error(WS_CONNINFO *pwsc, PRIVINFO *ppi, int eno, char *estr) {
xml_pop(pxml); /* status */
xml_pop(pxml); /* response */
xml_deinit(pxml);
infn->ws_close(pwsc);
_ppi->ws_close(pwsc);
}

View File

@@ -8,7 +8,6 @@
#define RSP_VERSION "1.0"
extern PLUGIN_INFO _pi;
#define infn ((PLUGIN_INPUT_FN *)(_pi.pi))
#ifndef TRUE
# define TRUE 1

View File

@@ -40,6 +40,8 @@ typedef struct tag_ssc_handle {
int buf_remainder_len;
int first_frame;
int duration;
int total_decoded;
int total_written;
@@ -64,19 +66,27 @@ typedef struct tag_ssc_handle {
#define SSC_FFMPEG_E_FILEOPEN 3
#define SSC_FFMPEG_E_NOSTREAM 4
#define SSC_FFMPEG_E_NOAUDIO 5
#define SSC_FFMPEG_E_BADFORMAT 6
char *ssc_ffmpeg_errors[] = {
"Success",
"Don't have appropriate codec",
"Can't open codec",
"Cannot open file",
"Cannot find any streams",
"No audio streams"
};
/* Forwards */
void *ssc_ffmpeg_init(void);
void ssc_ffmpeg_deinit(void *pv);
int ssc_ffmpeg_open(void *pv, char *file, char *codec);
int ssc_ffmpeg_open(void *pv, char *file, char *codec, int duration);
int ssc_ffmpeg_close(void *pv);
int ssc_ffmpeg_read(void *pv, char *buffer, int len);
char *ssc_ffmpeg_error(void *pv);
PLUGIN_INFO *plugin_info(void);
#define infn ((PLUGIN_INPUT_FN *)(_pi.pi))
PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN*);
/* Globals */
PLUGIN_TRANSCODE_FN _ptfn = {
@@ -84,9 +94,12 @@ PLUGIN_TRANSCODE_FN _ptfn = {
ssc_ffmpeg_deinit,
ssc_ffmpeg_open,
ssc_ffmpeg_close,
ssc_ffmpeg_read
ssc_ffmpeg_read,
ssc_ffmpeg_error
};
PLUGIN_INPUT_FN *_ppi;
PLUGIN_INFO _pi = {
PLUGIN_VERSION, /* version */
PLUGIN_TRANSCODE, /* type */
@@ -95,12 +108,18 @@ PLUGIN_INFO _pi = {
NULL, /* output fns */
NULL, /* event fns */
&_ptfn, /* fns */
NULL, /* functions exported by ff */
NULL, /* rend info */
"flac,alac,ogg,wma" /* codeclist */
};
PLUGIN_INFO *plugin_info(void) {
char *ssc_ffmpeg_error(void *pv) {
SSCHANDLE *handle = (SSCHANDLE*)pv;
return ssc_ffmpeg_errors[handle->errno];
}
PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) {
_ppi = ppi;
av_register_all();
return &_pi;
@@ -127,7 +146,7 @@ void ssc_ffmpeg_deinit(void *vp) {
return;
}
int ssc_ffmpeg_open(void *vp, char *file, char *codec) {
int ssc_ffmpeg_open(void *vp, char *file, char *codec, int duration) {
int i;
enum CodecID id=CODEC_ID_FLAC;
SSCHANDLE *handle = (SSCHANDLE*)vp;
@@ -135,10 +154,11 @@ int ssc_ffmpeg_open(void *vp, char *file, char *codec) {
if(!handle)
return FALSE;
handle->duration = duration;
handle->first_frame = 1;
handle->raw=0;
infn->log(E_DBG,"opening %s\n",file);
_ppi->log(E_DBG,"opening %s\n",file);
if(strcasecmp(codec,"flac") == 0) {
handle->raw=1;
@@ -146,6 +166,7 @@ int ssc_ffmpeg_open(void *vp, char *file, char *codec) {
}
if(handle->raw) {
_ppi->log(E_DBG,"opening file raw\n");
handle->pCodec = avcodec_find_decoder(id);
if(!handle->pCodec) {
handle->errno = SSC_FFMPEG_E_BADCODEC;
@@ -166,7 +187,8 @@ int ssc_ffmpeg_open(void *vp, char *file, char *codec) {
return TRUE;
}
_ppi->log(E_DBG,"opening file with format\n");
if(av_open_input_file(&handle->pFmtCtx,file,handle->pFormat,0,NULL) < 0) {
handle->errno = SSC_FFMPEG_E_FILEOPEN;
return FALSE;
@@ -178,7 +200,7 @@ int ssc_ffmpeg_open(void *vp, char *file, char *codec) {
return FALSE;
}
dump_format(handle->pFmtCtx,0,file,FALSE);
// dump_format(handle->pFmtCtx,0,file,FALSE);
handle->audio_stream = -1;
for(i=0; i < handle->pFmtCtx->nb_streams; i++) {
@@ -226,8 +248,10 @@ int ssc_ffmpeg_close(void *vp) {
if(handle->pFrame)
av_free(handle->pFrame);
if(handle->pCodecCtx)
avcodec_close(handle->pCodecCtx);
if(handle->raw) {
if(handle->pCodecCtx)
avcodec_close(handle->pCodecCtx);
}
if(handle->pFmtCtx)
av_close_input_file(handle->pFmtCtx);
@@ -393,14 +417,17 @@ int ssc_ffmpeg_read(void *vp, char *buffer, int len) {
handle->swab = (bits_per_sample == 16) &&
(memcmp((void*)&test1,test2,2) == 0);
data_len = (bits_per_sample * sample_rate * channels * (duration/1000));
if(handle->duration)
duration = handle->duration;
data_len = ((bits_per_sample * sample_rate * channels / 8) * (duration/1000));
byte_rate = sample_rate * channels * bits_per_sample / 8;
block_align = channels * bits_per_sample / 8;
infn->log(E_DBG,"Channels.......: %d\n",channels);
infn->log(E_DBG,"Sample rate....: %d\n",sample_rate);
infn->log(E_DBG,"Bits/Sample....: %d\n",bits_per_sample);
infn->log(E_DBG,"Swab...........: %d\n",handle->swab);
_ppi->log(E_DBG,"Channels.......: %d\n",channels);
_ppi->log(E_DBG,"Sample rate....: %d\n",sample_rate);
_ppi->log(E_DBG,"Bits/Sample....: %d\n",bits_per_sample);
_ppi->log(E_DBG,"Swab...........: %d\n",handle->swab);
memcpy(&handle->wav_header[0],"RIFF",4);
_ssc_ffmpeg_le32(&handle->wav_header[4],36 + data_len);

206
src/plugins/ssc-script.c Normal file
View File

@@ -0,0 +1,206 @@
/*
* $Id: $
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ff-plugins.h"
#ifndef TRUE
# define TRUE 1
# define FALSE 0
#endif
/* Forwards */
void *ssc_script_init(void);
void ssc_script_deinit(void *vp);
int ssc_script_open(void *vp, char *file, char *codec, int duration);
int ssc_script_close(void *vp);
int ssc_script_read(void *vp, char *buffer, int len);
char *ssc_script_error(void *vp);
PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *);
#define infn ((PLUGIN_INPUT_FN *)(_pi.pi))
/* Globals */
PLUGIN_TRANSCODE_FN _ptfn = {
ssc_script_init,
ssc_script_deinit,
ssc_script_open,
ssc_script_close,
ssc_script_read,
ssc_script_error
};
PLUGIN_INPUT_FN *_ppi;
PLUGIN_INFO _pi = {
PLUGIN_VERSION, /* version */
PLUGIN_TRANSCODE, /* type */
"ssc-script/" VERSION, /* server */
NULL, /* url */
NULL, /* output fns */
NULL, /* event fns */
&_ptfn, /* fns */
NULL, /* rend info */
NULL /* codeclist */
};
typedef struct tag_ssc_handle {
FILE *fin;
} SSCHANDLE;
static char *_ssc_script_program = NULL;
/**
* return the plugininfo struct to firefly
*/
PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) {
char *codeclist;
_ppi = ppi;
_ssc_script_program = _ppi->conf_alloc_string("general","ssc_prog",NULL);
if(!_ssc_script_program) {
_ppi->log(E_INF,"No ssc program specified for script transcoder.\n");
return NULL;
}
/* FIXME: need an unload function to stop leak */
codeclist = _ppi->conf_alloc_string("general","ssc_codectypes",NULL);
if(!codeclist) {
_ppi->log(E_INF,"No codectypes specified for script transcoder.\n");
return NULL;
}
_pi.codeclist = codeclist;
return &_pi;
}
/*
* get a new transcode handle
*/
void *ssc_script_init(void) {
SSCHANDLE *handle;
handle = (SSCHANDLE*)malloc(sizeof(SSCHANDLE));
if(handle) {
memset(handle,0,sizeof(SSCHANDLE));
}
return (void*)handle;
}
/**
* FIXME: make register errors in the sschandle
*/
char *ssc_script_error(void *vp) {
SSCHANDLE *handle = (SSCHANDLE*)vp;
return "Unknown";
}
/**
* dispose of the transocde handle obtained from init
*
* @param pv handle to dispose
*/
void ssc_script_deinit(void *vp) {
SSCHANDLE *handle = (SSCHANDLE*)vp;
if(handle->fin) {
pclose(handle->fin);
}
if(handle)
free(handle);
}
/**
* open a file to transocde
*
* @param pv private sschandle obtained from init
* @param file file name to transcode
* @param codec codec type
* @param duration duration in ms
*/
int ssc_script_open(void *vp, char *file, char *codec, int duration) {
SSCHANDLE *handle = (SSCHANDLE*)vp;
char *cmd;
char *newpath;
char *metachars = "\"\\!(){}#*?$&<>`"; /* More?? */
char metacount = 0;
char *src,*dst;
src=file;
while(*src) {
if(strchr(metachars,*src))
metacount+=5;
src++;
}
if(metachars) {
newpath = (char*)malloc(strlen(file) + metacount + 1);
if(!newpath) {
_ppi->log(E_FATAL,"ssc_script_open: malloc\n");
}
src=file;
dst=newpath;
while(*src) {
if(strchr(metachars,*src)) {
*dst++='"';
*dst++='\'';
*dst++=*src++;
*dst++='\'';
*dst++='"';
} else {
*dst++=*src++;
}
}
*dst='\0';
} else {
newpath = strdup(file); /* becuase it will be freed... */
}
/* FIXME: is 64 enough? is there a better way to determine this? */
cmd=(char *)malloc(strlen(_ssc_script_program) +
strlen(file) +
64);
sprintf(cmd, "%s \"%s\" 0 %lu.%03lu \"%s\"",
_ssc_script_program, newpath, (unsigned long) duration / 1000,
(unsigned long)duration % 1000, (codec && *codec) ? codec : "*");
_ppi->log(E_INF,"Executing %s\n",cmd);
handle->fin = popen(cmd, "r");
free(newpath);
free(cmd); /* should really have in-place expanded the path */
return TRUE;
}
int ssc_script_close(void *vp) {
SSCHANDLE *handle = (SSCHANDLE*)vp;
if(handle->fin) {
pclose(handle->fin);
handle->fin=NULL;
}
return TRUE;
}
int ssc_script_read(void *vp, char *buffer, int len) {
SSCHANDLE *handle = (SSCHANDLE*)vp;
return fread(buffer,1,len,handle->fin);
}

View File

@@ -41,6 +41,8 @@ struct tag_xmlstruct {
XML_STREAMBUFFER *psb;
};
extern PLUGIN_INPUT_FN *_ppi;
/* Forwards */
void xml_get_stats(WS_CONNINFO *pwsc);
void xml_set_config(WS_CONNINFO *pwsc);
@@ -62,7 +64,7 @@ void xml_write(XMLSTRUCT *pxml, char *fmt, ...) {
if(pxml->psb) {
xml_stream_write(pxml, buffer);
} else {
infn->ws_writefd(pxml->pwsc,"%s",buffer);
_ppi->ws_writefd(pxml->pwsc,"%s",buffer);
}
}
@@ -89,14 +91,14 @@ XML_STREAMBUFFER *xml_stream_open(void) {
psb = (XML_STREAMBUFFER*) malloc(sizeof(XML_STREAMBUFFER));
if(!psb) {
infn->log(E_FATAL,"xml_stream_open: malloc\n");
_ppi->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)) {
infn->log(E_FATAL,"xml_stream_open: malloc\n");
_ppi->log(E_FATAL,"xml_stream_open: malloc\n");
}
psb->strm.zalloc = Z_NULL;
@@ -134,9 +136,9 @@ int xml_stream_write(XMLSTRUCT *pxml, char *out) {
while(!done) {
result = deflate(&psb->strm, Z_NO_FLUSH);
if(result != Z_OK) {
infn->log(E_FATAL,"Error in zlib: %d\n",result);
_ppi->log(E_FATAL,"Error in zlib: %d\n",result);
}
infn->ws_writebinary(pxml->pwsc,(char*)psb->out_buffer,
_ppi->ws_writebinary(pxml->pwsc,(char*)psb->out_buffer,
XML_STREAM_BLOCK-psb->strm.avail_out);
if(psb->strm.avail_out != 0) {
done=1;
@@ -163,14 +165,14 @@ int xml_stream_close(XMLSTRUCT *pxml) {
psb->strm.next_in = psb->in_buffer;
deflate(&psb->strm,Z_FINISH);
infn->ws_writebinary(pxml->pwsc,(char*)psb->out_buffer,
_ppi->ws_writebinary(pxml->pwsc,(char*)psb->out_buffer,
XML_STREAM_BLOCK - psb->strm.avail_out);
if(psb->strm.avail_out != 0)
done=1;
}
infn->log(E_DBG,"Done sending xml stream\n");
_ppi->log(E_DBG,"Done sending xml stream\n");
deflateEnd(&psb->strm);
if(psb->out_buffer != NULL)
free(psb->out_buffer);
@@ -196,7 +198,7 @@ XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header) {
pxml=(XMLSTRUCT*)malloc(sizeof(XMLSTRUCT));
if(!pxml) {
infn->log(E_FATAL,"Malloc error\n");
_ppi->log(E_FATAL,"Malloc error\n");
}
memset(pxml,0,sizeof(XMLSTRUCT));
@@ -204,27 +206,27 @@ XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header) {
pxml->pwsc = pwsc;
/* should we compress output? */
nogzip = infn->ws_getvar(pwsc,"nogzip");
accept = infn->ws_getrequestheader(pwsc,"accept-encoding");
nogzip = _ppi->ws_getvar(pwsc,"nogzip");
accept = _ppi->ws_getrequestheader(pwsc,"accept-encoding");
if((!nogzip) && (accept) && (strcasestr(accept,"gzip"))) {
infn->log(E_DBG,"Gzipping output\n");
_ppi->log(E_DBG,"Gzipping output\n");
pxml->psb = xml_stream_open();
if(pxml->psb) {
infn->ws_addresponseheader(pwsc,"Content-Encoding","gzip");
infn->ws_addresponseheader(pwsc,"Vary","Accept-Encoding");
infn->ws_addresponseheader(pwsc,"Connection","Close");
_ppi->ws_addresponseheader(pwsc,"Content-Encoding","gzip");
_ppi->ws_addresponseheader(pwsc,"Vary","Accept-Encoding");
_ppi->ws_addresponseheader(pwsc,"Connection","Close");
}
}
/* the world would be a wonderful place without ie */
infn->ws_addresponseheader(pwsc,"Cache-Control","no-cache");
infn->ws_addresponseheader(pwsc,"Expires","-1");
_ppi->ws_addresponseheader(pwsc,"Cache-Control","no-cache");
_ppi->ws_addresponseheader(pwsc,"Expires","-1");
if(emit_header) {
infn->ws_addresponseheader(pwsc,"Content-Type","text/xml; charset=utf-8");
infn->ws_writefd(pwsc,"HTTP/1.0 200 OK\r\n");
infn->ws_emitheaders(pwsc);
_ppi->ws_addresponseheader(pwsc,"Content-Type","text/xml; charset=utf-8");
_ppi->ws_writefd(pwsc,"HTTP/1.0 200 OK\r\n");
_ppi->ws_emitheaders(pwsc);
xml_write(pxml,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
@@ -263,7 +265,7 @@ void xml_pop(XMLSTRUCT *pxml) {
pstack=pxml->stack.next;
if(!pstack) {
infn->log(E_LOG,"xml_pop: tried to pop an empty stack\n");
_ppi->log(E_LOG,"xml_pop: tried to pop an empty stack\n");
return;
}
@@ -310,7 +312,7 @@ void xml_deinit(XMLSTRUCT *pxml) {
XMLSTACK *pstack;
if(pxml->stack.next) {
infn->log(E_LOG,"xml_deinit: entries still on stack (%s)\n",
_ppi->log(E_LOG,"xml_deinit: entries still on stack (%s)\n",
pxml->stack.next->tag);
}