diff --git a/configure.in b/configure.in index bdb17a0b..45a4c7d0 100644 --- a/configure.in +++ b/configure.in @@ -23,6 +23,8 @@ AC_CHECK_HEADERS([dirent.h]) AC_CHECK_FUNCS(strptime) AC_CHECK_FUNCS(strtok_r) AC_CHECK_FUNCS(timegm) +AC_CHECK_FUNCS(va_copy) +AC_CHECK_FUNCS(__va_copy) AM_CONDITIONAL(COND_REND_OSX,false) diff --git a/src/Makefile.am b/src/Makefile.am index 42a0c110..d52afdf0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -64,7 +64,7 @@ wavstreamer_SOURCES = wavstreamer.c mt_daapd_SOURCES = main.c daapd.h rend.h webserver.c \ webserver.h configfile.c configfile.h err.c err.h restart.c restart.h \ mp3-scanner.h mp3-scanner.c rend-unix.h \ - db-generic.c db-generic.h \ + db-generic.c db-generic.h ff-plugins.c ff-plugins.h \ rxml.c rxml.h redblack.c redblack.h scan-mp3.c scan-mp4.c scan-aif.c \ scan-xml.c scan-wma.c scan-aac.c scan-aac.h scan-wav.c scan-url.c \ smart-parser.c smart-parser.h xml-rpc.c xml-rpc.h \ diff --git a/src/daapd.h b/src/daapd.h index 1b6a0092..3a3cc273 100644 --- a/src/daapd.h +++ b/src/daapd.h @@ -39,6 +39,20 @@ # include #endif +#ifdef DEBUG +# ifndef ASSERT +# define ASSERT(f) \ + if(f) \ + {} \ + else \ + err_log(0,"Assert error in %s, line %d\n",__FILE__,__LINE__) +# endif /* ndef ASSERT */ +#else /* ndef DEBUG */ +# ifndef ASSERT +# define ASSERT(f) +# endif +#endif + #include #include "memdebug.h" /* redefine free/malloc/etc */ #include "compat.h" diff --git a/src/ff-plugins.h b/src/ff-plugins.h index 32752404..b7ecca01 100644 --- a/src/ff-plugins.h +++ b/src/ff-plugins.h @@ -24,6 +24,13 @@ #include "ff-dbstruct.h" +#ifdef WIN32 +# define EXPORT __declspec(dllimport) +#else +# define EXPORT +#endif + + #ifndef TRUE #define TRUE 1 #define FALSE 0 @@ -122,51 +129,49 @@ typedef struct tag_db_query { void *priv; } DB_QUERY; +/* webserver functions */ +extern EXPORT EXPORT char *pi_ws_uri(struct tag_ws_conninfo *); +extern EXPORT EXPORT void pi_ws_will_close(struct tag_ws_conninfo *); +extern EXPORT EXPORT int pi_ws_returnerror(struct tag_ws_conninfo *, int, char *); +extern EXPORT char *pi_ws_getvar(struct tag_ws_conninfo *, char *); +extern EXPORT int pi_ws_writefd(struct tag_ws_conninfo *, char *, ...); +extern EXPORT int pi_ws_addresponseheader(struct tag_ws_conninfo *, char *, char *, ...); +extern EXPORT void pi_ws_emitheaders(struct tag_ws_conninfo *); +extern EXPORT char *pi_ws_getrequestheader(struct tag_ws_conninfo *, char *); +extern EXPORT int pi_ws_writebinary(struct tag_ws_conninfo *, char *, int); +extern EXPORT char *pi_ws_gethostname(struct tag_ws_conninfo *); +extern EXPORT int pi_ws_matchesrole(struct tag_ws_conninfo *, char *, char *, char *); -/* version 1 plugin imports */ -typedef struct tag_plugin_input_fn { - /* webserver helpers */ - char* (*ws_uri)(struct tag_ws_conninfo *); - void (*ws_will_close)(struct tag_ws_conninfo *); - int (*ws_returnerror)(struct tag_ws_conninfo *, int, char *); - char* (*ws_getvar)(struct tag_ws_conninfo *, char *); - int (*ws_writefd)(struct tag_ws_conninfo *, char *, ...); - int (*ws_addresponseheader)(struct tag_ws_conninfo *, char *, char *, ...); - void (*ws_emitheaders)(struct tag_ws_conninfo *); - char* (*ws_getrequestheader)(struct tag_ws_conninfo *, char *); - int (*ws_writebinary)(struct tag_ws_conninfo *, char *, int); - char* (*ws_gethostname)(struct tag_ws_conninfo *); - int (*ws_matchesrole)(struct tag_ws_conninfo *, char *, char *, char *); +/* misc helpers */ +extern EXPORT char *pi_server_ver(void); +extern EXPORT int pi_server_name(char *, int *); +extern EXPORT void pi_log(int, char *, ...); +extern EXPORT int pi_should_transcode(struct tag_ws_conninfo *, char *); - /* misc helpers */ - char* (*server_ver)(void); - int (*server_name)(char *, int *); - void (*log)(int, char *, ...); - int (*should_transcode)(struct tag_ws_conninfo *, char *); +/* db functions */ +extern EXPORT int pi_db_count(void); +extern EXPORT int pi_db_enum_start(char **, DB_QUERY *); +extern EXPORT int pi_db_enum_fetch_row(char **, char ***, DB_QUERY *); +extern EXPORT int pi_db_enum_end(char **); +extern EXPORT int pi_db_enum_restart(char **, DB_QUERY *); +extern EXPORT void pi_db_enum_dispose(char **, DB_QUERY*); +extern EXPORT void pi_stream(struct tag_ws_conninfo *, char *); - int (*db_count)(void); - int (*db_enum_start)(char **, DB_QUERY *); - int (*db_enum_fetch_row)(char **, char ***, DB_QUERY *); - int (*db_enum_end)(char **); - int (*db_enum_restart)(char **, DB_QUERY *); - void (*db_enum_dispose)(char **, DB_QUERY*); - void (*stream)(struct tag_ws_conninfo *, char *); +extern EXPORT int pi_db_add_playlist(char **pe, char *name, int type, char *clause, char *path, int index, int *playlistid); +extern EXPORT int pi_db_add_playlist_item(char **pe, int playlistid, int songid); +extern EXPORT int pi_db_edit_playlist(char **pe, int id, char *name, char *clause); +extern EXPORT int pi_db_delete_playlist(char **pe, int playlistid); +extern EXPORT int pi_db_delete_playlist_item(char **pe, int playlistid, int songid); +extern EXPORT int pi_db_revision(void); +extern EXPORT int pi_db_count_items(int what); +extern EXPORT int pi_db_wait_update(struct tag_ws_conninfo *); - int (*db_add_playlist)(char **pe, char *name, int type, char *clause, char *path, int index, int *playlistid); - int (*db_add_playlist_item)(char **pe, int playlistid, int songid); - int (*db_edit_playlist)(char **pe, int id, char *name, char *clause); - int (*db_delete_playlist)(char **pe, int playlistid); - int (*db_delete_playlist_item)(char **pe, int playlistid, int songid); - int (*db_revision)(void); - int (*db_count_items)(int what); - int (*db_wait_update)(struct tag_ws_conninfo *); +/* config/misc functions */ +extern EXPORT char *pi_conf_alloc_string(char *section, char *key, char *dflt); +extern EXPORT void pi_conf_dispose_string(char *str); +extern EXPORT int pi_conf_get_int(char *section, char *key, int dflt); - char *(*conf_alloc_string)(char *section, char *key, char *dflt); - void (*conf_dispose_string)(char *str); - int (*conf_get_int)(char *section, char *key, int dflt); - - void (*config_set_status)(struct tag_ws_conninfo *pwsc, int session, char *fmt, ...); -} PLUGIN_INPUT_FN; +extern EXPORT void pi_config_set_status(struct tag_ws_conninfo *pwsc, int session, char *fmt, ...); #endif /* _FF_PLUGINS_ */ diff --git a/src/plugin.c b/src/plugin.c index 6d4a12d2..87fa245d 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -92,74 +92,6 @@ void _plugin_free(int *pi); void _plugin_recalc_codecs(void); int _plugin_ssc_transcode(WS_CONNINFO *pwsc, MP3FILE *pmp3, int offset, int headers); -/* webserver helpers */ -void pi_ws_will_close(WS_CONNINFO *pwsc); -int pi_ws_fd(WS_CONNINFO *pwsc); -char *pi_ws_gethostname(WS_CONNINFO *pwsc); - -/* misc helpers */ -char *pi_server_ver(void); -int pi_server_name(char *, int *); -void pi_log(int, char *, ...); - -/* db helpers */ -int pi_db_count(void); -int pi_db_enum_start(char **pe, DB_QUERY *pinfo); -int pi_db_enum_fetch_row(char **pe, char ***row, DB_QUERY *pinfo); -int pi_db_enum_end(char **pe); -int pi_db_enum_restart(char **pe, DB_QUERY *pinfo); -void pi_db_enum_dispose(char **pe, DB_QUERY *pinfo); -void pi_stream(WS_CONNINFO *pwsc, char *id); -int pi_db_count_items(int what); -int pi_db_wait_update(WS_CONNINFO *pwsc); -void pi_conf_dispose_string(char *str); - -/* transcode helpers */ -int pi_ssc_should_transcode(WS_CONNINFO *pwsc, char *codec); - -PLUGIN_INPUT_FN pi = { - ws_uri, - pi_ws_will_close, - ws_returnerror, - ws_getvar, - ws_writefd, - ws_addresponseheader, - ws_emitheaders, - ws_getrequestheader, - ws_writebinary, - pi_ws_gethostname, - config_matches_role, - - pi_server_ver, - pi_server_name, - pi_log, - pi_ssc_should_transcode, - - pi_db_count, - pi_db_enum_start, - pi_db_enum_fetch_row, - pi_db_enum_end, - pi_db_enum_restart, - pi_db_enum_dispose, - pi_stream, - - db_add_playlist, - db_add_playlist_item, - db_edit_playlist, - db_delete_playlist, - db_delete_playlist_item, - db_revision, - pi_db_count_items, - pi_db_wait_update, - - conf_alloc_string, - pi_conf_dispose_string, - conf_get_int, - - config_set_status -}; - - /** * initialize stuff for plugins * @@ -294,7 +226,7 @@ void *plugin_enum(void *where) { int plugin_load(char **pe, char *path) { PLUGIN_ENTRY *ppi; void *phandle; - PLUGIN_INFO *(*info_func)(PLUGIN_INPUT_FN *); + PLUGIN_INFO *(*info_func)(void); PLUGIN_INFO *pinfo; DPRINTF(E_DBG,L_PLUG,"Attempting to load plugin %s\n",path); @@ -310,7 +242,7 @@ int plugin_load(char **pe, char *path) { ppi->phandle = phandle; - info_func = (PLUGIN_INFO*(*)(PLUGIN_INPUT_FN*)) os_libfunc(pe, phandle,"plugin_info"); + info_func = (PLUGIN_INFO*(*)(void)) os_libfunc(pe, phandle,"plugin_info"); if(info_func == NULL) { DPRINTF(E_INF,L_PLUG,"Couldn't get info_func for %s\n",path); os_unload(phandle); @@ -318,7 +250,7 @@ int plugin_load(char **pe, char *path) { return PLUGIN_E_BADFUNCS; } - pinfo = info_func(&pi); + pinfo = info_func(); ppi->pinfo = pinfo; if(!pinfo) { @@ -486,25 +418,137 @@ void plugin_event_dispatch(int event_id, int intval, void *vp, int len) { } } + /** - * check to see if we can transcode - * - * @param codec the codec we are trying to serve - * @returns TRUE if we can transcode, FALSE otherwise + * stupid helper to copy transcode stream to the fd */ -int pi_ssc_should_transcode(WS_CONNINFO *pwsc, char *codec) { +int __plugin_ssc_copy(WS_CONNINFO *pwsc, PLUGIN_TRANSCODE_FN *pfn, + void *vp,int offset) { + int bytes_read; + int bytes_to_read; + int total_bytes_read = 0; + char buffer[1024]; + + /* first, skip past the offset */ + while(offset) { + bytes_to_read = sizeof(buffer); + if(bytes_to_read > offset) + bytes_to_read = offset; + + bytes_read = pfn->ssc_read(vp,buffer,bytes_to_read); + if(bytes_read <= 0) + return bytes_read; + + offset -= bytes_read; + } + + while((bytes_read=pfn->ssc_read(vp,buffer,sizeof(buffer))) > 0) { + total_bytes_read += bytes_read; + if(ws_writebinary(pwsc,buffer,bytes_read) != bytes_read) { + return total_bytes_read; + } + } + + /* + if(bytes_read < 0) { + return bytes_read; + } + */ + + return total_bytes_read; +} + +/** + * do the transcode, emitting the headers, content type, + * and shoving the file down the wire + * + * @param pwsc connection to transcode to + * @param file file to transcode + * @param codec source codec + * @param duration time in ms + * @returns bytes transferred, or -1 on error + */ +int plugin_ssc_transcode(WS_CONNINFO *pwsc, MP3FILE *pmp3, int offset, int headers) { + PLUGIN_ENTRY *ppi, *ptc=NULL; + PLUGIN_TRANSCODE_FN *pfn = NULL; + void *vp_ssc; + int post_error = 1; + int result = -1; + + /* first, find the plugin that will do the conversion */ + ppi = _plugin_list.next; + while((ppi) && (!pfn)) { + if(ppi->pinfo->type & PLUGIN_TRANSCODE) { + if(strstr(ppi->pinfo->codeclist,pmp3->codectype)) { + ptc = ppi; + pfn = ppi->pinfo->transcode_fns; + } + } + ppi = ppi->next; + } + + if(pfn) { + DPRINTF(E_DBG,L_PLUG,"Transcoding %s with %s\n",pmp3->path, + ptc->pinfo->server); + + vp_ssc = pfn->ssc_init(); + if(vp_ssc) { + if(pfn->ssc_open(vp_ssc,pmp3)) { + /* start reading and throwing */ + if(headers) { + ws_addresponseheader(pwsc,"Content-Type","audio/wav"); + ws_addresponseheader(pwsc,"Connection","Close"); + if(!offset) { + ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n"); + } else { + ws_addresponseheader(pwsc,"Content-Range", + "bytes %ld-*/*", + (long)offset); + ws_writefd(pwsc,"HTTP/1.1 206 Partial Content\r\n"); + } + ws_emitheaders(pwsc); + } + + /* start reading/writing */ + result = __plugin_ssc_copy(pwsc,pfn,vp_ssc,offset); + post_error = 0; + pfn->ssc_close(vp_ssc); + } else { + DPRINTF(E_LOG,L_PLUG,"Error opening %s for ssc: %s\n", + pmp3->path,pfn->ssc_error(vp_ssc)); + } + pfn->ssc_deinit(vp_ssc); + } else { + DPRINTF(E_LOG,L_PLUG,"Error initializing transcoder: %s\n", + ptc->pinfo->server); + } + } + + if(post_error) { + pwsc->error = EPERM; /* ?? */ + ws_returnerror(pwsc,500,"Internal error"); + } + + return result; +} + +int plugin_ssc_should_transcode(WS_CONNINFO *pwsc, char *codec) { int result; char *native_codecs=NULL; char *user_agent=NULL; char *never_transcode = NULL; char *always_transcode = NULL; + ASSERT((pwsc) && (codec)); + + if(!pwsc) + return FALSE; + if(!codec) { DPRINTF(E_LOG,L_PLUG,"testing transcode on null codec?\n"); return FALSE; } - never_transcode = conf_alloc_string("general","never_transcode",NULL); if(never_transcode) { if(strstr(never_transcode,codec)) { @@ -558,462 +602,3 @@ int pi_ssc_should_transcode(WS_CONNINFO *pwsc, char *codec) { return result; } - -/** - * stupid helper to copy transcode stream to the fd - */ -int _plugin_ssc_copy(WS_CONNINFO *pwsc, PLUGIN_TRANSCODE_FN *pfn, - void *vp,int offset) { - int bytes_read; - int bytes_to_read; - int total_bytes_read = 0; - char buffer[1024]; - - /* first, skip past the offset */ - while(offset) { - bytes_to_read = sizeof(buffer); - if(bytes_to_read > offset) - bytes_to_read = offset; - - bytes_read = pfn->ssc_read(vp,buffer,bytes_to_read); - if(bytes_read <= 0) - return bytes_read; - - offset -= bytes_read; - } - - while((bytes_read=pfn->ssc_read(vp,buffer,sizeof(buffer))) > 0) { - total_bytes_read += bytes_read; - if(ws_writebinary(pwsc,buffer,bytes_read) != bytes_read) { - return total_bytes_read; - } - } - - /* - if(bytes_read < 0) { - return bytes_read; - } - */ - - return total_bytes_read; -} - -/** - * do the transcode, emitting the headers, content type, - * and shoving the file down the wire - * - * @param pwsc connection to transcode to - * @param file file to transcode - * @param codec source codec - * @param duration time in ms - * @returns bytes transferred, or -1 on error - */ -int _plugin_ssc_transcode(WS_CONNINFO *pwsc, MP3FILE *pmp3, int offset, int headers) { - PLUGIN_ENTRY *ppi, *ptc=NULL; - PLUGIN_TRANSCODE_FN *pfn = NULL; - void *vp_ssc; - int post_error = 1; - int result = -1; - - /* first, find the plugin that will do the conversion */ - ppi = _plugin_list.next; - while((ppi) && (!pfn)) { - if(ppi->pinfo->type & PLUGIN_TRANSCODE) { - if(strstr(ppi->pinfo->codeclist,pmp3->codectype)) { - ptc = ppi; - pfn = ppi->pinfo->transcode_fns; - } - } - ppi = ppi->next; - } - - if(pfn) { - DPRINTF(E_DBG,L_PLUG,"Transcoding %s with %s\n",pmp3->path, - ptc->pinfo->server); - - vp_ssc = pfn->ssc_init(); - if(vp_ssc) { - if(pfn->ssc_open(vp_ssc,pmp3)) { - /* start reading and throwing */ - if(headers) { - ws_addresponseheader(pwsc,"Content-Type","audio/wav"); - ws_addresponseheader(pwsc,"Connection","Close"); - if(!offset) { - ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n"); - } else { - ws_addresponseheader(pwsc,"Content-Range", - "bytes %ld-*/*", - (long)offset); - ws_writefd(pwsc,"HTTP/1.1 206 Partial Content\r\n"); - } - ws_emitheaders(pwsc); - } - - /* start reading/writing */ - result = _plugin_ssc_copy(pwsc,pfn,vp_ssc,offset); - post_error = 0; - pfn->ssc_close(vp_ssc); - } else { - DPRINTF(E_LOG,L_PLUG,"Error opening %s for ssc: %s\n", - pmp3->path,pfn->ssc_error(vp_ssc)); - } - pfn->ssc_deinit(vp_ssc); - } else { - DPRINTF(E_LOG,L_PLUG,"Error initializing transcoder: %s\n", - ptc->pinfo->server); - } - } - - if(post_error) { - pwsc->error = EPERM; /* ?? */ - ws_returnerror(pwsc,500,"Internal error"); - } - - return result; -} - -/* plugin wrappers for utility functions & stuff - * - * these functions need to be wrapped so we can maintain a stable - * interface to older plugins even if we get newer functions or apis - * upstream... it's a binary compatibility layer. - */ -void pi_ws_will_close(WS_CONNINFO *pwsc) { - ws_should_close(pwsc,1); -} - -char *pi_ws_gethostname(WS_CONNINFO *pwsc) { - return ws_hostname(pwsc); -} - -void pi_log(int level, char *fmt, ...) { - char buf[256]; - va_list ap; - - va_start(ap,fmt); - vsnprintf(buf,sizeof(buf),fmt,ap); - va_end(ap); - - DPRINTF(level,L_PLUG,"%s",buf); -} - -char *pi_server_ver(void) { - return VERSION; -} - -int pi_server_name(char *name, int *len) { - char *servername; - - servername = conf_get_servername(); - if((servername) && (strlen(servername) < (size_t)len)) { - strcpy(name,servername); - } else { - if((size_t)len > strlen("Firefly Media Server")) - strcpy(name,"Firefly Media Server"); - } - - free(servername); - return CONF_E_SUCCESS; -} - -int pi_db_count(void) { - int count; - db_get_song_count(NULL, &count); - - return count; -} - -int pi_db_enum_start(char **pe, DB_QUERY *pinfo) { - DBQUERYINFO *pqi; - int result; - - pqi = (DBQUERYINFO*)malloc(sizeof(DBQUERYINFO)); - if(!pqi) { - if(pe) *pe = strdup("Malloc error"); - return DB_E_MALLOC; - } - memset(pqi,0,sizeof(DBQUERYINFO)); - pinfo->priv = (void*)pqi; - - if(pinfo->filter) { - pqi->pt = sp_init(); - if(!sp_parse(pqi->pt,pinfo->filter,pinfo->filter_type)) { - DPRINTF(E_LOG,L_PLUG,"Ignoring bad query (%s): %s\n", - pinfo->filter,sp_get_error(pqi->pt)); - sp_dispose(pqi->pt); - pqi->pt = NULL; - } - } - - if((pinfo->limit) || (pinfo->offset)) { - pqi->index_low = pinfo->offset; - pqi->index_high = pinfo->offset + pinfo->limit - 1; - if(pqi->index_high < pqi->index_low) - pqi->index_high = 9999999; - - pqi->index_type = indexTypeSub; - } else { - pqi->index_type = indexTypeNone; - } - - pqi->want_count = 1; - - switch(pinfo->query_type) { - case QUERY_TYPE_PLAYLISTS: - pqi->query_type = queryTypePlaylists; - break; - case QUERY_TYPE_DISTINCT: - if((strcmp(pinfo->distinct_field,"artist") == 0)) { - pqi->query_type = queryTypeBrowseArtists; - } else if((strcmp(pinfo->distinct_field,"genre") == 0)) { - pqi->query_type = queryTypeBrowseGenres; - } else if((strcmp(pinfo->distinct_field,"album") == 0)) { - pqi->query_type = queryTypeBrowseAlbums; - } else if((strcmp(pinfo->distinct_field,"composer") == 0)) { - pqi->query_type = queryTypeBrowseComposers; - } else { - if(pe) *pe = strdup("Unsupported browse type"); - if(pqi->pt) - sp_dispose(pqi->pt); - pqi->pt = NULL; - return -1; /* not really a db error for this */ - } - break; - case QUERY_TYPE_ITEMS: - default: - pqi->query_type = queryTypePlaylistItems; - pqi->correct_order = conf_get_int("scan","correct_order",1); - break; - } - - pqi->playlist_id = pinfo->playlist_id; - result = db_enum_start(pe, pqi); - pinfo->totalcount = pqi->specifiedtotalcount; - - return DB_E_SUCCESS; -} - -int pi_db_enum_fetch_row(char **pe, char ***row, DB_QUERY *pinfo) { - return db_enum_fetch_row(pe, (PACKED_MP3FILE*)row, - (DBQUERYINFO*)pinfo->priv); -} - -int pi_db_enum_end(char **pe) { - return db_enum_end(pe); -} - -/* FIXME: error checking */ -int pi_db_count_items(int what) { - int count=0; - - switch(what) { - case COUNT_SONGS: - db_get_song_count(NULL,&count); - break; - case COUNT_PLAYLISTS: - db_get_playlist_count(NULL,&count); - break; - } - - return count; -} - - -int pi_db_enum_restart(char **pe, DB_QUERY *pinfo) { - DBQUERYINFO *pqi; - - pqi = (DBQUERYINFO*)pinfo->priv; - return db_enum_reset(pe,pqi); -} - -void pi_db_enum_dispose(char **pe, DB_QUERY *pinfo) { - DBQUERYINFO *pqi; - - if(!pinfo) - return; - - if(pinfo->priv) { - pqi = (DBQUERYINFO *)pinfo->priv; - if(pqi->pt) { - sp_dispose(pqi->pt); - pqi->pt = NULL; - } - } -} - -int pi_db_wait_update(WS_CONNINFO *pwsc) { - int clientver=1; - int lastver=0; - IO_WAITHANDLE hwait; - uint32_t ms; - - if(ws_getvar(pwsc,"revision-number")) { - clientver=atoi(ws_getvar(pwsc,"revision-number")); - } - - /* wait for db_version to be stable for 30 seconds */ - hwait = io_wait_new(); - if(!hwait) - DPRINTF(E_FATAL,L_MISC,"Can't get wait handle in db_wait_update\n"); - - /* FIXME: Move this up into webserver to avoid groping around - * inside reserved data structures */ - - io_wait_add(hwait,pwsc->hclient,IO_WAIT_ERROR); - - while((clientver == db_revision()) || - (lastver && (db_revision() != lastver))) { - lastver = db_revision(); - - if(!io_wait(hwait,&ms) && (ms != 0)) { - /* can't be ready for read, must be error */ - DPRINTF(E_DBG,L_DAAP,"Update session stopped\n"); - io_wait_dispose(hwait); - return FALSE; - } - } - - io_wait_dispose(hwait); - - return TRUE; -} - -void pi_stream(WS_CONNINFO *pwsc, char *id) { - int session = 0; - MP3FILE *pmp3; - IOHANDLE hfile; - uint64_t bytes_copied=0; - uint64_t real_len; - uint64_t file_len; - uint64_t offset=0; - int item; - - /* stream out the song */ - ws_should_close(pwsc,1); - - item = atoi(id); - - if(ws_getrequestheader(pwsc,"range")) { - offset=(off_t)atol(ws_getrequestheader(pwsc,"range") + 6); - } - - /* FIXME: error handling */ - pmp3=db_fetch_item(NULL,item); - if(!pmp3) { - DPRINTF(E_LOG,L_DAAP|L_WS|L_DB,"Could not find requested item %lu\n",item); - config_set_status(pwsc,session,NULL); - ws_returnerror(pwsc,404,"File Not Found"); - } else if (pi_ssc_should_transcode(pwsc,pmp3->codectype)) { - /************************ - * Server side conversion - ************************/ - config_set_status(pwsc,session, - "Transcoding '%s' (id %d)", - pmp3->title,pmp3->id); - - DPRINTF(E_WARN,L_WS, - "Session %d: Streaming file '%s' to %s (offset %ld)\n", - session,pmp3->fname, ws_hostname(pwsc),(long)offset); - - /* estimate the real length of this thing */ - bytes_copied = _plugin_ssc_transcode(pwsc,pmp3,offset,1); - if(bytes_copied != -1) - real_len = bytes_copied; - - config_set_status(pwsc,session,NULL); - db_dispose_item(pmp3); - } else { - /********************** - * stream file normally - **********************/ - if(pmp3->data_kind != 0) { - ws_returnerror(pwsc,500,"Can't stream radio station"); - return; - } - - hfile = io_new(); - if(!hfile) - DPRINTF(E_FATAL,L_WS,"Cannot allocate file handle\n"); - - if(!io_open(hfile,"file://%U",pmp3->path)) { - /* FIXME: ws_set_errstr */ - ws_set_err(pwsc,E_WS_NATIVE); - DPRINTF(E_WARN,L_WS,"Thread %d: Error opening %s: %s\n", - ws_threadno(pwsc),pmp3->path,io_errstr(hfile)); - ws_returnerror(pwsc,404,"Not found"); - config_set_status(pwsc,session,NULL); - db_dispose_item(pmp3); - io_dispose(hfile); - } else { - io_size(hfile,&real_len); - file_len = real_len - offset; - - DPRINTF(E_DBG,L_WS,"Thread %d: Length of file (remaining): %lld\n", - ws_threadno(pwsc),file_len); - - // DWB: fix content-type to correctly reflect data - // content type (dmap tagged) should only be used on - // dmap protocol requests, not the actually song data - if(pmp3->type) - ws_addresponseheader(pwsc,"Content-Type","audio/%s",pmp3->type); - - ws_addresponseheader(pwsc,"Content-Length","%ld",(long)file_len); - - if((ws_getrequestheader(pwsc,"user-agent")) && - (!strncmp(ws_getrequestheader(pwsc,"user-agent"), - "Hifidelio",9))) { - ws_addresponseheader(pwsc,"Connection","Keep-Alive"); - ws_should_close(pwsc,0); - } else { - ws_addresponseheader(pwsc,"Connection","Close"); - } - - if(!offset) - ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n"); - else { - ws_addresponseheader(pwsc,"Content-Range","bytes %ld-%ld/%ld", - (long)offset,(long)real_len, - (long)real_len+1); - ws_writefd(pwsc,"HTTP/1.1 206 Partial Content\r\n"); - } - - ws_emitheaders(pwsc); - - config_set_status(pwsc,session,"Streaming '%s' (id %d)", - pmp3->title, pmp3->id); - DPRINTF(E_WARN,L_WS,"Session %d: Streaming file '%s' to %s (offset %d)\n", - session,pmp3->fname, ws_hostname(pwsc),(long)offset); - - if(offset) { - DPRINTF(E_INF,L_WS,"Seeking to offset %ld\n",(long)offset); - io_setpos(hfile,offset,SEEK_SET); - } - - if(!ws_copyfile(pwsc,hfile,&bytes_copied)) { - DPRINTF(E_INF,L_WS,"Error copying file to remote... %s\n", - strerror(errno)); - ws_should_close(pwsc,1); - } else { - DPRINTF(E_INF,L_WS,"Finished streaming file to remote: %lld bytes\n", - bytes_copied); - } - - config_set_status(pwsc,session,NULL); - io_close(hfile); - io_dispose(hfile); - db_dispose_item(pmp3); - } - /* update play counts */ - if(bytes_copied >= (real_len * 80 / 100)) { - db_playcount_increment(NULL,pmp3->id); - if(!offset) - config.stats.songs_served++; /* FIXME: remove stat races */ - } - } - - // free(pqi); -} - -void pi_conf_dispose_string(char *str) { - free(str); -} diff --git a/src/plugin.h b/src/plugin.h index d5678f94..bb721929 100644 --- a/src/plugin.h +++ b/src/plugin.h @@ -40,6 +40,9 @@ extern void plugin_event_dispatch(int event_id, int intval, void *vp, int len); extern void *plugin_enum(void *); extern char *plugin_get_description(void *); +extern int plugin_ssc_should_transcode(WS_CONNINFO *pwsc, char *codec); +extern int plugin_ssc_transcode(WS_CONNINFO *pwsc, MP3FILE *pmp3, int offset, int headers); + /* these should really get rows */ #define PLUGIN_E_SUCCESS 0 diff --git a/src/plugins/out-daap-proto.c b/src/plugins/out-daap-proto.c index dfe4a3c1..961af0b5 100644 --- a/src/plugins/out-daap-proto.c +++ b/src/plugins/out-daap-proto.c @@ -262,10 +262,10 @@ MetaField_t daap_encode_meta(char *meta) { if(m->tag) bits |= (((MetaField_t) 1) << m->bit); else - _ppi->log(E_WARN,"Unknown meta code: %.*s\n", len, start); + pi_log(E_WARN,"Unknown meta code: %.*s\n", len, start); } - _ppi->log(E_DBG, "meta codes: %llu\n", bits); + pi_log(E_DBG, "meta codes: %llu\n", bits); return bits; } @@ -475,12 +475,12 @@ int daap_enum_size(char **pe, PRIVINFO *pinfo, int *count, int *total_size) { int record_size; char **row; - _ppi->log(E_DBG,"Enumerating size\n"); + pi_log(E_DBG,"Enumerating size\n"); *count=0; *total_size = 0; - while((!(err=_ppi->db_enum_fetch_row(pe,&row,&pinfo->dq))) && (row)) { + while((!(err=pi_db_enum_fetch_row(pe,&row,&pinfo->dq))) && (row)) { if((record_size = daap_get_size(pinfo,row))) { *total_size += record_size; *count = *count + 1; @@ -488,14 +488,14 @@ int daap_enum_size(char **pe, PRIVINFO *pinfo, int *count, int *total_size) { } if(err) { - _ppi->db_enum_end(NULL); - _ppi->db_enum_dispose(NULL,&pinfo->dq); + pi_db_enum_end(NULL); + pi_db_enum_dispose(NULL,&pinfo->dq); return err; } - err=_ppi->db_enum_restart(pe, &pinfo->dq); + err=pi_db_enum_restart(pe, &pinfo->dq); - _ppi->log(E_DBG,"Got size: %d\n",*total_size); + pi_log(E_DBG,"Got size: %d\n",*total_size); return err; } @@ -508,10 +508,10 @@ int daap_enum_fetch(char **pe, PRIVINFO *pinfo, int *size, unsigned char **pdmap unsigned char *presult; char **row; - err=_ppi->db_enum_fetch_row(pe, &row, &pinfo->dq); + err=pi_db_enum_fetch_row(pe, &row, &pinfo->dq); if(err) { - _ppi->db_enum_end(NULL); - _ppi->db_enum_dispose(NULL,&pinfo->dq); + pi_db_enum_end(NULL); + pi_db_enum_dispose(NULL,&pinfo->dq); return err; } @@ -520,7 +520,7 @@ int daap_enum_fetch(char **pe, PRIVINFO *pinfo, int *size, unsigned char **pdmap if(result_size) { presult = (unsigned char*)malloc(result_size); if(!presult) { - _ppi->log(E_FATAL,"Malloc error\n"); + pi_log(E_FATAL,"Malloc error\n"); } daap_build_dmap(pinfo,row,presult,result_size); @@ -570,7 +570,7 @@ int daap_get_size(PRIVINFO *pinfo, char **valarray) { break; case QUERY_TYPE_ITEMS: /* see if this is going to be transcoded */ - transcode = _ppi->should_transcode(pinfo->pwsc,valarray[SG_CODECTYPE]); + transcode = pi_should_transcode(pinfo->pwsc,valarray[SG_CODECTYPE]); /* Items that get changed by transcode: * @@ -720,7 +720,7 @@ int daap_get_size(PRIVINFO *pinfo, char **valarray) { break; default: - _ppi->log(E_LOG,"Unknown query type: %d\n",(int)pinfo->dq.query_type); + pi_log(E_LOG,"Unknown query type: %d\n",(int)pinfo->dq.query_type); return 0; } return 0; @@ -759,7 +759,7 @@ int daap_build_dmap(PRIVINFO *pinfo, char **valarray, unsigned char *presult, in break; case QUERY_TYPE_ITEMS: /* see if this is going to be transcoded */ - transcode = _ppi->should_transcode(pinfo->pwsc,valarray[SG_CODECTYPE]); + transcode = pi_should_transcode(pinfo->pwsc,valarray[SG_CODECTYPE]); /* Items that get changed by transcode: * @@ -924,7 +924,7 @@ int daap_build_dmap(PRIVINFO *pinfo, char **valarray, unsigned char *presult, in break; default: - _ppi->log(E_LOG,"Unknown query type: %d\n",(int)pinfo->dq.query_type); + pi_log(E_LOG,"Unknown query type: %d\n",(int)pinfo->dq.query_type); return 0; } return 0; diff --git a/src/plugins/out-daap.c b/src/plugins/out-daap.c index ed7eff2e..39c14e0b 100644 --- a/src/plugins/out-daap.c +++ b/src/plugins/out-daap.c @@ -90,18 +90,17 @@ static int out_daap_output_xml_write(WS_CONNINFO *pwsc, PRIVINFO *ppi, unsigned static void out_daap_cleanup(PRIVINFO *ppi); -PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *); void plugin_handler(WS_CONNINFO *pwsc); int plugin_can_handle(WS_CONNINFO *pwsc); int plugin_auth(WS_CONNINFO *pwsc, char *username, char *password); -PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *); +PLUGIN_INFO *plugin_info(void); PLUGIN_OUTPUT_FN _pofn = { plugin_can_handle, plugin_handler, plugin_auth }; PLUGIN_REND_INFO _pri[] = { { "_daap._tcp", NULL }, { NULL, NULL } }; -PLUGIN_INPUT_FN *_ppi; + PLUGIN_INFO _pi = { PLUGIN_VERSION, /* version */ PLUGIN_OUTPUT, /* type */ @@ -161,8 +160,7 @@ PLUGIN_RESPONSE daap_uri_map[] = { /** * return info about this plugin module */ -PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) { - _ppi = ppi; +PLUGIN_INFO *plugin_info(void) { return &_pi; } @@ -170,9 +168,9 @@ PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) { * see if the plugin should handle this request */ int plugin_can_handle(WS_CONNINFO *pwsc) { - char *uri = _ppi->ws_uri(pwsc); + char *uri = pi_ws_uri(pwsc); - _ppi->log(E_DBG,"Checking url %s\n",uri); + pi_log(E_DBG,"Checking url %s\n",uri); if(strncasecmp(uri,"/databases",10) == 0) return TRUE; if(strncasecmp(uri,"/server-info",12) == 0) @@ -194,7 +192,7 @@ int plugin_can_handle(WS_CONNINFO *pwsc) { * works. */ int plugin_auth(WS_CONNINFO *pwsc, char *username, char *password) { - char *uri = _ppi->ws_uri(pwsc); + char *uri = pi_ws_uri(pwsc); /* don't auth for stuff we shouldn't */ if(strncasecmp(uri,"/server-info",12) == 0) @@ -204,7 +202,7 @@ int plugin_auth(WS_CONNINFO *pwsc, char *username, char *password) { if(strncasecmp(uri,"/databases/1/items/",19) == 0) return TRUE; - return _ppi->ws_matchesrole(pwsc,username,password,"user"); + return pi_ws_matchesrole(pwsc,username,password,"user"); } @@ -249,7 +247,7 @@ int daap_auth(WS_CONNINFO *pwsc, char *username, char *password) { char *readpassword; int result; - readpassword = _ppi->conf_alloc_string("general","password",NULL); + readpassword = pi_conf_alloc_string("general","password",NULL); if(password == NULL) { if((readpassword == NULL)||(strlen(readpassword) == 0)) { @@ -265,7 +263,7 @@ int daap_auth(WS_CONNINFO *pwsc, char *username, char *password) { } } - if(readpassword) _ppi->conf_dispose_string(readpassword); + if(readpassword) pi_conf_dispose_string(readpassword); return result; } @@ -282,46 +280,46 @@ void plugin_handler(WS_CONNINFO *pwsc) { long l,h; char *ptr; - _ppi->log(E_DBG,"Getting uri...\n"); + pi_log(E_DBG,"Getting uri...\n"); - string = _ppi->ws_uri(pwsc); + string = pi_ws_uri(pwsc); string++; - _ppi->log(E_DBG,"Mallocing privinfo...\n"); + pi_log(E_DBG,"Mallocing privinfo...\n"); ppi = (PRIVINFO *)malloc(sizeof(PRIVINFO)); if(ppi) { memset(ppi,0,sizeof(PRIVINFO)); } if(!ppi) { - _ppi->ws_returnerror(pwsc,500,"Malloc error in plugin_handler"); + pi_ws_returnerror(pwsc,500,"Malloc error in plugin_handler"); return; } memset((void*)&ppi->dq,0,sizeof(DB_QUERY)); - ppi->empty_strings = _ppi->conf_get_int("daap","empty_strings",0); + ppi->empty_strings = pi_conf_get_int("daap","empty_strings",0); ppi->pwsc = pwsc; - _ppi->ws_addresponseheader(pwsc,"Accept-Ranges","bytes"); - _ppi->ws_addresponseheader(pwsc,"DAAP-Server","firefly/" VERSION); - _ppi->ws_addresponseheader(pwsc,"Content-Type","application/x-dmap-tagged"); - _ppi->ws_addresponseheader(pwsc,"Cache-Control","no-cache"); - _ppi->ws_addresponseheader(pwsc,"Expires","-1"); + pi_ws_addresponseheader(pwsc,"Accept-Ranges","bytes"); + pi_ws_addresponseheader(pwsc,"DAAP-Server","firefly/" VERSION); + pi_ws_addresponseheader(pwsc,"Content-Type","application/x-dmap-tagged"); + pi_ws_addresponseheader(pwsc,"Cache-Control","no-cache"); + pi_ws_addresponseheader(pwsc,"Expires","-1"); - if(_ppi->ws_getvar(pwsc,"session-id")) - ppi->session_id = atoi(_ppi->ws_getvar(pwsc,"session-id")); + if(pi_ws_getvar(pwsc,"session-id")) + ppi->session_id = atoi(pi_ws_getvar(pwsc,"session-id")); ppi->dq.offset = 0; ppi->dq.limit = 999999; l=h=0; - if(_ppi->ws_getvar(pwsc,"index")) { - index_req = _ppi->ws_getvar(pwsc,"index"); + if(pi_ws_getvar(pwsc,"index")) { + index_req = pi_ws_getvar(pwsc,"index"); l = strtol(index_req,&ptr,10); if(l<0) { /* "-h"... tail range, last "h" entries */ - _ppi->log(E_LOG,"Unsupported index range: %s\n",index_req); + pi_log(E_LOG,"Unsupported index range: %s\n",index_req); } else if(*ptr == 0) { /* single item */ ppi->dq.offset = l; @@ -334,31 +332,31 @@ void plugin_handler(WS_CONNINFO *pwsc) { } } - _ppi->log(E_DBG,"Index %s: offset %d, limit %d\n",index_req, + pi_log(E_DBG,"Index %s: offset %d, limit %d\n",index_req, ppi->dq.offset,ppi->dq.limit); } - if(_ppi->ws_getvar(pwsc,"query")) { + if(pi_ws_getvar(pwsc,"query")) { ppi->dq.filter_type = FILTER_TYPE_APPLE; - ppi->dq.filter = _ppi->ws_getvar(pwsc,"query"); + ppi->dq.filter = pi_ws_getvar(pwsc,"query"); } - _ppi->log(E_DBG,"Tokenizing url\n"); + pi_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(daap_uri_map) / sizeof(PLUGIN_RESPONSE); - _ppi->log(E_DBG,"Found %d elements\n",elements); + pi_log(E_DBG,"Found %d elements\n",elements); index = 0; found = 0; while((!found) && (index < elements)) { /* test this set */ - _ppi->log(E_DBG,"Checking reponse %d\n",index); + pi_log(E_DBG,"Checking reponse %d\n",index); part=0; while(part < 10) { if((daap_uri_map[index].uri[part]) && (!ppi->uri_sections[part])) @@ -377,7 +375,7 @@ void plugin_handler(WS_CONNINFO *pwsc) { if(part == 10) { found = 1; - _ppi->log(E_DBG,"Found it! Index: %d\n",index); + pi_log(E_DBG,"Found it! Index: %d\n",index); } else { index++; } @@ -389,8 +387,8 @@ void plugin_handler(WS_CONNINFO *pwsc) { return; } - _ppi->ws_returnerror(pwsc,400,"Bad request"); - _ppi->ws_will_close(pwsc); + pi_ws_returnerror(pwsc,400,"Bad request"); + pi_ws_will_close(pwsc); out_daap_cleanup(ppi); return; } @@ -408,33 +406,33 @@ int out_daap_output_start(WS_CONNINFO *pwsc, PRIVINFO *ppi, int content_length) poi=(OUTPUT_INFO*)calloc(1,sizeof(OUTPUT_INFO)); if(!poi) { - _ppi->log(E_LOG,"Malloc error in out_daap_ouput_start\n"); + pi_log(E_LOG,"Malloc error in out_daap_ouput_start\n"); return -1; } ppi->output_info = (void*) poi; poi->dmap_response_length = content_length; - if(_ppi->ws_getvar(pwsc,"output")) { - if(strcasecmp(_ppi->ws_getvar(pwsc,"output"),"readable") == 0) + if(pi_ws_getvar(pwsc,"output")) { + if(strcasecmp(pi_ws_getvar(pwsc,"output"),"readable") == 0) poi->readable=1; poi->xml_output=1; - _ppi->ws_addresponseheader(pwsc,"Content-Type","text/xml"); - _ppi->ws_addresponseheader(pwsc,"Connection","Close"); - _ppi->ws_will_close(pwsc); - _ppi->ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n"); - _ppi->ws_emitheaders(pwsc); - _ppi->ws_writefd(pwsc,""); + pi_ws_addresponseheader(pwsc,"Content-Type","text/xml"); + pi_ws_addresponseheader(pwsc,"Connection","Close"); + pi_ws_will_close(pwsc); + pi_ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n"); + pi_ws_emitheaders(pwsc); + pi_ws_writefd(pwsc,""); if(poi->readable) - _ppi->ws_writefd(pwsc,"\n"); + pi_ws_writefd(pwsc,"\n"); return 0; } - _ppi->ws_addresponseheader(pwsc,"Content-Length","%d", + pi_ws_addresponseheader(pwsc,"Content-Length","%d", poi->dmap_response_length); - _ppi->ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n"); - _ppi->ws_emitheaders(pwsc); + pi_ws_writefd(pwsc,"HTTP/1.1 200 OK\r\n"); + pi_ws_emitheaders(pwsc); /* I guess now we would start writing the output */ return 0; @@ -458,7 +456,7 @@ int out_daap_output_write(WS_CONNINFO *pwsc, PRIVINFO *ppi, unsigned char *block if(poi->xml_output) return out_daap_output_xml_write(pwsc, ppi, block, len); - result=_ppi->ws_writebinary(pwsc,(char*)block,len); + result=pi_ws_writebinary(pwsc,(char*)block,len); if(result != len) return -1; @@ -493,7 +491,7 @@ int out_daap_output_xml_write(WS_CONNINFO *pwsc, PRIVINFO *ppi, unsigned char *b block_done=1; len_left=(int)((block+len) - current); if(len_left < 8) { - _ppi->log(E_FATAL,"Badly formatted dmap block - frag size: %d",len_left); + pi_log(E_FATAL,"Badly formatted dmap block - frag size: %d",len_left); } /* set up block */ @@ -509,49 +507,49 @@ int out_daap_output_xml_write(WS_CONNINFO *pwsc, PRIVINFO *ppi, unsigned char *b } /* lookup and serialize */ - _ppi->log(E_SPAM,"%*s %s: %d\n",poi->stack_height,"",block_tag,block_len); + pi_log(E_SPAM,"%*s %s: %d\n",poi->stack_height,"",block_tag,block_len); pitem=out_daap_xml_lookup_tag(block_tag); if(poi->readable) - _ppi->ws_writefd(pwsc,"%*s",poi->stack_height,""); - _ppi->ws_writefd(pwsc,"<%s>",pitem->description); + pi_ws_writefd(pwsc,"%*s",poi->stack_height,""); + pi_ws_writefd(pwsc,"<%s>",pitem->description); switch(pitem->type) { case 0x01: /* byte */ if(block_len != 1) { - _ppi->log(E_FATAL,"tag %s, size %d, wanted 1\n",block_tag, block_len); + pi_log(E_FATAL,"tag %s, size %d, wanted 1\n",block_tag, block_len); } - _ppi->ws_writefd(pwsc,"%d",*((char *)data)); + pi_ws_writefd(pwsc,"%d",*((char *)data)); break; case 0x02: /* unsigned byte */ if(block_len != 1) { - _ppi->log(E_FATAL,"tag %s, size %d, wanted 1\n",block_tag, block_len); + pi_log(E_FATAL,"tag %s, size %d, wanted 1\n",block_tag, block_len); } - _ppi->ws_writefd(pwsc,"%ud",*((char *)data)); + pi_ws_writefd(pwsc,"%ud",*((char *)data)); break; case 0x03: /* short */ if(block_len != 2) { - _ppi->log(E_FATAL,"tag %s, size %d, wanted 2\n",block_tag, block_len); + pi_log(E_FATAL,"tag %s, size %d, wanted 2\n",block_tag, block_len); } ivalue = data[0] << 8 | data[1]; - _ppi->ws_writefd(pwsc,"%d",ivalue); + pi_ws_writefd(pwsc,"%d",ivalue); break; case 0x05: /* int */ case 0x0A: /* epoch */ if(block_len != 4) { - _ppi->log(E_FATAL,"tag %s, size %d, wanted 4\n",block_tag, block_len); + pi_log(E_FATAL,"tag %s, size %d, wanted 4\n",block_tag, block_len); } ivalue = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; - _ppi->ws_writefd(pwsc,"%d",ivalue); + pi_ws_writefd(pwsc,"%d",ivalue); break; case 0x07: /* long long */ if(block_len != 8) { - _ppi->log(E_FATAL,"tag %s, size %d, wanted 8\n",block_tag, block_len); + pi_log(E_FATAL,"tag %s, size %d, wanted 8\n",block_tag, block_len); } ivalue = data[0] << 24 | @@ -564,29 +562,29 @@ int out_daap_output_xml_write(WS_CONNINFO *pwsc, PRIVINFO *ppi, unsigned char *b data[6] << 8 | data[7]; lvalue = (lvalue << 32) | ivalue; - _ppi->ws_writefd(pwsc,"%ll",ivalue); + pi_ws_writefd(pwsc,"%ll",ivalue); break; case 0x09: /* string */ if(block_len) { encoded_string=out_daap_xml_encode((char*)data,block_len); - _ppi->ws_writefd(pwsc,"%s",encoded_string); + pi_ws_writefd(pwsc,"%s",encoded_string); free(encoded_string); } break; case 0x0B: /* version? */ if(block_len != 4) { - _ppi->log(E_FATAL,"tag %s, size %d, wanted 4\n",block_tag, block_len); + pi_log(E_FATAL,"tag %s, size %d, wanted 4\n",block_tag, block_len); } ivalue=data[0] << 8 | data[1]; - _ppi->ws_writefd(pwsc,"%d.%d.%d",ivalue,data[2],data[3]); + pi_ws_writefd(pwsc,"%d.%d.%d",ivalue,data[2],data[3]); break; case 0x0C: if((poi->browse_response)&&(strcmp(block_tag,"mlit") ==0)) { if(block_len) { encoded_string=out_daap_xml_encode((char*)data,block_len); - _ppi->ws_writefd(pwsc,"%s",encoded_string); + pi_ws_writefd(pwsc,"%s",encoded_string); free(encoded_string); } } else { @@ -599,29 +597,29 @@ int out_daap_output_xml_write(WS_CONNINFO *pwsc, PRIVINFO *ppi, unsigned char *b memcpy(poi->stack[poi->stack_height].tag,block_tag,5); poi->stack_height++; if(poi->stack_height == 10) { - _ppi->log(E_FATAL,"Stack overflow\n"); + pi_log(E_FATAL,"Stack overflow\n"); } block_done=0; } break; default: - _ppi->log(E_FATAL,"Bad dmap type: %d, %s\n", + pi_log(E_FATAL,"Bad dmap type: %d, %s\n", pitem->type, pitem->description); break; } if(block_done) { - _ppi->ws_writefd(pwsc,"",pitem->description); + pi_ws_writefd(pwsc,"",pitem->description); if(poi->readable) - _ppi->ws_writefd(pwsc,"\n"); + pi_ws_writefd(pwsc,"\n"); block_len += 8; } else { /* must be a container */ block_len = 8; if(poi->readable) - _ppi->ws_writefd(pwsc,"\n"); + pi_ws_writefd(pwsc,"\n"); } current += block_len; @@ -631,17 +629,17 @@ int out_daap_output_xml_write(WS_CONNINFO *pwsc, PRIVINFO *ppi, unsigned char *b while(stack_ptr--) { poi->stack[stack_ptr].bytes_left -= block_len; if(poi->stack[stack_ptr].bytes_left < 0) { - _ppi->log(E_FATAL,"negative container\n"); + pi_log(E_FATAL,"negative container\n"); } if(!poi->stack[stack_ptr].bytes_left) { poi->stack_height--; pitem=out_daap_xml_lookup_tag(poi->stack[stack_ptr].tag); if(poi->readable) - _ppi->ws_writefd(pwsc,"%*s",poi->stack_height,""); - _ppi->ws_writefd(pwsc,"",pitem->description); + pi_ws_writefd(pwsc,"%*s",poi->stack_height,""); + pi_ws_writefd(pwsc,"",pitem->description); if(poi->readable) - _ppi->ws_writefd(pwsc,"\n"); + pi_ws_writefd(pwsc,"\n"); } } } @@ -662,10 +660,10 @@ int out_daap_output_end(WS_CONNINFO *pwsc, PRIVINFO *ppi) { OUTPUT_INFO *poi = ppi->output_info; if((poi) && (poi->xml_output) && (poi->stack_height)) { - _ppi->log(E_LOG,"Badly formed xml -- still stack\n"); + pi_log(E_LOG,"Badly formed xml -- still stack\n"); } - _ppi->config_set_status(pwsc,ppi->session_id,NULL); + pi_config_set_status(pwsc,ppi->session_id,NULL); return 0; } @@ -680,7 +678,7 @@ DAAP_ITEMS *out_daap_xml_lookup_tag(char *tag) { } if(!pitem->tag) - _ppi->log(E_FATAL,"Unknown daap tag: %c%c%c%c\n",tag[0],tag[1],tag[2],tag[3]); + pi_log(E_FATAL,"Unknown daap tag: %c%c%c%c\n",tag[0],tag[1],tag[2],tag[3]); return pitem; } @@ -747,7 +745,7 @@ char *out_daap_xml_encode(char *original, int len) { void out_daap_stream(WS_CONNINFO *pwsc, PRIVINFO *ppi) { /* should show sesson id */ - _ppi->stream(pwsc, ppi->uri_sections[3]); + pi_stream(pwsc, ppi->uri_sections[3]); } /** @@ -762,19 +760,19 @@ void out_daap_addplaylistitems(WS_CONNINFO *pwsc, PRIVINFO *ppi) { playlist_id = atoi(ppi->uri_sections[3]); - if(!_ppi->ws_getvar(pwsc,"dmap.itemid")) { - _ppi->log(E_LOG,"Attempt to add playlist item w/o dmap.itemid\n"); + if(!pi_ws_getvar(pwsc,"dmap.itemid")) { + pi_log(E_LOG,"Attempt to add playlist item w/o dmap.itemid\n"); out_daap_error(pwsc,ppi,"MAPI","No item id specified (dmap.itemid)"); return; } - tempstring=strdup(_ppi->ws_getvar(pwsc,"dmap.itemid")); + tempstring=strdup(pi_ws_getvar(pwsc,"dmap.itemid")); current=(unsigned char*)tempstring; while((token=_strsep((char**)(char*)¤t,","))) { if(token) { /* FIXME: error handling */ - _ppi->db_add_playlist_item(NULL,playlist_id,atoi(token)); + pi_db_add_playlist_item(NULL,playlist_id,atoi(token)); } } @@ -789,7 +787,7 @@ void out_daap_addplaylistitems(WS_CONNINFO *pwsc, PRIVINFO *ppi) { out_daap_output_write(pwsc,ppi,playlist_response,20); out_daap_output_end(pwsc,ppi); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); return; } @@ -801,14 +799,14 @@ void out_daap_deleteplaylist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { unsigned char playlist_response[20]; unsigned char *current; - if(!_ppi->ws_getvar(pwsc,"dmap.itemid")) { - _ppi->log(E_LOG,"Attempt to delete playlist w/o dmap.itemid\n"); + if(!pi_ws_getvar(pwsc,"dmap.itemid")) { + pi_log(E_LOG,"Attempt to delete playlist w/o dmap.itemid\n"); out_daap_error(pwsc,ppi,"MDPR","No playlist id specified"); return; } /* FIXME: error handling */ - _ppi->db_delete_playlist(NULL,atoi(_ppi->ws_getvar(pwsc,"dmap.itemid"))); + pi_db_delete_playlist(NULL,atoi(pi_ws_getvar(pwsc,"dmap.itemid"))); /* success(ish)... spool out a dmap block */ current = playlist_response; @@ -819,7 +817,7 @@ void out_daap_deleteplaylist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { out_daap_output_write(pwsc,ppi,playlist_response,20); out_daap_output_end(pwsc,ppi); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); return; } @@ -834,22 +832,22 @@ void out_daap_deleteplaylistitems(WS_CONNINFO *pwsc, PRIVINFO *ppi) { char *token; int playlist_id; - if(!_ppi->ws_getvar(pwsc,"dmap.itemid")) { - _ppi->log(E_LOG,"Delete playlist item w/o dmap.itemid\n"); + if(!pi_ws_getvar(pwsc,"dmap.itemid")) { + pi_log(E_LOG,"Delete playlist item w/o dmap.itemid\n"); out_daap_error(pwsc,ppi,"MDPI","No playlist item specified"); return; } playlist_id = atoi(ppi->uri_sections[3]); - tempstring=strdup(_ppi->ws_getvar(pwsc,"dmap.itemid")); + tempstring=strdup(pi_ws_getvar(pwsc,"dmap.itemid")); current=(unsigned char *)tempstring; /* this looks strange, but gets rid of gcc 4 warnings */ while((token=_strsep((char**)(char*)¤t,","))) { if(token) { /* FIXME: Error handling */ - _ppi->db_delete_playlist_item(NULL,playlist_id,atoi(token)); + pi_db_delete_playlist_item(NULL,playlist_id,atoi(token)); } } @@ -864,7 +862,7 @@ void out_daap_deleteplaylistitems(WS_CONNINFO *pwsc, PRIVINFO *ppi) { out_daap_output_write(pwsc,ppi,playlist_response,20); out_daap_output_end(pwsc,ppi); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); return; } @@ -880,21 +878,21 @@ void out_daap_addplaylist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { int retval, playlistid; char *estring = NULL; - if((!_ppi->ws_getvar(pwsc,"org.mt-daapd.playlist-type")) || - (!_ppi->ws_getvar(pwsc,"dmap.itemname"))) { - _ppi->log(E_LOG,"attempt to add playlist with invalid type\n"); + if((!pi_ws_getvar(pwsc,"org.mt-daapd.playlist-type")) || + (!pi_ws_getvar(pwsc,"dmap.itemname"))) { + pi_log(E_LOG,"attempt to add playlist with invalid type\n"); out_daap_error(pwsc,ppi,"MAPR","bad playlist info specified"); return; } - type=atoi(_ppi->ws_getvar(pwsc,"org.mt-daapd.playlist-type")); - name=_ppi->ws_getvar(pwsc,"dmap.itemname"); - query=_ppi->ws_getvar(pwsc,"org.mt-daapd.smart-playlist-spec"); + type=atoi(pi_ws_getvar(pwsc,"org.mt-daapd.playlist-type")); + name=pi_ws_getvar(pwsc,"dmap.itemname"); + query=pi_ws_getvar(pwsc,"org.mt-daapd.smart-playlist-spec"); - retval=_ppi->db_add_playlist(&estring,name,type,query,NULL,0,&playlistid); + retval=pi_db_add_playlist(&estring,name,type,query,NULL,0,&playlistid); if(retval) { out_daap_error(pwsc,ppi,"MAPR",estring); - _ppi->log(E_LOG,"error adding playlist %s: %s\n",name,estring); + pi_log(E_LOG,"error adding playlist %s: %s\n",name,estring); free(estring); return; } @@ -908,7 +906,7 @@ void out_daap_addplaylist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { out_daap_output_write(pwsc,ppi,playlist_response,32); out_daap_output_end(pwsc,ppi); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); return; } @@ -924,20 +922,20 @@ void out_daap_editplaylist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { int retval; - if(!_ppi->ws_getvar(pwsc,"dmap.itemid")) { - _ppi->log(E_LOG,"Missing itemid on playlist edit"); + if(!pi_ws_getvar(pwsc,"dmap.itemid")) { + pi_log(E_LOG,"Missing itemid on playlist edit"); out_daap_error(pwsc,ppi,"MEPR","No itemid specified"); return; } - name=_ppi->ws_getvar(pwsc,"dmap.itemname"); - query=_ppi->ws_getvar(pwsc,"org.mt-daapd.smart-playlist-spec"); - id=atoi(_ppi->ws_getvar(pwsc,"dmap.itemid")); + name=pi_ws_getvar(pwsc,"dmap.itemname"); + query=pi_ws_getvar(pwsc,"org.mt-daapd.smart-playlist-spec"); + id=atoi(pi_ws_getvar(pwsc,"dmap.itemid")); /* FIXME: Error handling */ - retval=_ppi->db_edit_playlist(&pe,id,name,query); + retval=pi_db_edit_playlist(&pe,id,name,query); if(retval) { - _ppi->log(E_LOG,"error editing playlist.\n"); + pi_log(E_LOG,"error editing playlist.\n"); out_daap_error(pwsc,ppi,"MEPR",pe); if(pe) free(pe); return; @@ -950,7 +948,7 @@ void out_daap_editplaylist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { out_daap_output_write(pwsc,ppi,edit_response,20); out_daap_output_end(pwsc,ppi); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); return; } @@ -967,8 +965,8 @@ void out_daap_playlistitems(WS_CONNINFO *pwsc, PRIVINFO *ppi) { char *pe = NULL; int mtco; - if(_ppi->ws_getvar(pwsc,"meta")) { - ppi->meta = daap_encode_meta(_ppi->ws_getvar(pwsc,"meta")); + if(pi_ws_getvar(pwsc,"meta")) { + ppi->meta = daap_encode_meta(pi_ws_getvar(pwsc,"meta")); } else { ppi->meta = ((1ll << metaItemId) | (1ll << metaItemName) | @@ -980,21 +978,21 @@ void out_daap_playlistitems(WS_CONNINFO *pwsc, PRIVINFO *ppi) { ppi->dq.query_type = QUERY_TYPE_ITEMS; ppi->dq.playlist_id = atoi(ppi->uri_sections[3]); - if(_ppi->db_enum_start(&pe,&ppi->dq)) { - _ppi->log(E_LOG,"Could not start enum: %s\n",pe); + if(pi_db_enum_start(&pe,&ppi->dq)) { + pi_log(E_LOG,"Could not start enum: %s\n",pe); out_daap_error(pwsc,ppi,"apso",pe); if(pe) free(pe); return; } if(daap_enum_size(&pe,ppi,&song_count,&list_length)) { - _ppi->log(E_LOG,"Could not enum size: %s\n",pe); + pi_log(E_LOG,"Could not enum size: %s\n",pe); out_daap_error(pwsc,ppi,"apso",pe); if(pe) free(pe); return; } - _ppi->log(E_DBG,"Item enum: got %d songs, dmap size: %d\n",song_count,list_length); + pi_log(E_DBG,"Item enum: got %d songs, dmap size: %d\n",song_count,list_length); mtco = song_count; if(ppi->dq.offset || ppi->dq.limit) @@ -1013,15 +1011,15 @@ void out_daap_playlistitems(WS_CONNINFO *pwsc, PRIVINFO *ppi) { /* FIXME: Error checking */ while((daap_enum_fetch(NULL,ppi,&list_length,&block)==0) && (list_length)) { - _ppi->log(E_SPAM,"Got block of size %d\n",list_length); + pi_log(E_SPAM,"Got block of size %d\n",list_length); out_daap_output_write(pwsc,ppi,block,list_length); free(block); } - _ppi->log(E_DBG,"Done enumerating.\n"); + pi_log(E_DBG,"Done enumerating.\n"); - _ppi->db_enum_end(NULL); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_db_enum_end(NULL); + pi_db_enum_dispose(NULL,&ppi->dq); out_daap_output_end(pwsc,ppi); return; @@ -1042,7 +1040,7 @@ void out_daap_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) { which_field = 3; } - _ppi->log(E_DBG,"Browsing by %s (field %d)\n", + pi_log(E_DBG,"Browsing by %s (field %d)\n", ppi->uri_sections[which_field],which_field); ppi->dq.query_type = QUERY_TYPE_DISTINCT; @@ -1062,25 +1060,25 @@ void out_daap_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) { response_type = "abcp"; ppi->dq.distinct_field = "composer"; } else { - _ppi->log(E_WARN,"Invalid browse request type %s\n",ppi->uri_sections[3]); + pi_log(E_WARN,"Invalid browse request type %s\n",ppi->uri_sections[3]); out_daap_error(pwsc,ppi,"abro","Invalid browse type"); - _ppi->config_set_status(pwsc,ppi->session_id,NULL); + pi_config_set_status(pwsc,ppi->session_id,NULL); return; } - if(_ppi->db_enum_start(&pe,&ppi->dq)) { - _ppi->log(E_LOG,"Could not start enum: %s\n",pe); + if(pi_db_enum_start(&pe,&ppi->dq)) { + pi_log(E_LOG,"Could not start enum: %s\n",pe); out_daap_error(pwsc,ppi,"abro",pe); if(pe) free(pe); return; } - _ppi->log(E_DBG,"Getting enum size.\n"); + pi_log(E_DBG,"Getting enum size.\n"); /* FIXME: Error handling */ daap_enum_size(NULL,ppi,&item_count,&list_length); - _ppi->log(E_DBG,"Item enum: got %d items, dmap size: %d\n", + pi_log(E_DBG,"Item enum: got %d items, dmap size: %d\n", item_count,list_length); mtco = item_count; @@ -1099,15 +1097,15 @@ void out_daap_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) { while((daap_enum_fetch(NULL,ppi,&list_length,&block)==0) && (list_length)) { - _ppi->log(E_SPAM,"Got block of size %d\n",list_length); + pi_log(E_SPAM,"Got block of size %d\n",list_length); out_daap_output_write(pwsc,ppi,block,list_length); free(block); } - _ppi->log(E_DBG,"Done enumerating\n"); + pi_log(E_DBG,"Done enumerating\n"); - _ppi->db_enum_end(NULL); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_db_enum_end(NULL); + pi_db_enum_dispose(NULL,&ppi->dq); out_daap_output_end(pwsc,ppi); return; @@ -1123,8 +1121,8 @@ void out_daap_playlists(WS_CONNINFO *pwsc, PRIVINFO *ppi) { int mtco; /* currently, this is ignored for playlist queries */ - if(_ppi->ws_getvar(pwsc,"meta")) { - ppi->meta = daap_encode_meta(_ppi->ws_getvar(pwsc,"meta")); + if(pi_ws_getvar(pwsc,"meta")) { + ppi->meta = daap_encode_meta(pi_ws_getvar(pwsc,"meta")); } else { ppi->meta = ((1ll << metaItemId) | (1ll << metaItemName) | @@ -1135,21 +1133,21 @@ void out_daap_playlists(WS_CONNINFO *pwsc, PRIVINFO *ppi) { ppi->dq.query_type = QUERY_TYPE_PLAYLISTS; - if(_ppi->db_enum_start(&pe,&ppi->dq)) { - _ppi->log(E_LOG,"Could not start enum: %s\n",pe); + if(pi_db_enum_start(&pe,&ppi->dq)) { + pi_log(E_LOG,"Could not start enum: %s\n",pe); out_daap_error(pwsc,ppi,"aply",pe); if(pe) free(pe); return; } if(daap_enum_size(NULL,ppi,&pl_count,&list_length)) { - _ppi->log(E_LOG,"error in enumerating size: %s\n",pe); + pi_log(E_LOG,"error in enumerating size: %s\n",pe); out_daap_error(pwsc,ppi,"aply",pe); if(pe) free(pe); return; } - _ppi->log(E_DBG,"Item enum: got %d playlists, dmap size: %d\n",pl_count,list_length); + pi_log(E_DBG,"Item enum: got %d playlists, dmap size: %d\n",pl_count,list_length); mtco = pl_count; if((ppi->dq.offset) || (ppi->dq.limit)) @@ -1169,15 +1167,15 @@ void out_daap_playlists(WS_CONNINFO *pwsc, PRIVINFO *ppi) { while((daap_enum_fetch(NULL,ppi,&list_length,&block)==0) && (list_length)) { - _ppi->log(E_SPAM,"Got block of size %d\n",list_length); + pi_log(E_SPAM,"Got block of size %d\n",list_length); out_daap_output_write(pwsc,ppi,block,list_length); free(block); } - _ppi->log(E_DBG,"Done enumerating.\n"); + pi_log(E_DBG,"Done enumerating.\n"); - _ppi->db_enum_end(NULL); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_db_enum_end(NULL); + pi_db_enum_dispose(NULL,&ppi->dq); out_daap_output_end(pwsc,ppi); return; @@ -1192,16 +1190,16 @@ void out_daap_items(WS_CONNINFO *pwsc, PRIVINFO *ppi) { char *pe = NULL; int mtco; - if(_ppi->ws_getvar(pwsc,"meta")) { - ppi->meta = daap_encode_meta(_ppi->ws_getvar(pwsc,"meta")); + if(pi_ws_getvar(pwsc,"meta")) { + ppi->meta = daap_encode_meta(pi_ws_getvar(pwsc,"meta")); } else { ppi->meta = (MetaField_t) -1ll; } ppi->dq.query_type = QUERY_TYPE_ITEMS; - if(_ppi->db_enum_start(&pe,&ppi->dq)) { - _ppi->log(E_LOG,"Could not start enum: %s\n",pe); + if(pi_db_enum_start(&pe,&ppi->dq)) { + pi_log(E_LOG,"Could not start enum: %s\n",pe); out_daap_error(pwsc,ppi,"adbs",pe); if(pe) free(pe); return; @@ -1209,13 +1207,13 @@ void out_daap_items(WS_CONNINFO *pwsc, PRIVINFO *ppi) { /* FIXME: Error handling */ if(daap_enum_size(&pe,ppi,&song_count,&list_length)) { - _ppi->log(E_LOG,"Error getting dmap size: %s\n",pe); + pi_log(E_LOG,"Error getting dmap size: %s\n",pe); out_daap_error(pwsc,ppi,"adbs",pe); if(pe) free(pe); return; } - _ppi->log(E_DBG,"Item enum: got %d songs, dmap size: %d\n",song_count, + pi_log(E_DBG,"Item enum: got %d songs, dmap size: %d\n",song_count, list_length); mtco = song_count; @@ -1235,13 +1233,13 @@ void out_daap_items(WS_CONNINFO *pwsc, PRIVINFO *ppi) { /* FIXME: check errors */ while((daap_enum_fetch(NULL,ppi,&list_length,&block)==0) && (list_length)) { - _ppi->log(E_SPAM,"Got block of size %d\n",list_length); + pi_log(E_SPAM,"Got block of size %d\n",list_length); out_daap_output_write(pwsc,ppi,block,list_length); free(block); } - _ppi->log(E_DBG,"Done enumerating.\n"); - _ppi->db_enum_end(NULL); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_log(E_DBG,"Done enumerating.\n"); + pi_db_enum_end(NULL); + pi_db_enum_dispose(NULL,&ppi->dq); out_daap_output_end(pwsc,ppi); return; } @@ -1250,18 +1248,18 @@ void out_daap_update(WS_CONNINFO *pwsc, PRIVINFO *ppi) { unsigned char update_response[32]; unsigned char *current=update_response; - _ppi->log(E_DBG,"Preparing to send update response\n"); - _ppi->config_set_status(pwsc,ppi->session_id,"Waiting for DB update"); + pi_log(E_DBG,"Preparing to send update response\n"); + pi_config_set_status(pwsc,ppi->session_id,"Waiting for DB update"); - if(!_ppi->db_wait_update(pwsc)) { - _ppi->log(E_DBG,"Update session stopped\n"); + if(!pi_db_wait_update(pwsc)) { + pi_log(E_DBG,"Update session stopped\n"); return; } /* otherwise, send the info about this version */ current += dmap_add_container(current,"mupd",24); current += dmap_add_int(current,"mstt",200); /* 12 */ - current += dmap_add_int(current,"musr",_ppi->db_revision()); /* 12 */ + current += dmap_add_int(current,"musr",pi_db_revision()); /* 12 */ out_daap_output_start(pwsc,ppi,32); out_daap_output_write(pwsc,ppi,update_response,32); @@ -1279,7 +1277,7 @@ void out_daap_dbinfo(WS_CONNINFO *pwsc, PRIVINFO *ppi) { int servername_size; servername_size = sizeof(servername); - _ppi->server_name(servername,&servername_size); + pi_server_name(servername,&servername_size); namelen=(int) strlen(servername); @@ -1293,9 +1291,9 @@ void out_daap_dbinfo(WS_CONNINFO *pwsc, PRIVINFO *ppi) { current += dmap_add_int(current,"miid",1); /* 12 */ current += dmap_add_long(current,"mper",1); /* 16 */ current += dmap_add_string(current,"minm",servername); /* 8 + namelen */ - count = _ppi->db_count_items(COUNT_SONGS); + count = pi_db_count_items(COUNT_SONGS); current += dmap_add_int(current,"mimc",count); /* 12 */ - count = _ppi->db_count_items(COUNT_PLAYLISTS); + count = pi_db_count_items(COUNT_PLAYLISTS); current += dmap_add_int(current,"mctc",count); /* 12 */ out_daap_output_start(pwsc,ppi,129+namelen); @@ -1306,8 +1304,8 @@ void out_daap_dbinfo(WS_CONNINFO *pwsc, PRIVINFO *ppi) { } void out_daap_logout(WS_CONNINFO *pwsc, PRIVINFO *ppi) { - _ppi->config_set_status(pwsc,ppi->session_id,NULL); - _ppi->ws_returnerror(pwsc,204,"Logout Successful"); + pi_config_set_status(pwsc,ppi->session_id,NULL); + pi_ws_returnerror(pwsc,204,"Logout Successful"); } @@ -1368,9 +1366,9 @@ void out_daap_content_codes(WS_CONNINFO *pwsc, PRIVINFO *ppi) { int out_daap_conf_isset(char *section, char *key) { char *value; - value = _ppi->conf_alloc_string(section,key,NULL); + value = pi_conf_alloc_string(section,key,NULL); if(value) { - _ppi->conf_dispose_string(value); + pi_conf_dispose_string(value); return TRUE; } @@ -1389,7 +1387,7 @@ void out_daap_server_info(WS_CONNINFO *pwsc, PRIVINFO *ppi) { int supports_update=0; size = sizeof(servername); - _ppi->server_name(servername,&size); + pi_server_name(servername,&size); // supports_update = conf_get_int("daap","supports_update",1); actual_length=139 + (int) strlen(servername); @@ -1397,10 +1395,10 @@ void out_daap_server_info(WS_CONNINFO *pwsc, PRIVINFO *ppi) { actual_length -= 9; if(actual_length > sizeof(server_info)) { - _ppi->log(E_FATAL,"Server name too long.\n"); + pi_log(E_FATAL,"Server name too long.\n"); } - client_version=_ppi->ws_getrequestheader(pwsc,"Client-DAAP-Version"); + client_version=pi_ws_getrequestheader(pwsc,"Client-DAAP-Version"); current += dmap_add_container(current,"msrv",actual_length - 8); current += dmap_add_int(current,"mstt",200); /* 12 */ @@ -1453,7 +1451,7 @@ void out_daap_error(WS_CONNINFO *pwsc, PRIVINFO *ppi, char *container, char *err block = (unsigned char *)malloc(len); if(!block) - _ppi->log(E_FATAL,"Malloc error\n"); + pi_log(E_FATAL,"Malloc error\n"); current = block; current += dmap_add_container(current,container,len - 8); @@ -1466,7 +1464,7 @@ void out_daap_error(WS_CONNINFO *pwsc, PRIVINFO *ppi, char *container, char *err free(block); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); } diff --git a/src/plugins/out-daap.h b/src/plugins/out-daap.h index a5cb03d6..6f693d06 100644 --- a/src/plugins/out-daap.h +++ b/src/plugins/out-daap.h @@ -92,7 +92,5 @@ typedef struct tag_daap_privinfo { WS_CONNINFO *pwsc; } PRIVINFO; -extern PLUGIN_INPUT_FN *_ppi; - #endif /* _OUT_DAAP_H_ */ diff --git a/src/plugins/rsp.c b/src/plugins/rsp.c index e040975b..5166dacf 100644 --- a/src/plugins/rsp.c +++ b/src/plugins/rsp.c @@ -27,7 +27,7 @@ typedef struct tag_rsp_privinfo { } PRIVINFO; /* Forwards */ -PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *); +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); @@ -45,7 +45,6 @@ PLUGIN_REND_INFO _pri[] = { { NULL, NULL } }; -PLUGIN_INPUT_FN *_ppi; PLUGIN_INFO _pi = { PLUGIN_VERSION, /* version */ PLUGIN_OUTPUT, /* type */ @@ -150,8 +149,7 @@ FIELDSPEC rsp_fields[] = { /** * return info about this plugin module */ -PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) { - _ppi = ppi; +PLUGIN_INFO *plugin_info(void) { return &_pi; } @@ -159,8 +157,8 @@ PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) { * see if the plugin should handle this request */ int plugin_can_handle(WS_CONNINFO *pwsc) { - _ppi->log(E_DBG,"Checking url %s\n",_ppi->ws_uri(pwsc)); - if(strncasecmp(_ppi->ws_uri(pwsc),"/rsp/",5) == 0) + 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; } @@ -170,7 +168,7 @@ int plugin_can_handle(WS_CONNINFO *pwsc) { * works. */ int plugin_auth(WS_CONNINFO *pwsc, char *username, char *password) { - return _ppi->ws_matchesrole(pwsc,username,password,"user"); + return pi_ws_matchesrole(pwsc,username,password,"user"); } /** @@ -183,39 +181,39 @@ void plugin_handler(WS_CONNINFO *pwsc) { int index, part; int found; - _ppi->log(E_DBG,"Getting uri...\n"); + pi_log(E_DBG,"Getting uri...\n"); - string = _ppi->ws_uri(pwsc); + string = pi_ws_uri(pwsc); string++; - _ppi->log(E_DBG,"Mallocing privinfo...\n"); + pi_log(E_DBG,"Mallocing privinfo...\n"); ppi = (PRIVINFO *)malloc(sizeof(PRIVINFO)); if(ppi) { memset(ppi,0,sizeof(PRIVINFO)); } if(!ppi) { - _ppi->ws_returnerror(pwsc,500,"Malloc error in plugin_handler"); + pi_ws_returnerror(pwsc,500,"Malloc error in plugin_handler"); return; } memset((void*)&ppi->dq,0,sizeof(DB_QUERY)); - _ppi->log(E_DBG,"Tokenizing url\n"); + pi_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); - _ppi->log(E_DBG,"Found %d elements\n",elements); + pi_log(E_DBG,"Found %d elements\n",elements); index = 0; found = 0; while((!found) && (index < elements)) { /* test this set */ - _ppi->log(E_DBG,"Checking reponse %d\n",index); + 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])) @@ -234,7 +232,7 @@ void plugin_handler(WS_CONNINFO *pwsc) { if(part == 10) { found = 1; - _ppi->log(E_DBG,"Found it! Index: %d\n",index); + pi_log(E_DBG,"Found it! Index: %d\n",index); } else { index++; } @@ -242,13 +240,13 @@ void plugin_handler(WS_CONNINFO *pwsc) { if(found) { rsp_uri_map[index].dispatch(pwsc, ppi); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); free(ppi); return; } rsp_error(pwsc, ppi, 1, "Bad path"); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); free(ppi); return; } @@ -261,7 +259,7 @@ void rsp_info(WS_CONNINFO *pwsc, PRIVINFO *ppi) { char servername[256]; int size; - _ppi->log(E_DBG,"Starting rsp_info\n"); + pi_log(E_DBG,"Starting rsp_info\n"); pxml = xml_init(pwsc,1); @@ -275,13 +273,13 @@ void rsp_info(WS_CONNINFO *pwsc, PRIVINFO *ppi) { /* info block */ xml_push(pxml,"info"); - xml_output(pxml,"count","%d",_ppi->db_count()); + xml_output(pxml,"count","%d",pi_db_count()); xml_output(pxml,"rsp-version","%s",RSP_VERSION); - xml_output(pxml,"server-version","%s",_ppi->server_ver()); + xml_output(pxml,"server-version","%s",pi_server_ver()); size = sizeof(servername); - _ppi->server_name(servername,&size); + pi_server_name(servername,&size); xml_output(pxml,"name","%s",servername); xml_pop(pxml); /* info */ @@ -303,9 +301,9 @@ void rsp_db(WS_CONNINFO *pwsc, PRIVINFO *ppi) { ppi->dq.query_type = QUERY_TYPE_PLAYLISTS; - if((err=_ppi->db_enum_start(&pe,&ppi->dq)) != 0) { + if((err=pi_db_enum_start(&pe,&ppi->dq)) != 0) { rsp_error(pwsc, ppi, err | E_DB, pe); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_db_enum_dispose(NULL,&ppi->dq); return; } @@ -321,7 +319,7 @@ void rsp_db(WS_CONNINFO *pwsc, PRIVINFO *ppi) { xml_push(pxml,"playlists"); - while((_ppi->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) { + while((pi_db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) { xml_push(pxml,"playlist"); rowindex=0; while(rsp_playlist_fields[rowindex].name) { @@ -334,8 +332,8 @@ void rsp_db(WS_CONNINFO *pwsc, PRIVINFO *ppi) { xml_pop(pxml); /* playlist */ } - _ppi->db_enum_end(NULL); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_db_enum_end(NULL); + pi_db_enum_dispose(NULL,&ppi->dq); xml_pop(pxml); /* playlists */ xml_pop(pxml); /* response */ @@ -359,17 +357,17 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { unsigned int samplerate; int done = 0; - ppi->dq.filter = _ppi->ws_getvar(pwsc,"query"); + ppi->dq.filter = pi_ws_getvar(pwsc,"query"); ppi->dq.filter_type = FILTER_TYPE_FIREFLY; - if(_ppi->ws_getvar(pwsc,"offset")) { - ppi->dq.offset = atoi(_ppi->ws_getvar(pwsc,"offset")); + if(pi_ws_getvar(pwsc,"offset")) { + ppi->dq.offset = atoi(pi_ws_getvar(pwsc,"offset")); } - if(_ppi->ws_getvar(pwsc,"limit")) { - ppi->dq.limit = atoi(_ppi->ws_getvar(pwsc,"limit")); + if(pi_ws_getvar(pwsc,"limit")) { + ppi->dq.limit = atoi(pi_ws_getvar(pwsc,"limit")); } - browse_type = _ppi->ws_getvar(pwsc,"type"); + browse_type = pi_ws_getvar(pwsc,"type"); type = F_FULL; if(browse_type) { @@ -385,9 +383,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=_ppi->db_enum_start(&pe,&ppi->dq)) != 0) { + if((err=pi_db_enum_start(&pe,&ppi->dq)) != 0) { rsp_error(pwsc, ppi, err | E_DB, pe); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_db_enum_dispose(NULL,&ppi->dq); free(pe); return; } @@ -412,15 +410,15 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { xml_push(pxml,"items"); - while((!done) && (_ppi->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && + while((!done) && (pi_db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) { xml_push(pxml,"item"); rowindex=0; transcode = 0; - transcode = _ppi->should_transcode(pwsc,row[37]); + transcode = pi_should_transcode(pwsc,row[37]); - _ppi->log(E_DBG,"Transcode: %d, %s: %s\n",transcode,row[37],row[2]); + 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) && @@ -466,7 +464,7 @@ void rsp_playlist(WS_CONNINFO *pwsc, PRIVINFO *ppi) { xml_pop(pxml); /* item */ } - _ppi->db_enum_end(NULL); + pi_db_enum_end(NULL); xml_pop(pxml); /* items */ xml_pop(pxml); /* response */ @@ -483,22 +481,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 = _ppi->ws_getvar(pwsc,"query"); + ppi->dq.filter = pi_ws_getvar(pwsc,"query"); ppi->dq.filter_type = FILTER_TYPE_FIREFLY; - if(_ppi->ws_getvar(pwsc,"offset")) { - ppi->dq.offset = atoi(_ppi->ws_getvar(pwsc,"offset")); + if(pi_ws_getvar(pwsc,"offset")) { + ppi->dq.offset = atoi(pi_ws_getvar(pwsc,"offset")); } - if(_ppi->ws_getvar(pwsc,"limit")) { - ppi->dq.limit = atoi(_ppi->ws_getvar(pwsc,"limit")); + 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=_ppi->db_enum_start(&pe,&ppi->dq)) != 0) { + if((err=pi_db_enum_start(&pe,&ppi->dq)) != 0) { rsp_error(pwsc, ppi, err | E_DB, pe); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_db_enum_dispose(NULL,&ppi->dq); return; } @@ -522,12 +520,12 @@ void rsp_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) { xml_push(pxml,"items"); - while((_ppi->db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) { + while((pi_db_enum_fetch_row(NULL,&row,&ppi->dq) == 0) && (row)) { xml_output(pxml,"item","%s",row[0]); } - _ppi->db_enum_end(NULL); - _ppi->db_enum_dispose(NULL,&ppi->dq); + pi_db_enum_end(NULL); + pi_db_enum_dispose(NULL,&ppi->dq); xml_pop(pxml); /* items */ xml_pop(pxml); /* response */ @@ -535,7 +533,7 @@ void rsp_browse(WS_CONNINFO *pwsc, PRIVINFO *ppi) { } void rsp_stream(WS_CONNINFO *pwsc, PRIVINFO *ppi) { - _ppi->stream(pwsc, ppi->uri_sections[2]); + pi_stream(pwsc, ppi->uri_sections[2]); return; } @@ -552,6 +550,6 @@ void rsp_error(WS_CONNINFO *pwsc, PRIVINFO *ppi, int eno, char *estr) { xml_pop(pxml); /* status */ xml_pop(pxml); /* response */ xml_deinit(pxml); - _ppi->ws_will_close(pwsc); + pi_ws_will_close(pwsc); } diff --git a/src/plugins/ssc-ffmpeg.c b/src/plugins/ssc-ffmpeg.c index 76b2f8f8..efa7ca6b 100644 --- a/src/plugins/ssc-ffmpeg.c +++ b/src/plugins/ssc-ffmpeg.c @@ -194,7 +194,7 @@ int ssc_ffmpeg_open(void *vp, MP3FILE *pmp3) { handle->first_frame = 1; handle->raw=0; - _ppi->log(E_DBG,"opening %s\n",file); + pi_log(E_DBG,"opening %s\n",file); if(strcasecmp(codec,"flac") == 0) { handle->raw=1; @@ -211,7 +211,7 @@ int ssc_ffmpeg_open(void *vp, MP3FILE *pmp3) { handle->samples = (uint32_t)pmp3->sample_count; handle->sample_rate = pmp3->samplerate; - _ppi->log(E_DBG,"opening file raw\n"); + pi_log(E_DBG,"opening file raw\n"); handle->pCodec = avcodec_find_decoder(id); if(!handle->pCodec) { handle->errnum = SSC_FFMPEG_E_BADCODEC; @@ -235,7 +235,7 @@ int ssc_ffmpeg_open(void *vp, MP3FILE *pmp3) { handle->fin = fopen(file,"rb"); #endif if(!handle->fin) { - _ppi->log(E_DBG,"could not open file\n"); + pi_log(E_DBG,"could not open file\n"); handle->errnum = SSC_FFMPEG_E_FILEOPEN; return FALSE; } @@ -243,9 +243,9 @@ int ssc_ffmpeg_open(void *vp, MP3FILE *pmp3) { /* check to see if there is an id3 tag there... if so, skip it. */ if(fread((unsigned char *)&id3,1,sizeof(id3),handle->fin) != sizeof(id3)) { if(ferror(handle->fin)) { - _ppi->log(E_LOG,"Error reading file: %s\n",file); + pi_log(E_LOG,"Error reading file: %s\n",file); } else { - _ppi->log(E_LOG,"Short file: %s\n",file); + pi_log(E_LOG,"Short file: %s\n",file); } handle->errnum = SSC_FFMPEG_E_FILEOPEN; fclose(handle->fin); @@ -255,11 +255,11 @@ int ssc_ffmpeg_open(void *vp, MP3FILE *pmp3) { if(strncmp(id3.id,"ID3",3)==0) { /* found an ID3 header... */ - _ppi->log(E_DBG,"Found ID3 header\n"); + pi_log(E_DBG,"Found ID3 header\n"); size = (id3.size[0] << 21 | id3.size[1] << 14 | id3.size[2] << 7 | id3.size[3]); fseek(handle->fin,size + sizeof(SCAN_ID3HEADER),SEEK_SET); - _ppi->log(E_DBG,"Header length: %d\n",size); + pi_log(E_DBG,"Header length: %d\n",size); } else { fseek(handle->fin,0,SEEK_SET); } @@ -267,7 +267,7 @@ int ssc_ffmpeg_open(void *vp, MP3FILE *pmp3) { return TRUE; } - _ppi->log(E_DBG,"opening file with format\n"); + pi_log(E_DBG,"opening file with format\n"); if(av_open_input_file(&handle->pFmtCtx,file,handle->pFormat,0,NULL) < 0) { handle->errnum = SSC_FFMPEG_E_FILEOPEN; return FALSE; @@ -501,10 +501,10 @@ int ssc_ffmpeg_read(void *vp, char *buffer, int len) { byte_rate = sample_rate * channels * bits_per_sample / 8; block_align = channels * bits_per_sample / 8; - _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); + pi_log(E_DBG,"Channels.......: %d\n",channels); + pi_log(E_DBG,"Sample rate....: %d\n",sample_rate); + pi_log(E_DBG,"Bits/Sample....: %d\n",bits_per_sample); + pi_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); diff --git a/src/plugins/ssc-script.c b/src/plugins/ssc-script.c index 3a454262..b620cef0 100644 --- a/src/plugins/ssc-script.c +++ b/src/plugins/ssc-script.c @@ -30,7 +30,7 @@ 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 *); +PLUGIN_INFO *plugin_info(void); #define infn ((PLUGIN_INPUT_FN *)(_pi.pi)) @@ -44,8 +44,6 @@ PLUGIN_TRANSCODE_FN _ptfn = { ssc_script_error }; -PLUGIN_INPUT_FN *_ppi; - PLUGIN_INFO _pi = { PLUGIN_VERSION, /* version */ PLUGIN_TRANSCODE, /* type */ @@ -66,21 +64,19 @@ static char *_ssc_script_program = NULL; /** * return the plugininfo struct to firefly */ -PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) { +PLUGIN_INFO *plugin_info(void) { char *codeclist; - _ppi = ppi; - - _ssc_script_program = _ppi->conf_alloc_string("general","ssc_prog",NULL); + _ssc_script_program = pi_conf_alloc_string("general","ssc_prog",NULL); if(!_ssc_script_program) { - _ppi->log(E_INF,"No ssc program specified for script transcoder.\n"); + pi_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); + codeclist = pi_conf_alloc_string("general","ssc_codectypes",NULL); if(!codeclist) { - _ppi->log(E_INF,"No codectypes specified for script transcoder.\n"); + pi_log(E_INF,"No codectypes specified for script transcoder.\n"); return NULL; } @@ -161,7 +157,7 @@ int ssc_script_open(void *vp, MP3FILE *pmp3) { if(metachars) { newpath = (char*)malloc(strlen(file) + metacount + 1); if(!newpath) { - _ppi->log(E_FATAL,"ssc_script_open: malloc\n"); + pi_log(E_FATAL,"ssc_script_open: malloc\n"); } src=file; dst=newpath; @@ -189,7 +185,7 @@ int ssc_script_open(void *vp, MP3FILE *pmp3) { 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); + pi_log(E_INF,"Executing %s\n",cmd); handle->fin = popen(cmd, "r"); free(newpath); free(cmd); /* should really have in-place expanded the path */ diff --git a/src/plugins/xml-rpc.c b/src/plugins/xml-rpc.c index 3a97ab7a..432b3a7d 100644 --- a/src/plugins/xml-rpc.c +++ b/src/plugins/xml-rpc.c @@ -46,8 +46,6 @@ 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); @@ -72,7 +70,7 @@ int xml_write(XMLSTRUCT *pxml, char *fmt, ...) { if(!result) result = -1; } else { - result=_ppi->ws_writefd(pxml->pwsc,"%s",buffer); + result=pi_ws_writefd(pxml->pwsc,"%s",buffer); } return result; @@ -101,14 +99,14 @@ XML_STREAMBUFFER *xml_stream_open(void) { psb = (XML_STREAMBUFFER*) malloc(sizeof(XML_STREAMBUFFER)); if(!psb) { - _ppi->log(E_FATAL,"xml_stream_open: malloc\n"); + 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)) { - _ppi->log(E_FATAL,"xml_stream_open: malloc\n"); + pi_log(E_FATAL,"xml_stream_open: malloc\n"); } psb->strm.zalloc = Z_NULL; @@ -146,9 +144,9 @@ int xml_stream_write(XMLSTRUCT *pxml, char *out) { while(!done) { result = deflate(&psb->strm, Z_NO_FLUSH); if(result != Z_OK) { - _ppi->log(E_FATAL,"Error in zlib: %d\n",result); + pi_log(E_FATAL,"Error in zlib: %d\n",result); } - _ppi->ws_writebinary(pxml->pwsc,(char*)psb->out_buffer, + pi_ws_writebinary(pxml->pwsc,(char*)psb->out_buffer, XML_STREAM_BLOCK-psb->strm.avail_out); if(psb->strm.avail_out != 0) { done=1; @@ -175,14 +173,14 @@ int xml_stream_close(XMLSTRUCT *pxml) { psb->strm.next_in = psb->in_buffer; deflate(&psb->strm,Z_FINISH); - _ppi->ws_writebinary(pxml->pwsc,(char*)psb->out_buffer, + pi_ws_writebinary(pxml->pwsc,(char*)psb->out_buffer, XML_STREAM_BLOCK - psb->strm.avail_out); if(psb->strm.avail_out != 0) done=1; } - _ppi->log(E_DBG,"Done sending xml stream\n"); + pi_log(E_DBG,"Done sending xml stream\n"); deflateEnd(&psb->strm); if(psb->out_buffer != NULL) free(psb->out_buffer); @@ -208,7 +206,7 @@ XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header) { pxml=(XMLSTRUCT*)malloc(sizeof(XMLSTRUCT)); if(!pxml) { - _ppi->log(E_FATAL,"Malloc error\n"); + pi_log(E_FATAL,"Malloc error\n"); } memset(pxml,0,sizeof(XMLSTRUCT)); @@ -216,27 +214,27 @@ XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header) { pxml->pwsc = pwsc; /* should we compress output? */ - nogzip = _ppi->ws_getvar(pwsc,"nogzip"); - accept = _ppi->ws_getrequestheader(pwsc,"accept-encoding"); + nogzip = pi_ws_getvar(pwsc,"nogzip"); + accept = pi_ws_getrequestheader(pwsc,"accept-encoding"); if((!nogzip) && (accept) && (strcasestr(accept,"gzip"))) { - _ppi->log(E_DBG,"Gzipping output\n"); + pi_log(E_DBG,"Gzipping output\n"); pxml->psb = xml_stream_open(); if(pxml->psb) { - _ppi->ws_addresponseheader(pwsc,"Content-Encoding","gzip"); - _ppi->ws_addresponseheader(pwsc,"Vary","Accept-Encoding"); - _ppi->ws_addresponseheader(pwsc,"Connection","Close"); + 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 */ - _ppi->ws_addresponseheader(pwsc,"Cache-Control","no-cache"); - _ppi->ws_addresponseheader(pwsc,"Expires","-1"); + pi_ws_addresponseheader(pwsc,"Cache-Control","no-cache"); + pi_ws_addresponseheader(pwsc,"Expires","-1"); if(emit_header) { - _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); + 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,""); @@ -275,7 +273,7 @@ void xml_pop(XMLSTRUCT *pxml) { pstack=pxml->stack.next; if(!pstack) { - _ppi->log(E_LOG,"xml_pop: tried to pop an empty stack\n"); + pi_log(E_LOG,"xml_pop: tried to pop an empty stack\n"); return; } @@ -326,7 +324,7 @@ void xml_deinit(XMLSTRUCT *pxml) { XMLSTACK *pstack; if(pxml->stack.next) { - _ppi->log(E_LOG,"xml_deinit: entries still on stack (%s)\n", + pi_log(E_LOG,"xml_deinit: entries still on stack (%s)\n", pxml->stack.next->tag); } diff --git a/src/util.c b/src/util.c index 4403abf9..0a059739 100644 --- a/src/util.c +++ b/src/util.c @@ -13,6 +13,7 @@ #endif #include +#include #include #include #include @@ -23,6 +24,7 @@ #include "err.h" #include "util.h" + /* Globals */ pthread_mutex_t util_locks[(int)l_last]; pthread_mutex_t util_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -453,7 +455,7 @@ void util_mutex_unlock(ff_lock_t which) { fprintf(stderr,"Cannot unlock mutex\n"); exit(-1); } - + } /** @@ -587,6 +589,81 @@ void util_dispose_split(char **argv) { free(argv); } +/** + * Write a formatted string to an allocated string. Leverage + * the existing util_vasprintf to do so + */ +char *util_asprintf(char *fmt, ...) { + char *outbuf; + va_list ap; + + ASSERT(fmt); + + if(!fmt) + return NULL; + + va_start(ap,fmt); + outbuf = util_vasprintf(fmt, ap); + va_end(ap); + + return outbuf; +} + +/** + * Write a formatted string to an allocated string. This deals with + * versions of vsnprintf that return either the C99 way, or the pre-C99 + * way, by increasing the buffer until it works. + * + * @param + * @param fmt format string of print (compatible with printf(2)) + * @returns TRUE on success + */ + +#ifdef HAVE_VA_COPY +# define VA_COPY(a,b) va_copy((a),(b)) +#else +# ifdef HAVE___VA_COPY +# define VA_COPY(a,b) __va_copy((a),(b)) +# else +# define VA_COPY(a,b) a=b; +# endif +#endif + +char *util_vasprintf(char *fmt, va_list ap) { + char *outbuf; + char *newbuf; + va_list ap2; + int size=200; + int new_size; + + outbuf = (char*)malloc(size); + if(!outbuf) + DPRINTF(E_FATAL,L_MISC,"Could not allocate buffer in vasprintf\n"); + + VA_COPY(ap2,ap); + + while(1) { + new_size=vsnprintf(outbuf,size,fmt,ap); + + if(new_size > -1 && new_size < size) + break; + + if(new_size > -1) + size = new_size + 1; + else + size *= 2; + + if((newbuf = realloc(outbuf,size)) == NULL) { + free(outbuf); + DPRINTF(E_FATAL,L_MISC,"malloc error in vasprintf\n"); + exit(1); + } + outbuf = newbuf; + VA_COPY(ap,ap2); + } + + return outbuf; +} #ifdef DEBUG_MEM diff --git a/src/util.h b/src/util.h index 02e864bf..fcd54703 100644 --- a/src/util.h +++ b/src/util.h @@ -13,6 +13,7 @@ # include #endif +#include #include typedef enum { @@ -54,7 +55,8 @@ extern int util_utf16toutf8(unsigned char *utf8, int dlen, unsigned char *utf16, extern int util_utf16_byte_len(unsigned char *utf16); extern void util_hexdump(unsigned char *block, int len); - +extern char *util_vasprintf(char *fmt, va_list ap); +extern char *util_asprintf(char *fmt, ...); #endif /* _UTIL_H_ */