diff --git a/ChangeLog b/ChangeLog index 289de82c..6f49c052 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18303,3 +18303,6 @@ 2019-01-07 Fred Gleason * Removed the 'rlm_icecast2' RLM. * Removed the 'rlm_tunein' RLM. +2019-01-07 Fred Gleason + * Added a 'pypad_shoutcast1.py' PyPAD script. + * Removed the 'rlm_shoutcast1' RLM. diff --git a/apis/PyPAD/scripts/Makefile.am b/apis/PyPAD/scripts/Makefile.am index 91a8e64e..c6b48266 100644 --- a/apis/PyPAD/scripts/Makefile.am +++ b/apis/PyPAD/scripts/Makefile.am @@ -36,6 +36,8 @@ install-exec-am: cp pypad_liqcomp.exemplar $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_liqcomp.exemplar ../../../helpers/install_python.sh pypad_serial.py $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_serial.py cp pypad_serial.exemplar $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_serial.exemplar + ../../../helpers/install_python.sh pypad_shoutcast1.py $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_shoutcast1.py + cp pypad_shoutcast1.exemplar $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_shoutcast1.exemplar ../../../helpers/install_python.sh pypad_spinitron.py $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_spinitron.py cp pypad_spinitron.exemplar $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_spinitron.exemplar ../../../helpers/install_python.sh pypad_spottrap.py $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_spottrap.py @@ -68,6 +70,8 @@ uninstall-local: rm -f $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_liqcomp.py rm -f $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_serial.exemplar rm -f $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_serial.py + rm -f $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_shoutcast1.exemplar + rm -f $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_shoutcast1.py rm -f $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_spinitron.exemplar rm -f $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_spinitron.py rm -f $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/PyPAD/pypad_spottrap.exemplar @@ -97,6 +101,10 @@ EXTRA_DIST = pypad_ando.exemplar\ pypad_liqcomp.py\ pypad_live365.exemplar\ pypad_live365.py\ + pypad_serial.exemplar\ + pypad_serial.py\ + pypad_shoutcast1.exemplar\ + pypad_shoutcast1.py\ pypad_spinitron.exemplar\ pypad_spinitron.py\ pypad_spottrap.exemplar\ diff --git a/apis/PyPAD/scripts/pypad_shoutcast1.exemplar b/apis/PyPAD/scripts/pypad_shoutcast1.exemplar new file mode 100644 index 00000000..1d1007a8 --- /dev/null +++ b/apis/PyPAD/scripts/pypad_shoutcast1.exemplar @@ -0,0 +1,96 @@ +; This is the sample configuration for the 'pypad_shoutcast1.py' script for +; Rivendell, which can be used to update the metadata on an Shoutcast 1.x +; server using Now & Next data. + + +; Section Header +; +; One section per Shoutcast server instance is configured, starting with +; 'Shoutcast1' and working up consecutively +[Shoutcast1] + +; Password +; +; The password of the Shoutcast server instance to which to send updates. +Password=changeme + +; Host Name +; +; The fully-qualified domain name or IP address of the Shoutcast server +Hostname=shoutcast.example.com + +; Host Port +; +; The TCP port number of the Shoutcast server +Tcpport=8000 + +; Format String. The metadata to be sent each time RDAirPlay changes +; play state, including any wildcards as placeholders for metadata values. +; +; The list of available wildcards can be found in the 'metadata_wildcards.txt' +; file in the Rivendell documentation directory. +; +FormatString=%a%20-%20%t + +; Log Selection +; +; Set the status for each log to 'Yes', 'No' or 'Onair' to indicate whether +; state changes on that log should be output to this account. If set +; to 'Onair', then output will be generated only if RDAirPlays OnAir flag +; is active. +MasterLog=Yes +Aux1Log=Yes +Aux2Log=Yes +VLog101=No +VLog102=No +VLog103=No +VLog104=No +VLog105=No +VLog106=No +VLog107=No +VLog108=No +VLog109=No +VLog110=No +VLog111=No +VLog112=No +VLog113=No +VLog114=No +VLog115=No +VLog116=No +VLog117=No +VLog118=No +VLog119=No +VLog120=No + + +; Additional Shoutcast server instances can be configured by adding new +; sections... +; +;[Shoutcast2] +;Password=letmein +;Hostname=anotherone.example.com +;Tcpport=80 +;FormatString=%t by %a +;MasterLog=Yes +;Aux1Log=No +;Aux2Log=Onair +;VLog101=No +;VLog102=No +;VLog103=No +;VLog104=No +;VLog105=No +;VLog106=No +;VLog107=No +;VLog108=No +;VLog109=No +;VLog110=No +;VLog111=No +;VLog112=No +;VLog113=No +;VLog114=No +;VLog115=No +;VLog116=No +;VLog117=No +;VLog118=No +;VLog119=No +;VLog120=No diff --git a/apis/PyPAD/scripts/pypad_shoutcast1.py b/apis/PyPAD/scripts/pypad_shoutcast1.py new file mode 100755 index 00000000..1a844916 --- /dev/null +++ b/apis/PyPAD/scripts/pypad_shoutcast1.py @@ -0,0 +1,83 @@ +#!%PYTHON_BANGPATH% + +# pypad_shoutcast1.py +# +# Write PAD updates to a Shoutcast 1 instance +# +# (C) Copyright 2018 Fred Gleason +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +import sys +import syslog +import configparser +import pycurl +import PyPAD +from io import BytesIO + +last_updates={} + +def eprint(*args,**kwargs): + print(*args,file=sys.stderr,**kwargs) + +def ProcessPad(update): + try: + last_updates[update.machine()] + except KeyError: + last_updates[update.machine()]=None + + n=1 + try: + while(True): + section='Shoutcast'+str(n) + if update.shouldBeProcessed(section) and update.hasPadType(PyPAD.TYPE_NOW) and (last_updates[update.machine()] != update.startDateTimeString(PyPAD.TYPE_NOW)): + last_updates[update.machine()]=update.startDateTimeString(PyPAD.TYPE_NOW) + song=update.resolvePadFields(update.config().get(section,'FormatString'),PyPAD.ESCAPE_URL) + url='http://'+update.config().get(section,'Hostname')+':'+str(update.config().get(section,'Tcpport'))+'/admin.cgi?pass='+update.escape(update.config().get(section,'Password'),PyPAD.ESCAPE_URL)+'&mode=updinfo&song='+song + curl=pycurl.Curl() + curl.setopt(curl.URL,url) + headers=[] + # + # D.N.A.S v1.9.8 refuses to process updates with the default + # CURL user-agent value, hence we lie to it. + # + headers.append('User-Agent: '+'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2') + curl.setopt(curl.HTTPHEADER,headers); + try: + curl.perform() + code=curl.getinfo(pycurl.RESPONSE_CODE) + if (code<200) or (code>=300): + syslog.syslog(syslog.LOG_WARNING,'['+section+'] returned response code '+str(code)) + except pycurl.error: + syslog.syslog(syslog.LOG_WARNING,'['+section+'] failed: '+curl.errstr()) + curl.close() + n=n+1 + + except configparser.NoSectionError: + return + +# +# 'Main' function +# +syslog.openlog(sys.argv[0].split('/')[-1]) + +rcvr=PyPAD.Receiver() +try: + rcvr.setConfigFile(sys.argv[3]) +except IndexError: + eprint('pypad_shoutcast1.py: you must specify a configuration file') + sys.exit(1) +rcvr.setCallback(ProcessPad) +rcvr.start(sys.argv[1],int(sys.argv[2])) diff --git a/apis/rlm/Makefile.am b/apis/rlm/Makefile.am index 313e01c2..370b7a87 100644 --- a/apis/rlm/Makefile.am +++ b/apis/rlm/Makefile.am @@ -21,7 +21,7 @@ AM_CFLAGS = -fPIC -Wall -I../ -RLM_MODULES = rlm_shoutcast1.rlm +RLM_MODULES = all: $(RLM_MODULES) @@ -41,8 +41,7 @@ headerdir = $(includedir)/rlm header_HEADERS = rlm.h EXTRA_DIST = Makefile-example\ - rlm.h\ - rlm_shoutcast1.c + rlm.h CLEANFILES = *~\ *.idb\ diff --git a/apis/rlm/rlm_shoutcast1.c b/apis/rlm/rlm_shoutcast1.c deleted file mode 100644 index 1669d0ef..00000000 --- a/apis/rlm/rlm_shoutcast1.c +++ /dev/null @@ -1,519 +0,0 @@ -/* rlm_shoutcast1.c - * - * (C) Copyright 2011-2018 Fred Gleason - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * This is a Rivendell Loadable Module. It uses Now&Next PAD data - * to update the metadata on an Icecast2 mountpoint specified in the - * configuration file pointed to by the plugin argument. - * - * This module requires the curl(1) network transfer tool, included with - * most Linux distros. It is also available at http://curl.haxx.se/. - * - * To compile this module, just do: - * - * gcc -shared -o rlm_shoutcast1.rlm rlm_shoutcast1.c - */ - -#include -#include -#include -#include -#include -#include - -#include - -int rlm_shoutcast1_devs; -char *rlm_shoutcast1_passwords; -char *rlm_shoutcast1_hostnames; -int *rlm_shoutcast1_tcpports; -char *rlm_shoutcast1_formats; -int *rlm_shoutcast1_masters; -int *rlm_shoutcast1_aux1s; -int *rlm_shoutcast1_aux2s; -int *rlm_shoutcast1_vlog101s; -int *rlm_shoutcast1_vlog102s; -int *rlm_shoutcast1_vlog103s; -int *rlm_shoutcast1_vlog104s; -int *rlm_shoutcast1_vlog105s; -int *rlm_shoutcast1_vlog106s; -int *rlm_shoutcast1_vlog107s; -int *rlm_shoutcast1_vlog108s; -int *rlm_shoutcast1_vlog109s; -int *rlm_shoutcast1_vlog110s; -int *rlm_shoutcast1_vlog111s; -int *rlm_shoutcast1_vlog112s; -int *rlm_shoutcast1_vlog113s; -int *rlm_shoutcast1_vlog114s; -int *rlm_shoutcast1_vlog115s; -int *rlm_shoutcast1_vlog116s; -int *rlm_shoutcast1_vlog117s; -int *rlm_shoutcast1_vlog118s; -int *rlm_shoutcast1_vlog119s; -int *rlm_shoutcast1_vlog120s; - -int rlm_shoutcast1_BufferDiff(char *sString,int dOrigin,int dDiff,int dMaxSize) -{ - int dOldSize,dNewSize; - int i; - - /* - * Will it fit? - */ - dOldSize=strlen(sString); - if((dOldSize+dDiff)>=dMaxSize) { - return -1; - } - dNewSize=dOldSize+dDiff; - - /* - * Adding characters - */ - if(dDiff>0) { - for(i=dOldSize;i>dOrigin;i--) { - sString[i+dDiff]=sString[i]; - } - return dNewSize; - } - - /* - * No Change - */ - if(dDiff==0) { - return dNewSize; - } - - /* - * Deleting Characters - */ - if(dDiff<0) { - for(i=dOrigin;i'9') && (sString[i]<'A')) || - ((sString[i]>'Z') && (sString[i]<'a')) || - (sString[i]>'z'))) { - if(rlm_shoutcast1_BufferDiff(sString,i,2,dMaxSize)<0) { - return -1; - } - sprintf(sAccum,"%%%2x",sString[i]); - sString[i++]=sAccum[0]; - sString[i++]=sAccum[1]; - sString[i]=sAccum[2]; - } - if(sString[i]==' ') { - sString[i]='+'; - } - i++; - if(i>=dMaxSize) { - return -1; - } - } - return strlen(sString); -} - - -int rlm_shoutcast1_GetLogStatus(void *ptr,const char *arg,const char *section, - const char *logname) -{ - const char *tag=RLMGetStringValue(ptr,arg,section,logname,""); - if(strcasecmp(tag,"yes")==0) { - return 1; - } - if(strcasecmp(tag,"on")==0) { - return 1; - } - if(strcasecmp(tag,"true")==0) { - return 1; - } - if(strcasecmp(tag,"no")==0) { - return 0; - } - if(strcasecmp(tag,"off")==0) { - return 0; - } - if(strcasecmp(tag,"false")==0) { - return 0; - } - if(strcasecmp(tag,"onair")==0) { - return 2; - } - return 0; -} - - -void rlm_shoutcast1_RLMStart(void *ptr,const char *arg) -{ - char password[256]; - char section[256]; - char errtext[256]; - int i=1; - - rlm_shoutcast1_devs=0; - rlm_shoutcast1_passwords=NULL; - rlm_shoutcast1_formats=NULL; - rlm_shoutcast1_masters=NULL; - rlm_shoutcast1_aux1s=NULL; - rlm_shoutcast1_aux2s=NULL; - rlm_shoutcast1_vlog101s=NULL; - rlm_shoutcast1_vlog102s=NULL; - rlm_shoutcast1_vlog103s=NULL; - rlm_shoutcast1_vlog104s=NULL; - rlm_shoutcast1_vlog105s=NULL; - rlm_shoutcast1_vlog106s=NULL; - rlm_shoutcast1_vlog107s=NULL; - rlm_shoutcast1_vlog108s=NULL; - rlm_shoutcast1_vlog109s=NULL; - rlm_shoutcast1_vlog110s=NULL; - rlm_shoutcast1_vlog111s=NULL; - rlm_shoutcast1_vlog112s=NULL; - rlm_shoutcast1_vlog113s=NULL; - rlm_shoutcast1_vlog114s=NULL; - rlm_shoutcast1_vlog115s=NULL; - rlm_shoutcast1_vlog116s=NULL; - rlm_shoutcast1_vlog117s=NULL; - rlm_shoutcast1_vlog118s=NULL; - rlm_shoutcast1_vlog119s=NULL; - rlm_shoutcast1_vlog120s=NULL; - - sprintf(section,"Shoutcast%d",i++); - strncpy(password,RLMGetStringValue(ptr,arg,section,"Password",""),255); - password[255]=0; - if(strlen(password)==0) { - RLMLog(ptr,LOG_WARNING,"rlm_shoutcast1: no shoutcast servers specified"); - return; - } - while(strlen(password)>0) { - rlm_shoutcast1_passwords=realloc(rlm_shoutcast1_passwords, - (rlm_shoutcast1_devs+1)*(rlm_shoutcast1_devs+1)*256); - strcpy(rlm_shoutcast1_passwords+256*rlm_shoutcast1_devs,password); - rlm_shoutcast1_hostnames=realloc(rlm_shoutcast1_hostnames, - (rlm_shoutcast1_devs+1)*(rlm_shoutcast1_devs+1)*256); - strcpy(rlm_shoutcast1_hostnames+256*rlm_shoutcast1_devs, - RLMGetStringValue(ptr,arg,section,"Hostname","")); - rlm_shoutcast1_tcpports=realloc(rlm_shoutcast1_tcpports, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_tcpports[rlm_shoutcast1_devs]= - RLMGetIntegerValue(ptr,arg,section,"Tcpport",0); - rlm_shoutcast1_formats=realloc(rlm_shoutcast1_formats,(rlm_shoutcast1_devs+1)*256); - strncpy(rlm_shoutcast1_formats+256*rlm_shoutcast1_devs, - RLMGetStringValue(ptr,arg,section,"FormatString",""),256); - rlm_shoutcast1_masters=realloc(rlm_shoutcast1_masters, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_masters[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"MasterLog"); - rlm_shoutcast1_aux1s=realloc(rlm_shoutcast1_aux1s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_aux1s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"Aux1Log"); - rlm_shoutcast1_aux2s=realloc(rlm_shoutcast1_aux2s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_aux2s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"Aux2Log"); - rlm_shoutcast1_vlog101s=realloc(rlm_shoutcast1_vlog101s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog101s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog101"); - - rlm_shoutcast1_vlog102s=realloc(rlm_shoutcast1_vlog102s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog102s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog102"); - - rlm_shoutcast1_vlog103s=realloc(rlm_shoutcast1_vlog103s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog103s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog103"); - - rlm_shoutcast1_vlog104s=realloc(rlm_shoutcast1_vlog104s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog104s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog104"); - - rlm_shoutcast1_vlog105s=realloc(rlm_shoutcast1_vlog105s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog105s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog105"); - - rlm_shoutcast1_vlog106s=realloc(rlm_shoutcast1_vlog106s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog106s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog106"); - - rlm_shoutcast1_vlog107s=realloc(rlm_shoutcast1_vlog107s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog107s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog107"); - - rlm_shoutcast1_vlog108s=realloc(rlm_shoutcast1_vlog108s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog108s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog108"); - - rlm_shoutcast1_vlog109s=realloc(rlm_shoutcast1_vlog109s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog109s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog109"); - - rlm_shoutcast1_vlog110s=realloc(rlm_shoutcast1_vlog110s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog110s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog110"); - - rlm_shoutcast1_vlog111s=realloc(rlm_shoutcast1_vlog111s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog111s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog111"); - - rlm_shoutcast1_vlog112s=realloc(rlm_shoutcast1_vlog112s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog112s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog112"); - - rlm_shoutcast1_vlog113s=realloc(rlm_shoutcast1_vlog113s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog113s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog113"); - - rlm_shoutcast1_vlog114s=realloc(rlm_shoutcast1_vlog114s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog114s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog114"); - - rlm_shoutcast1_vlog115s=realloc(rlm_shoutcast1_vlog115s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog115s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog115"); - - rlm_shoutcast1_vlog116s=realloc(rlm_shoutcast1_vlog116s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog116s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog116"); - - rlm_shoutcast1_vlog117s=realloc(rlm_shoutcast1_vlog117s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog117s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog117"); - - rlm_shoutcast1_vlog118s=realloc(rlm_shoutcast1_vlog118s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog118s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog118"); - - rlm_shoutcast1_vlog119s=realloc(rlm_shoutcast1_vlog119s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog119s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog119"); - - rlm_shoutcast1_vlog120s=realloc(rlm_shoutcast1_vlog120s, - (rlm_shoutcast1_devs+1)*sizeof(int)); - rlm_shoutcast1_vlog120s[rlm_shoutcast1_devs]= - rlm_shoutcast1_GetLogStatus(ptr,arg,section,"VLog120"); - - sprintf(errtext,"rlm_shoutcast1: configured server \"%s:%d\"",rlm_shoutcast1_hostnames+256*rlm_shoutcast1_devs,rlm_shoutcast1_tcpports[rlm_shoutcast1_devs]); - rlm_shoutcast1_devs++; - RLMLog(ptr,LOG_INFO,errtext); - sprintf(section,"Shoutcast%d",i++); - strncpy(password,RLMGetStringValue(ptr,arg,section,"Password",""),255); - password[255]=0; - } -} - - -void rlm_shoutcast1_RLMFree(void *ptr) -{ - free(rlm_shoutcast1_passwords); - free(rlm_shoutcast1_hostnames); - free(rlm_shoutcast1_tcpports); - free(rlm_shoutcast1_formats); - free(rlm_shoutcast1_masters); - free(rlm_shoutcast1_aux1s); - free(rlm_shoutcast1_aux2s); - free(rlm_shoutcast1_vlog101s); - free(rlm_shoutcast1_vlog102s); - free(rlm_shoutcast1_vlog103s); - free(rlm_shoutcast1_vlog104s); - free(rlm_shoutcast1_vlog105s); - free(rlm_shoutcast1_vlog106s); - free(rlm_shoutcast1_vlog107s); - free(rlm_shoutcast1_vlog108s); - free(rlm_shoutcast1_vlog109s); - free(rlm_shoutcast1_vlog110s); - free(rlm_shoutcast1_vlog111s); - free(rlm_shoutcast1_vlog112s); - free(rlm_shoutcast1_vlog113s); - free(rlm_shoutcast1_vlog114s); - free(rlm_shoutcast1_vlog115s); - free(rlm_shoutcast1_vlog116s); - free(rlm_shoutcast1_vlog117s); - free(rlm_shoutcast1_vlog118s); - free(rlm_shoutcast1_vlog119s); - free(rlm_shoutcast1_vlog120s); -} - - -void rlm_shoutcast1_RLMPadDataSent(void *ptr,const struct rlm_svc *svc, - const struct rlm_log *log, - const struct rlm_pad *now, - const struct rlm_pad *next) -{ - int i; - int flag=0; - char str[1024]; - char account[1024]; - char url[1024]; - char msg[1500]; - char user_agent[255]; - - for(i=0;ilog_mach) { - case 0: - flag=rlm_shoutcast1_masters[i]; - break; - - case 1: - flag=rlm_shoutcast1_aux1s[i]; - break; - - case 2: - flag=rlm_shoutcast1_aux2s[i]; - break; - - case 100: - flag=rlm_shoutcast1_vlog101s[i]; - break; - - case 101: - flag=rlm_shoutcast1_vlog102s[i]; - break; - - case 102: - flag=rlm_shoutcast1_vlog103s[i]; - break; - - case 103: - flag=rlm_shoutcast1_vlog104s[i]; - break; - - case 104: - flag=rlm_shoutcast1_vlog105s[i]; - break; - - case 105: - flag=rlm_shoutcast1_vlog106s[i]; - break; - - case 106: - flag=rlm_shoutcast1_vlog107s[i]; - break; - - case 107: - flag=rlm_shoutcast1_vlog108s[i]; - break; - - case 108: - flag=rlm_shoutcast1_vlog109s[i]; - break; - - case 109: - flag=rlm_shoutcast1_vlog110s[i]; - break; - - case 110: - flag=rlm_shoutcast1_vlog111s[i]; - break; - - case 111: - flag=rlm_shoutcast1_vlog112s[i]; - break; - - case 112: - flag=rlm_shoutcast1_vlog113s[i]; - break; - - case 113: - flag=rlm_shoutcast1_vlog114s[i]; - break; - - case 114: - flag=rlm_shoutcast1_vlog115s[i]; - break; - - case 115: - flag=rlm_shoutcast1_vlog116s[i]; - break; - - case 116: - flag=rlm_shoutcast1_vlog117s[i]; - break; - - case 117: - flag=rlm_shoutcast1_vlog118s[i]; - break; - - case 118: - flag=rlm_shoutcast1_vlog119s[i]; - break; - - case 119: - flag=rlm_shoutcast1_vlog120s[i]; - break; - } - if((flag==1)||((flag==2)&&(log->log_onair!=0))) { - strncpy(str,RLMResolveNowNext(ptr,now,next, - rlm_shoutcast1_formats+256*i),256); - rlm_shoutcast1_EncodeString(str,1023); - snprintf(account,1024,":%s",rlm_shoutcast1_passwords+256*i); - snprintf(url,1024,"http://%s:%d/admin.cgi?pass=%s&mode=updinfo&song=%s", - rlm_shoutcast1_hostnames+256*i, - rlm_shoutcast1_tcpports[i], - rlm_shoutcast1_passwords+256*i, - str); - /* - * D.N.A.S v1.9.8 refuses to process updates with the default CURL - * user-agent value, hence we lie to it. - */ - strncpy(user_agent,"User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2",255); - if(strlen(now->rlm_title)!=0) { - if(fork()==0) { - execlp("curl","curl","-o","/dev/null","-s","--header",user_agent, - url,(char *)NULL); - RLMLog(ptr,LOG_WARNING,"rlm_shoutcast1: unable to execute curl(1)"); - exit(0); - } - } - snprintf(msg,1500,"rlm_shoutcast1: sending pad update: \"%s\"", - (const char *)str); - RLMLog(ptr,LOG_INFO,msg); - } - } -}