mirror of
https://github.com/ElvishArtisan/rivendell.git
synced 2025-11-26 15:20:29 +01:00
Initial import of CVS-v2_8_branch
This commit is contained in:
42
rlm/Makefile-example
Normal file
42
rlm/Makefile-example
Normal file
@@ -0,0 +1,42 @@
|
||||
## Makefile
|
||||
##
|
||||
## An example Makefile for building Rivendell Loadable Modules
|
||||
##
|
||||
## (C) Copyright 2008-2013 Fred Gleason <fredg@paravelsystems.com>
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU Library 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.
|
||||
##
|
||||
|
||||
OBJS = rlm_ando.rlm\
|
||||
rlm_facebook.rlm\
|
||||
rlm_icecast2.rlm\
|
||||
rlm_inno713.rlm\
|
||||
rlm_liqcomp.rlm\
|
||||
rlm_padpoint.rlm\
|
||||
rlm_serial.rlm\
|
||||
rlm_shoutcast1.rlm\
|
||||
rlm_spinitron_plus.rlm\
|
||||
rlm_spottrap.rlm\
|
||||
rlm_test.rlm\
|
||||
rlm_twitter.rlm\
|
||||
rlm_udp.rlm \
|
||||
rlm_xmpad.rlm
|
||||
|
||||
%.rlm: %.c
|
||||
$(CC) $(CFLAGS) -fPIC -shared $< -o $@
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) *~
|
||||
90
rlm/Makefile.am
Normal file
90
rlm/Makefile.am
Normal file
@@ -0,0 +1,90 @@
|
||||
## automake.am
|
||||
##
|
||||
## Automake.am for rivendell/rlm
|
||||
##
|
||||
## (C) Copyright 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
##
|
||||
## $Id: Makefile.am,v 1.7.4.5 2013/09/12 23:26:11 cvs Exp $
|
||||
##
|
||||
## 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.
|
||||
##
|
||||
## Use automake to process this into a Makefile.in
|
||||
|
||||
AM_CFLAGS = -fPIC -Wall
|
||||
|
||||
RLM_MODULES=rlm_ando.rlm\
|
||||
rlm_facebook.rlm\
|
||||
rlm_filewrite.rlm\
|
||||
rlm_icecast2.rlm\
|
||||
rlm_inno713.rlm\
|
||||
rlm_liqcomp.rlm\
|
||||
rlm_padpoint.rlm\
|
||||
rlm_serial.rlm\
|
||||
rlm_shoutcast1.rlm\
|
||||
rlm_spinitron_plus.rlm\
|
||||
rlm_spottrap.rlm\
|
||||
rlm_test.rlm\
|
||||
rlm_twitter.rlm\
|
||||
rlm_udp.rlm\
|
||||
rlm_xds.rlm\
|
||||
rlm_xmpad.rlm
|
||||
|
||||
all: $(RLM_MODULES)
|
||||
|
||||
%.rlm: %.c
|
||||
$(CC) $(AM_CFLAGS) -I$(top_srcdir) -shared $< -o $@
|
||||
|
||||
install: all
|
||||
mkdir -p $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell
|
||||
cp $(RLM_MODULES) $(DESTDIR)$(prefix)/@RD_LIB_PATH@/rivendell/
|
||||
mkdir -p $(headerdir)
|
||||
cp rlm.h $(headerdir)
|
||||
|
||||
headerdir = $(includedir)/rlm
|
||||
header_HEADERS = rlm.h
|
||||
|
||||
EXTRA_DIST = Makefile-example\
|
||||
rlm.h\
|
||||
rlm_ando.c\
|
||||
rlm_facebook.c\
|
||||
rlm_filewrite.c\
|
||||
rlm_icecast2.c\
|
||||
rlm_inno713.c\
|
||||
rlm_liqcomp.c\
|
||||
rlm_padpoint.c\
|
||||
rlm_serial.c\
|
||||
rlm_shoutcast1.c\
|
||||
rlm_spinitron_plus.c\
|
||||
rlm_spottrap.c\
|
||||
rlm_test.c\
|
||||
rlm_twitter.c\
|
||||
rlm_udp.c\
|
||||
rlm_xds.c\
|
||||
rlm_xmpad.c
|
||||
|
||||
CLEANFILES = *~\
|
||||
*.idb\
|
||||
*ilk\
|
||||
*.obj\
|
||||
*.pdb\
|
||||
*.qm\
|
||||
*.rlm\
|
||||
moc_*
|
||||
|
||||
MAINTAINERCLEANFILES = *~\
|
||||
*.tar.gz\
|
||||
aclocal.m4\
|
||||
configure\
|
||||
Makefile.in\
|
||||
moc_*
|
||||
372
rlm/rlm.h
Normal file
372
rlm/rlm.h
Normal file
@@ -0,0 +1,372 @@
|
||||
/* rlm.h
|
||||
*
|
||||
* The Rivendell Loadable Module Interface
|
||||
*
|
||||
* (C) Copyright 2008-2013 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 interface can be used to create "Rivendell Loadable Modules" [RLMs]
|
||||
* that enable Rivendell's "Now & Next" capability to supply program associated
|
||||
* data [PAD] to external devices and systems. Runtime module configuration
|
||||
* is accomplished in RDAdmin->ManageHosts->RDAirPlay->ConfigureNow&Next.
|
||||
*
|
||||
* Compiled plugins are dynamically loadable libraries (DLLs) and have names
|
||||
* of the form '<basename>.rlm'. The following callbacks are provided:
|
||||
*
|
||||
* void <basename>_RLMStart(void *ptr,const char *arg)
|
||||
* Called once upon RDAirPlay startup. The plugin should do any necessary
|
||||
* startup tasks (opening i/o devices, allocating memory, etc) here. The
|
||||
* single argument 'arg' is a null-terminated string, consisting of the
|
||||
* 'Argument' parameter supplied in the specific runtime configuration
|
||||
* from RDAdmin. The 'ptr' argument is an opaque pointer that is
|
||||
* used as the first argument to the utility functions.
|
||||
*
|
||||
* void <basename>_RLMFree(void *ptr)
|
||||
* Called once upon RDAirPlay shutdown. Any system resources allocated
|
||||
* by the plugin should be released here. The 'ptr' argument is an opaque
|
||||
* pointer that is be used as the first argument to any of the utility
|
||||
* functions.
|
||||
*
|
||||
*
|
||||
* void <basename>_RLMPadDataSent(void *ptr,const struct rlm_svc *svc,
|
||||
* const struct rlm_log *log,
|
||||
* const struct rlm_pad *now,
|
||||
* const struct rlm_pad *next)
|
||||
* Called each time RDAirPlay changes play state on a log. The 'svc'
|
||||
* and 'log' parameters provide information about the current log and
|
||||
* service respectively. The 'ptr' argument is an opaque pointer that
|
||||
* is used as the first argument to the utility functions.
|
||||
*
|
||||
* WARNING: the structures provided in this callback are dynamically
|
||||
* allocated, their scope is valid only within the callback!
|
||||
*
|
||||
* void <basename>_RLMTimerExpired(void *ptr,int timernum)
|
||||
* Called each time the system RLM timer indicated by 'timernum' expires.
|
||||
* See the 'RLMStartTimer()' and 'RLMStopTimer()' functions for info on
|
||||
* using timers. The 'ptr' argument is an opaque pointer that is
|
||||
* used as the first argument to the utility functions.
|
||||
*
|
||||
* void <basename>_RLMSerialDataReceived(void *ptr,int handle,
|
||||
* const char *data,int len)
|
||||
* Called each time data is received on an open tty/serial device. See
|
||||
* the 'RLMOpenSerial()' and 'RLMCloseSerial()' functions for info on
|
||||
* using tty/serial devices. The 'ptr' argument is an opaque pointer
|
||||
* that is used as the first argument to the utility functions.
|
||||
*/
|
||||
|
||||
#ifndef RLM_H
|
||||
#define RLM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RLM Interface Version
|
||||
*/
|
||||
#define RLM_VERSION 17
|
||||
|
||||
/*
|
||||
* Available Timers
|
||||
*/
|
||||
#define RLM_MAX_TIMERS 32
|
||||
|
||||
/*
|
||||
* Timer Modes
|
||||
* (for use in the RLMStartTimer() function).
|
||||
*/
|
||||
#define RLM_TIMER_REPEATING 0
|
||||
#define RLM_TIMER_ONESHOT 1
|
||||
|
||||
/*
|
||||
* Parity Modes
|
||||
* (for use in the RLMOpenSerial() function).
|
||||
*/
|
||||
#define RLM_PARITY_NONE 0
|
||||
#define RLM_PARITY_EVEN 1
|
||||
#define RLM_PARITY_ODD 2
|
||||
|
||||
/*
|
||||
* Cart Types
|
||||
* (for use in the 'rlm_carttype' field of the 'rlm_pad' struct)
|
||||
*/
|
||||
#define RLM_CARTTYPE_ALL 0
|
||||
#define RLM_CARTTYPE_AUDIO 1
|
||||
#define RLM_CARTTYPE_MACRO 2
|
||||
|
||||
/*
|
||||
* Log Machine Modes
|
||||
* (for use in the 'rlm_mode' field of the 'rlm_log' struct)
|
||||
*/
|
||||
#define RLM_LOGMODE_LIVEASSIST 1
|
||||
#define RLM_LOGMODE_AUTOMATIC 2
|
||||
#define RLM_LOGMODE_MANUAL 3
|
||||
|
||||
/*
|
||||
* Data Encodings
|
||||
* (for use in the RLMResolveNowNextEncoded() function).
|
||||
*/
|
||||
#define RLM_ENCODE_NONE 0
|
||||
#define RLM_ENCODE_XML 1
|
||||
#define RLM_ENCODE_URL 2
|
||||
|
||||
/*
|
||||
* Service data structure
|
||||
*/
|
||||
struct rlm_svc {
|
||||
char svc_name[256]; /* Service name */
|
||||
char svc_pgmcode[256]; /* Program Code */
|
||||
char reserved[1536]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
/*
|
||||
* Log data structure
|
||||
*/
|
||||
struct rlm_log {
|
||||
char log_name[65]; /* Log name */
|
||||
uint32_t log_mach; /* Log machine number, 0=Main, 1=Aux 1, 2=Aux2 */
|
||||
char log_onair; /* On-air flag, 0=False, 1=True */
|
||||
uint32_t log_mode; /* Log machine mode, 1=LiveAssist, 2=Automatic, 3=Manual */
|
||||
char reserved[1974]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
/*
|
||||
* Metadata structure
|
||||
*/
|
||||
struct rlm_pad {
|
||||
uint32_t rlm_cartnum; /* Rivendell cart number */
|
||||
uint32_t rlm_len; /* Event length, in milliseconds */
|
||||
char rlm_year[5]; /* Cart year */
|
||||
char rlm_group[11]; /* Rivendell Group Name */
|
||||
char rlm_title[256]; /* Cart 'title' field */
|
||||
char rlm_artist[256]; /* Cart 'artist' field */
|
||||
char rlm_label[65]; /* Cart 'label' field */
|
||||
char rlm_client[65]; /* Cart 'client' field */
|
||||
char rlm_agency[65]; /* Cart 'agency' field */
|
||||
char rlm_comp[65]; /* Cart 'composer' field */
|
||||
char rlm_pub[65]; /* Cart 'publisher' field */
|
||||
char rlm_userdef[256]; /* Cart 'user defined' field */
|
||||
char rlm_album[256]; /* Cart 'album' field */
|
||||
char rlm_isrc[12]; /* Cut International Standard Recording Code */
|
||||
char rlm_isci[32]; /* Cut ISCI Code */
|
||||
char rlm_carttype; /* Cart type, see RLM_CARTTYPE_* defines */
|
||||
char rlm_ext_eventid[33]; /* Event ID, from external scheduler */
|
||||
char rlm_ext_data[33]; /* Data, from external scheduler */
|
||||
char rlm_ext_annctype[1]; /* Announcement Type, from external scheduler */
|
||||
int32_t rlm_start_msec; /* Event start time, milliseconds part */
|
||||
int32_t rlm_start_sec; /* Event start time, seconds part */
|
||||
int32_t rlm_start_min; /* Event start time, minutes part */
|
||||
int32_t rlm_start_hour; /* Event start time, hours part */
|
||||
int32_t rlm_start_day; /* Event start date, day of month part */
|
||||
int32_t rlm_start_mon; /* Event start date, month of year part */
|
||||
int32_t rlm_start_year; /* Event start date, year part */
|
||||
char rlm_conductor[65]; /* Cart 'conductor' field */
|
||||
char rlm_song_id[33]; /* Cart 'songId' field */
|
||||
char rlm_outcue[65]; /* Cut outcue field */
|
||||
char rlm_description[65]; /* Cut description field */
|
||||
char reserved[305]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
/*
|
||||
* Communications Functions
|
||||
*
|
||||
*
|
||||
* Send a UDP packet.
|
||||
*
|
||||
* The <ipaddr> parameter is a null-terminated string consisting of the
|
||||
* IPv4 destination address in dotted-quad notation, and <port> is the
|
||||
* destination UDP port number. All structures are in host (*not* network)
|
||||
* byte order. The data to be sent, of length <len>, is pointed to by
|
||||
* <data>.
|
||||
*/
|
||||
void RLMSendUdp(void *ptr,const char *ipaddr,uint16_t port,
|
||||
const char *data,int len);
|
||||
|
||||
/*
|
||||
* Open a tty device (serial port) for output.
|
||||
*
|
||||
* The <devname> parameter is a null-terminated string consisting of the
|
||||
* name of the tty device to open (e.g. "/dev/ttyS0"). The <speed>,
|
||||
* <parity> and <word_length> parameters define the communications
|
||||
* parameters to be used.
|
||||
*
|
||||
* RETURNS: if successful, a non-negative integer that should be used
|
||||
* as the <handle> argument for the RLMSendSerial() and RLMCloseSerial()
|
||||
* functions. If unsuccessful, a negative integer will be returned.
|
||||
*/
|
||||
int RLMOpenSerial(void *ptr,const char *devname,int speed,
|
||||
int parity,int word_length);
|
||||
|
||||
/*
|
||||
* Output data on a tty device.
|
||||
*
|
||||
* Output data of length <len> pointed to by <data> on the tty device
|
||||
* indicated by the <handle> value returned by the RLMOpenSerial() function.
|
||||
*/
|
||||
void RLMSendSerial(void *ptr,int handle,const char *data,int len);
|
||||
|
||||
/*
|
||||
* Close a tty device.
|
||||
*
|
||||
* Close the tty device indicated by the <handle> value returned by the
|
||||
* RLMOpenSerial() function.
|
||||
*/
|
||||
void RLMCloseSerial(void *ptr,int handle);
|
||||
|
||||
/*
|
||||
* Convienence Functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get a string indicating the system time.
|
||||
*
|
||||
* Returns a pointer to a null-terminated string indicating the system time,
|
||||
* formatted as per the <format> argument. The following wildcards are
|
||||
* supported:
|
||||
* d the day as number without a leading zero (1-31)
|
||||
* dd the day as number with a leading zero (01-31)
|
||||
* ddd the abbreviated localized day name (e.g. 'Mon'..'Sun').
|
||||
* dddd the long localized day name (e.g. 'Monday'..'Sunday').
|
||||
* M the month as number without a leading zero (1-12)
|
||||
* MM the month as number with a leading zero (01-12)
|
||||
* MMM the abbreviated localized month name (e.g. 'Jan'..'Dec').
|
||||
* MMMM the long localized month name (e.g. 'January'..'December').
|
||||
* yy the year as two digit number (00-99)
|
||||
* yyyy the year as four digit number (1752-8000)
|
||||
* h the hour without a leading zero (0..23 or 1..12 if AM/PM
|
||||
* display)
|
||||
* hh the hour with a leading zero (00..23 or 01..12 if AM/PM display)
|
||||
* m the minute without a leading zero (0..59)
|
||||
* mm the minute with a leading zero (00..59)
|
||||
* s the second whithout a leading zero (0..59)
|
||||
* ss the second whith a leading zero (00..59)
|
||||
* z the milliseconds without leading zeroes (0..999)
|
||||
* zzz the milliseconds with leading zeroes (000..999)
|
||||
* AP use AM/PM display. AP will be replaced by either "AM" or "PM".
|
||||
* ap use am/pm display. ap will be replaced by either "am" or "pm".
|
||||
*
|
||||
* RETURNS: A pointer to a null terminated string. This string is statically
|
||||
* allocated, and may be reused in subsequent calls to the utility functions.
|
||||
*/
|
||||
const char *RLMDateTime(void *ptr,int offset_msecs,const char *format);
|
||||
|
||||
/*
|
||||
* Resolve standard Rivendell Now & Next wildcards, with the possiblity
|
||||
* to encode the PAD fields.
|
||||
*
|
||||
* Returns a pointer to a null-terminated string resulting from resolving
|
||||
* the 'standard' Rivendell Now & Next wildcards in accordance with the
|
||||
* data values in the <now> and <next> parameters. The following wildcards
|
||||
* are supported:
|
||||
*
|
||||
* Now Next Field
|
||||
* ----------------------------------------------
|
||||
* %n %N The Rivendell cart number
|
||||
* %h %H Event length (in milliseconds)
|
||||
* %g %G The Rivendell group name
|
||||
* %t %T Title
|
||||
* %a %A Artist
|
||||
* %l %L Album
|
||||
* %y %Y Year
|
||||
* %b %B Record Label
|
||||
* %c %C Client
|
||||
* %e %E Agency
|
||||
* %m %M Composer
|
||||
* %p %P Publisher
|
||||
* %r %R Conductor
|
||||
* %s %S Song ID
|
||||
* %u %U User Definied
|
||||
* %o %O Outcue
|
||||
* %i %I Description
|
||||
* %D(<dt>) The current date/time, formatted according to <dt>. <dt>
|
||||
* can be any of the wildcards supported by the RLMDateTime()
|
||||
* function (see above).
|
||||
*
|
||||
* Additionally, an encoding can be specified to allow PAD fields to be
|
||||
* escaped for a particular format. Available encodings are:
|
||||
*
|
||||
* RLM_ENCODE_NONE - Perform no character escaping.
|
||||
* RLM_ENCODE_XML - Escape reserved characters as per XML-v1.0
|
||||
* RLM_ENCODE_URL - Escape reserved characters as per RFC 2396 Section 2.4
|
||||
*
|
||||
* RETURNS: A pointer to a null terminated string. This string is statically
|
||||
* allocated, and may be reused in subsequent calls to the utility functions.
|
||||
*/
|
||||
const char *RLMResolveNowNextEncoded(void *ptr,const struct rlm_pad *now,
|
||||
const struct rlm_pad *next,
|
||||
const char *format,int encoding);
|
||||
|
||||
/*
|
||||
* Resolve standard Rivendell Now & Next wildcards
|
||||
*
|
||||
* (NOTE: This function is deprecated, and included merely to keep old code
|
||||
* working. It should *not* be used in new code. For a better alternative,
|
||||
* see the RLMResolveNowNextEncoded() function above).
|
||||
*
|
||||
* Returns a pointer to a null-terminated string resulting from resolving
|
||||
* the 'standard' Rivendell Now & Next wildcards in accordance with the
|
||||
* data values in the <now> and <next> parameters. The following wildcards
|
||||
* are supported:
|
||||
*
|
||||
* Now Next Field
|
||||
* ----------------------------------------------
|
||||
* %n %N The Rivendell cart number
|
||||
* %h %H Event length (in milliseconds)
|
||||
* %g %G The Rivendell group name
|
||||
* %t %T Title
|
||||
* %a %A Artist
|
||||
* %l %L Album
|
||||
* %y %Y Year
|
||||
* %b %B Record Label
|
||||
* %c %C Client
|
||||
* %e %E Agency
|
||||
* %m %M Composer
|
||||
* %p %P Publisher
|
||||
* %r %R Conductor
|
||||
* %s %S Song ID
|
||||
* %u %U User Definied
|
||||
* %o %O Outcue
|
||||
* %d %D Cut Description
|
||||
*
|
||||
* RETURNS: A pointer to a null terminated string. This string is statically
|
||||
* allocated, and may be reused in subsequent calls to the utility functions.
|
||||
*/
|
||||
const char *RLMResolveNowNext(void *ptr,const struct rlm_pad *now,
|
||||
const struct rlm_pad *next,const char *format);
|
||||
|
||||
void RLMLog(void *ptr,int prio,const char *msg);
|
||||
void RLMStartTimer(void *ptr,int timernum,int msecs,int mode);
|
||||
void RLMStopTimer(void *ptr,int timernum);
|
||||
int RLMGetIntegerValue(void *ptr,const char *filename,const char *section,
|
||||
const char *label,int default_value);
|
||||
int RLMGetHexValue(void *ptr,const char *filename,
|
||||
const char *section,const char *label,int default_value);
|
||||
int RLMGetBooleanValue(void *ptr,const char *filename,
|
||||
const char *section,const char *label,
|
||||
int default_value);
|
||||
const char *RLMGetStringValue(void *ptr,const char *filename,
|
||||
const char *section,const char *label,
|
||||
const char *default_value);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RLM_H */
|
||||
217
rlm/rlm_ando.c
Normal file
217
rlm/rlm_ando.c
Normal file
@@ -0,0 +1,217 @@
|
||||
/* rlm_ando.c
|
||||
*
|
||||
* (C) Copyright 2009 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data to an
|
||||
* ANDO Media Streaming system. Options are specified in the configuration
|
||||
* file pointed to by the plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_ando.rlm rlm_ando.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_ando_devs;
|
||||
char *rlm_ando_addresses;
|
||||
uint16_t *rlm_ando_ports;
|
||||
char *rlm_ando_titles;
|
||||
char *rlm_ando_artists;
|
||||
char *rlm_ando_albums;
|
||||
char *rlm_ando_labels;
|
||||
int *rlm_ando_masters;
|
||||
int *rlm_ando_aux1s;
|
||||
int *rlm_ando_aux2s;
|
||||
|
||||
int rlm_ando_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_ando_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[17];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_ando_devs=0;
|
||||
rlm_ando_addresses=NULL;
|
||||
rlm_ando_ports=NULL;
|
||||
rlm_ando_masters=NULL;
|
||||
rlm_ando_aux1s=NULL;
|
||||
rlm_ando_aux2s=NULL;
|
||||
|
||||
sprintf(section,"System%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
if(strlen(address)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_ando: no ando destinations specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(address)>0) {
|
||||
rlm_ando_addresses=
|
||||
realloc(rlm_ando_addresses,(rlm_ando_devs+1)*(rlm_ando_devs+1)*16);
|
||||
strcpy(rlm_ando_addresses+16*rlm_ando_devs,address);
|
||||
rlm_ando_ports=realloc(rlm_ando_ports,(rlm_ando_devs+1)*sizeof(uint16_t));
|
||||
rlm_ando_ports[rlm_ando_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"UdpPort",0);
|
||||
rlm_ando_titles=realloc(rlm_ando_titles,(rlm_ando_devs+1)*256);
|
||||
strncpy(rlm_ando_titles+256*rlm_ando_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Title",""),256);
|
||||
rlm_ando_artists=realloc(rlm_ando_artists,(rlm_ando_devs+1)*256);
|
||||
strncpy(rlm_ando_artists+256*rlm_ando_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Artist",""),256);
|
||||
rlm_ando_albums=realloc(rlm_ando_albums,(rlm_ando_devs+1)*256);
|
||||
strncpy(rlm_ando_albums+256*rlm_ando_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Album",""),256);
|
||||
rlm_ando_labels=realloc(rlm_ando_labels,(rlm_ando_devs+1)*256);
|
||||
strncpy(rlm_ando_labels+256*rlm_ando_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Label",""),256);
|
||||
rlm_ando_masters=realloc(rlm_ando_masters,
|
||||
(rlm_ando_devs+1)*sizeof(int));
|
||||
rlm_ando_masters[rlm_ando_devs]=
|
||||
rlm_ando_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_ando_aux1s=realloc(rlm_ando_aux1s,
|
||||
(rlm_ando_devs+1)*sizeof(int));
|
||||
rlm_ando_aux1s[rlm_ando_devs]=
|
||||
rlm_ando_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_ando_aux2s=realloc(rlm_ando_aux2s,
|
||||
(rlm_ando_devs+1)*sizeof(int));
|
||||
rlm_ando_aux2s[rlm_ando_devs]=
|
||||
rlm_ando_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_ando: configured destination \"%s:%d\"",address,
|
||||
rlm_ando_ports[rlm_ando_devs]);
|
||||
rlm_ando_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"System%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
}
|
||||
RLMStartTimer(ptr,0,30000,RLM_TIMER_REPEATING);
|
||||
}
|
||||
|
||||
|
||||
void rlm_ando_RLMFree(void *ptr)
|
||||
{
|
||||
RLMStopTimer(ptr,0);
|
||||
free(rlm_ando_addresses);
|
||||
free(rlm_ando_ports);
|
||||
free(rlm_ando_titles);
|
||||
free(rlm_ando_artists);
|
||||
free(rlm_ando_albums);
|
||||
free(rlm_ando_labels);
|
||||
free(rlm_ando_masters);
|
||||
free(rlm_ando_aux1s);
|
||||
free(rlm_ando_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_ando_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 fmt[1024];
|
||||
char msg[1500];
|
||||
int hours;
|
||||
int minutes;
|
||||
int seconds;
|
||||
|
||||
for(i=0;i<rlm_ando_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_ando_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_ando_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_ando_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
if(strlen(rlm_ando_labels+256*i)==0) { // Original format
|
||||
snprintf(fmt,1024,"^%s~%s~%02d:%02d~%%g~%s~%%n|",
|
||||
rlm_ando_artists+256*i,
|
||||
rlm_ando_titles+256*i,
|
||||
now->rlm_len/60000,(now->rlm_len%60000)/1000,
|
||||
rlm_ando_albums+256*i);
|
||||
}
|
||||
else { // Enhanced format
|
||||
hours=now->rlm_len/3600000;
|
||||
minutes=(now->rlm_len-hours*3600000)/60000;
|
||||
seconds=(now->rlm_len-hours*3600000-minutes*60000)/1000;
|
||||
snprintf(fmt,1024,"^%s~%s~%02d:%02d:%02d~%%g~%%n~%s~%s|",
|
||||
rlm_ando_artists+256*i,
|
||||
rlm_ando_titles+256*i,
|
||||
hours,minutes,seconds,
|
||||
rlm_ando_albums+256*i,
|
||||
rlm_ando_labels+256*i);
|
||||
}
|
||||
const char *str=RLMResolveNowNext(ptr,now,next,fmt);
|
||||
RLMSendUdp(ptr,rlm_ando_addresses+i*16,rlm_ando_ports[i],str,strlen(str));
|
||||
snprintf(msg,1500,"rlm_ando: sending pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_ando_RLMTimerExpired(void *ptr,int timernum)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch(timernum) {
|
||||
case 0: // Heartbeat
|
||||
for(i=0;i<rlm_ando_devs;i++) {
|
||||
RLMSendUdp(ptr,rlm_ando_addresses+i*16,rlm_ando_ports[i],"HB",2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
316
rlm/rlm_facebook.c
Normal file
316
rlm/rlm_facebook.c
Normal file
@@ -0,0 +1,316 @@
|
||||
/* rlm_facebook.c
|
||||
*
|
||||
* (C) Copyright 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data
|
||||
* to the Facebook account(s) specified in the configuration file pointed
|
||||
* to by the plugin argument. For information about the Facebook service,
|
||||
* see http://www.facebook.com/.
|
||||
*
|
||||
* 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_facebook.rlm rlm_facebook.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_facebook_devs;
|
||||
char *rlm_facebook_addresses;
|
||||
char *rlm_facebook_passwords;
|
||||
char *rlm_facebook_formats;
|
||||
int *rlm_facebook_masters;
|
||||
int *rlm_facebook_aux1s;
|
||||
int *rlm_facebook_aux2s;
|
||||
char *rlm_facebook_cookies;
|
||||
|
||||
|
||||
int rlm_facebook_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<dOldSize;i++) {
|
||||
sString[i]=sString[i-dDiff];
|
||||
}
|
||||
return dNewSize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int rlm_facebook_EncodeString(char *sString,int dMaxSize)
|
||||
{
|
||||
int i; /* General Purpose Counter */
|
||||
char sAccum[4]; /* General String Buffer */
|
||||
|
||||
i=0;
|
||||
while(sString[i]!=0) {
|
||||
if(((sString[i]!=' ') && (sString[i]!='*') && (sString[i]!='-') &&
|
||||
(sString[i]!='_') && (sString[i]!='.')) &&
|
||||
((sString[i]<'0') ||
|
||||
((sString[i]>'9') && (sString[i]<'A')) ||
|
||||
((sString[i]>'Z') && (sString[i]<'a')) ||
|
||||
(sString[i]>'z'))) {
|
||||
if(rlm_facebook_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++;
|
||||
}
|
||||
return strlen(sString);
|
||||
}
|
||||
|
||||
|
||||
void rlm_facebook_Login(int config)
|
||||
{
|
||||
char cmd[1024];
|
||||
|
||||
unlink(rlm_facebook_cookies+256*config); /* Cleanup from past session */
|
||||
snprintf(cmd,1024,
|
||||
"curl -o /dev/null -s -A Mozilla/4.0 -c %s http://www.facebook.com/",
|
||||
rlm_facebook_cookies+256*config);
|
||||
system(cmd);
|
||||
snprintf(cmd,1024,"curl -o /dev/null -s --insecure -A Mozilla/4.0 -c %s -b %s -d persistent=1 -d email=%s -d pass=%s https://login.facebook.com/login.php",
|
||||
rlm_facebook_cookies+256*config,
|
||||
rlm_facebook_cookies+256*config,
|
||||
rlm_facebook_addresses+256*config,
|
||||
rlm_facebook_passwords+256*config);
|
||||
system(cmd);
|
||||
}
|
||||
|
||||
|
||||
void rlm_facebook_Logout(int config)
|
||||
{
|
||||
if(fork()==0) {
|
||||
execlp("curl","curl","-A","Mozilla/4.0","-b",
|
||||
rlm_facebook_cookies+256*config,
|
||||
"-o","/dev/null","-s",
|
||||
"http://www.facebook.com/logout.php",
|
||||
(char *)NULL);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int rlm_facebook_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_facebook_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[256];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_facebook_devs=0;
|
||||
rlm_facebook_addresses=NULL;
|
||||
rlm_facebook_passwords=NULL;
|
||||
rlm_facebook_formats=NULL;
|
||||
rlm_facebook_masters=NULL;
|
||||
rlm_facebook_aux1s=NULL;
|
||||
rlm_facebook_aux2s=NULL;
|
||||
rlm_facebook_cookies=NULL;
|
||||
|
||||
sprintf(section,"Facebook%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"EmailAddress",""),255);
|
||||
address[255]=0;
|
||||
if(strlen(address)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_facebook: no facebook accounts specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(address)>0) {
|
||||
rlm_facebook_addresses=realloc(rlm_facebook_addresses,
|
||||
(rlm_facebook_devs+1)*(rlm_facebook_devs+1)*256);
|
||||
strcpy(rlm_facebook_addresses+256*rlm_facebook_devs,address);
|
||||
rlm_facebook_EncodeString(rlm_facebook_addresses+256*rlm_facebook_devs,255);
|
||||
rlm_facebook_passwords=realloc(rlm_facebook_passwords,
|
||||
(rlm_facebook_devs+1)*(rlm_facebook_devs+1)*256);
|
||||
strcpy(rlm_facebook_passwords+256*rlm_facebook_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Password",""));
|
||||
rlm_facebook_EncodeString(rlm_facebook_passwords+256*rlm_facebook_devs,255);
|
||||
rlm_facebook_formats=realloc(rlm_facebook_formats,(rlm_facebook_devs+1)*256);
|
||||
strncpy(rlm_facebook_formats+256*rlm_facebook_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString",""),256);
|
||||
rlm_facebook_masters=realloc(rlm_facebook_masters,
|
||||
(rlm_facebook_devs+1)*sizeof(int));
|
||||
rlm_facebook_masters[rlm_facebook_devs]=
|
||||
rlm_facebook_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_facebook_aux1s=realloc(rlm_facebook_aux1s,
|
||||
(rlm_facebook_devs+1)*sizeof(int));
|
||||
rlm_facebook_aux1s[rlm_facebook_devs]=
|
||||
rlm_facebook_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_facebook_aux2s=realloc(rlm_facebook_aux2s,
|
||||
(rlm_facebook_devs+1)*sizeof(int));
|
||||
rlm_facebook_aux2s[rlm_facebook_devs]=
|
||||
rlm_facebook_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_facebook: configured account \"%s\"",address);
|
||||
rlm_facebook_cookies=
|
||||
realloc(rlm_facebook_cookies,(rlm_facebook_devs+1)*256);
|
||||
snprintf(rlm_facebook_cookies+rlm_facebook_devs*256,256,
|
||||
"/tmp/rlm_facebook%d_cookies.txt",rlm_facebook_devs+1);
|
||||
rlm_facebook_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"Facebook%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"EmailAddress",""),255);
|
||||
address[255]=0;
|
||||
}
|
||||
|
||||
for(i=0;i<(rlm_facebook_devs);i++) {
|
||||
rlm_facebook_Login(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_facebook_RLMFree(void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<(rlm_facebook_devs);i++) {
|
||||
rlm_facebook_Logout(i);
|
||||
}
|
||||
free(rlm_facebook_addresses);
|
||||
free(rlm_facebook_passwords);
|
||||
free(rlm_facebook_formats);
|
||||
free(rlm_facebook_masters);
|
||||
free(rlm_facebook_aux1s);
|
||||
free(rlm_facebook_aux2s);
|
||||
free(rlm_facebook_cookies);
|
||||
}
|
||||
|
||||
|
||||
void rlm_facebook_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 pad[1024];
|
||||
char msg[1500];
|
||||
|
||||
for(i=0;i<rlm_facebook_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_facebook_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_facebook_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_facebook_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
strncpy(str,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_facebook_formats+256*i),256);
|
||||
rlm_facebook_EncodeString(str,1023);
|
||||
snprintf(pad,1024,"status=%s",str);
|
||||
if(strlen(now->rlm_title)!=0) {
|
||||
if(fork()==0) {
|
||||
execlp("curl","curl","-A","Mozilla/4.0","-b",
|
||||
rlm_facebook_cookies+256*i,
|
||||
"-d",pad,
|
||||
"-d","test_name=INLINE_STATUS_EDITOR",
|
||||
"-d","action=OTHER_UPDATE",
|
||||
"-d","post_form_id=aae2d1af1c8ed0cd36ade54bc8f48427",
|
||||
"-o","/dev/null","-s",
|
||||
"http://www.facebook.com/updatestatus.php",(char *)NULL);
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_facebook: unable to execute curl(1)");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
snprintf(msg,1500,"rlm_facebook: sending pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
228
rlm/rlm_filewrite.c
Normal file
228
rlm/rlm_filewrite.c
Normal file
@@ -0,0 +1,228 @@
|
||||
/* rlm_filewrite.c
|
||||
*
|
||||
* (C) Copyright 2012 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 write to one or more file(s) on the local system specified in the
|
||||
* configuration file pointed to by the plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_filewrite.rlm rlm_filewrite.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_filewrite_devs;
|
||||
char *rlm_filewrite_filenames;
|
||||
int *rlm_filewrite_appends;
|
||||
char *rlm_filewrite_formats;
|
||||
int *rlm_filewrite_encodings;
|
||||
int *rlm_filewrite_masters;
|
||||
int *rlm_filewrite_aux1s;
|
||||
int *rlm_filewrite_aux2s;
|
||||
|
||||
void rlm_filewrite_ReplaceChar(char c,char *str,int pos)
|
||||
{
|
||||
int i;
|
||||
|
||||
str[pos]=c;
|
||||
for(i=pos+1;i<strlen(str);i++) {
|
||||
str[i]=str[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_filewrite_ProcessString(char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<(strlen(str)-1);i++) {
|
||||
if(str[i]=='\\') {
|
||||
if(str[i+1]=='r') {
|
||||
rlm_filewrite_ReplaceChar(13,str,i);
|
||||
}
|
||||
else {
|
||||
if(str[i+1]=='n') {
|
||||
rlm_filewrite_ReplaceChar(10,str,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int rlm_filewrite_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_filewrite_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char filename[256];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_filewrite_devs=0;
|
||||
rlm_filewrite_filenames=NULL;
|
||||
rlm_filewrite_appends=NULL;
|
||||
rlm_filewrite_formats=NULL;
|
||||
rlm_filewrite_encodings=NULL;
|
||||
rlm_filewrite_masters=NULL;
|
||||
rlm_filewrite_aux1s=NULL;
|
||||
rlm_filewrite_aux2s=NULL;
|
||||
|
||||
sprintf(section,"File%d",i++);
|
||||
strncpy(filename,RLMGetStringValue(ptr,arg,section,"Filename",""),255);
|
||||
filename[255]=0;
|
||||
if(strlen(filename)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_filewrite: no files specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(filename)>0) {
|
||||
rlm_filewrite_filenames=realloc(rlm_filewrite_filenames,
|
||||
(rlm_filewrite_devs+1)*(rlm_filewrite_devs+1)*256);
|
||||
strcpy(rlm_filewrite_filenames+256*rlm_filewrite_devs,filename);
|
||||
rlm_filewrite_appends=realloc(rlm_filewrite_appends,
|
||||
(rlm_filewrite_devs+1)*sizeof(int));
|
||||
rlm_filewrite_appends[rlm_filewrite_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"Append",0);
|
||||
rlm_filewrite_formats=realloc(rlm_filewrite_formats,(rlm_filewrite_devs+1)*256);
|
||||
strncpy(rlm_filewrite_formats+256*rlm_filewrite_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString",""),256);
|
||||
rlm_filewrite_masters=realloc(rlm_filewrite_masters,
|
||||
(rlm_filewrite_devs+1)*sizeof(int));
|
||||
rlm_filewrite_masters[rlm_filewrite_devs]=
|
||||
rlm_filewrite_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
|
||||
rlm_filewrite_encodings=realloc(rlm_filewrite_encodings,
|
||||
(rlm_filewrite_devs+1)*sizeof(int));
|
||||
rlm_filewrite_encodings[rlm_filewrite_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"Encoding",RLM_ENCODE_NONE);
|
||||
rlm_filewrite_aux1s=realloc(rlm_filewrite_aux1s,
|
||||
(rlm_filewrite_devs+1)*sizeof(int));
|
||||
rlm_filewrite_aux1s[rlm_filewrite_devs]=
|
||||
rlm_filewrite_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_filewrite_aux2s=realloc(rlm_filewrite_aux2s,
|
||||
(rlm_filewrite_devs+1)*sizeof(int));
|
||||
rlm_filewrite_aux2s[rlm_filewrite_devs]=
|
||||
rlm_filewrite_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_filewrite: configured file \"%s\"",
|
||||
rlm_filewrite_filenames+256*rlm_filewrite_devs);
|
||||
rlm_filewrite_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"File%d",i++);
|
||||
strncpy(filename,RLMGetStringValue(ptr,arg,section,"Filename",""),255);
|
||||
filename[255]=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_filewrite_RLMFree(void *ptr)
|
||||
{
|
||||
free(rlm_filewrite_filenames);
|
||||
free(rlm_filewrite_appends);
|
||||
free(rlm_filewrite_formats);
|
||||
free(rlm_filewrite_encodings);
|
||||
free(rlm_filewrite_masters);
|
||||
free(rlm_filewrite_aux1s);
|
||||
free(rlm_filewrite_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_filewrite_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[8192];
|
||||
char msg[1500];
|
||||
FILE *f;
|
||||
|
||||
for(i=0;i<rlm_filewrite_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_filewrite_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_filewrite_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_filewrite_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
strncpy(str,RLMResolveNowNextEncoded(ptr,now,next,
|
||||
rlm_filewrite_formats+256*i,
|
||||
rlm_filewrite_encodings[i]),8192);
|
||||
rlm_filewrite_ProcessString(str);
|
||||
if(rlm_filewrite_appends[i]==0) {
|
||||
f=fopen(rlm_filewrite_filenames+256*i,"w");
|
||||
}
|
||||
else {
|
||||
f=fopen(rlm_filewrite_filenames+256*i,"a");
|
||||
}
|
||||
if(f!=NULL) {
|
||||
snprintf(msg,1500,"rlm_filewrite: sending pad update: \"%s\" to \"%s\"",
|
||||
str,rlm_filewrite_filenames+256*i);
|
||||
fprintf(f,"%s",str);
|
||||
fclose(f);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
else {
|
||||
snprintf(msg,1500,"rlm_filewrite: unable to open file \"%s\"",
|
||||
rlm_filewrite_filenames+256*i);
|
||||
RLMLog(ptr,LOG_WARNING,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
295
rlm/rlm_icecast2.c
Normal file
295
rlm/rlm_icecast2.c
Normal file
@@ -0,0 +1,295 @@
|
||||
/* rlm_icecast2.c
|
||||
*
|
||||
* (C) Copyright 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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_icecast2.rlm rlm_icecast2.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_icecast2_devs;
|
||||
char *rlm_icecast2_usernames;
|
||||
char *rlm_icecast2_passwords;
|
||||
char *rlm_icecast2_hostnames;
|
||||
int *rlm_icecast2_tcpports;
|
||||
char *rlm_icecast2_mountpoints;
|
||||
char *rlm_icecast2_formats;
|
||||
int *rlm_icecast2_masters;
|
||||
int *rlm_icecast2_aux1s;
|
||||
int *rlm_icecast2_aux2s;
|
||||
|
||||
|
||||
int rlm_icecast2_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<dOldSize;i++) {
|
||||
sString[i]=sString[i-dDiff];
|
||||
}
|
||||
return dNewSize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int rlm_icecast2_EncodeString(char *sString,int dMaxSize)
|
||||
{
|
||||
int i; /* General Purpose Counter */
|
||||
char sAccum[4]; /* General String Buffer */
|
||||
|
||||
i=0;
|
||||
while(sString[i]!=0) {
|
||||
if(((sString[i]!='*') && (sString[i]!='-') &&
|
||||
(sString[i]!='_') && (sString[i]!='.')) &&
|
||||
((sString[i]<'0') ||
|
||||
((sString[i]>'9') && (sString[i]<'A')) ||
|
||||
((sString[i]>'Z') && (sString[i]<'a')) ||
|
||||
(sString[i]>'z'))) {
|
||||
if(rlm_icecast2_BufferDiff(sString,i,2,dMaxSize)<0) {
|
||||
fprintf(stderr,"rlm_icecast2: BufferDiff() failed, maxsize: %d\n",
|
||||
dMaxSize);
|
||||
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) {
|
||||
fprintf(stderr,"rlm_icecast2: offset exceeded limit, maxsize: %d\n",
|
||||
dMaxSize);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return strlen(sString);
|
||||
}
|
||||
|
||||
|
||||
int rlm_icecast2_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_icecast2_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char username[256];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_icecast2_devs=0;
|
||||
rlm_icecast2_usernames=NULL;
|
||||
rlm_icecast2_passwords=NULL;
|
||||
rlm_icecast2_formats=NULL;
|
||||
rlm_icecast2_masters=NULL;
|
||||
rlm_icecast2_aux1s=NULL;
|
||||
rlm_icecast2_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Icecast%d",i++);
|
||||
strncpy(username,RLMGetStringValue(ptr,arg,section,"Username",""),255);
|
||||
username[255]=0;
|
||||
if(strlen(username)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_icecast2: no icecast mountpoints specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(username)>0) {
|
||||
rlm_icecast2_usernames=realloc(rlm_icecast2_usernames,
|
||||
(rlm_icecast2_devs+1)*(rlm_icecast2_devs+1)*256);
|
||||
strcpy(rlm_icecast2_usernames+256*rlm_icecast2_devs,username);
|
||||
|
||||
rlm_icecast2_passwords=realloc(rlm_icecast2_passwords,
|
||||
(rlm_icecast2_devs+1)*(rlm_icecast2_devs+1)*256);
|
||||
strcpy(rlm_icecast2_passwords+256*rlm_icecast2_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Password",""));
|
||||
rlm_icecast2_hostnames=realloc(rlm_icecast2_hostnames,
|
||||
(rlm_icecast2_devs+1)*(rlm_icecast2_devs+1)*256);
|
||||
strcpy(rlm_icecast2_hostnames+256*rlm_icecast2_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Hostname",""));
|
||||
rlm_icecast2_tcpports=realloc(rlm_icecast2_tcpports,
|
||||
(rlm_icecast2_devs+1)*sizeof(int));
|
||||
rlm_icecast2_tcpports[rlm_icecast2_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"Tcpport",0);
|
||||
rlm_icecast2_mountpoints=realloc(rlm_icecast2_mountpoints,
|
||||
(rlm_icecast2_devs+1)*(rlm_icecast2_devs+1)*256);
|
||||
strcpy(rlm_icecast2_mountpoints+256*rlm_icecast2_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Mountpoint",""));
|
||||
rlm_icecast2_formats=realloc(rlm_icecast2_formats,(rlm_icecast2_devs+1)*256);
|
||||
strncpy(rlm_icecast2_formats+256*rlm_icecast2_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString",""),256);
|
||||
rlm_icecast2_masters=realloc(rlm_icecast2_masters,
|
||||
(rlm_icecast2_devs+1)*sizeof(int));
|
||||
rlm_icecast2_masters[rlm_icecast2_devs]=
|
||||
rlm_icecast2_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_icecast2_aux1s=realloc(rlm_icecast2_aux1s,
|
||||
(rlm_icecast2_devs+1)*sizeof(int));
|
||||
rlm_icecast2_aux1s[rlm_icecast2_devs]=
|
||||
rlm_icecast2_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_icecast2_aux2s=realloc(rlm_icecast2_aux2s,
|
||||
(rlm_icecast2_devs+1)*sizeof(int));
|
||||
rlm_icecast2_aux2s[rlm_icecast2_devs]=
|
||||
rlm_icecast2_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_icecast2: configured mountpoint \"http://%s:%u%s\"",
|
||||
rlm_icecast2_hostnames+256*rlm_icecast2_devs,
|
||||
rlm_icecast2_tcpports[rlm_icecast2_devs],
|
||||
rlm_icecast2_mountpoints+256*rlm_icecast2_devs);
|
||||
rlm_icecast2_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"Icecast%d",i++);
|
||||
strncpy(username,RLMGetStringValue(ptr,arg,section,"Username",""),255);
|
||||
username[255]=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_icecast2_RLMFree(void *ptr)
|
||||
{
|
||||
free(rlm_icecast2_usernames);
|
||||
free(rlm_icecast2_passwords);
|
||||
free(rlm_icecast2_hostnames);
|
||||
free(rlm_icecast2_tcpports);
|
||||
free(rlm_icecast2_mountpoints);
|
||||
free(rlm_icecast2_formats);
|
||||
free(rlm_icecast2_masters);
|
||||
free(rlm_icecast2_aux1s);
|
||||
free(rlm_icecast2_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_icecast2_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];
|
||||
|
||||
for(i=0;i<rlm_icecast2_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_icecast2_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_icecast2_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_icecast2_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
strncpy(str,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_icecast2_formats+256*i),256);
|
||||
rlm_icecast2_EncodeString(str,1023);
|
||||
snprintf(account,1024,"%s:%s",rlm_icecast2_usernames+256*i,
|
||||
rlm_icecast2_passwords+256*i);
|
||||
snprintf(url,1024,"http://%s:%d/admin/metadata?mount=%s&mode=updinfo&song=%s",
|
||||
rlm_icecast2_hostnames+256*i,
|
||||
rlm_icecast2_tcpports[i],
|
||||
rlm_icecast2_mountpoints+256*i,str);
|
||||
if(strlen(now->rlm_title)!=0) {
|
||||
if(fork()==0) {
|
||||
execlp("curl","curl","-u",account,"-o","/dev/null","-s",
|
||||
url,(char *)NULL);
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_icecast2: unable to execute curl(1)");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
snprintf(msg,1500,"rlm_icecast2: sending pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
253
rlm/rlm_inno713.c
Normal file
253
rlm/rlm_inno713.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/* rlm_inno713.c
|
||||
*
|
||||
* (C) Copyright 2009 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD
|
||||
* to the Innovonics model 713 RDS encoder, as specified in the
|
||||
* configuration file pointed to by the plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_inno713.rlm rlm_inno713.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_inno713_devs;
|
||||
char *rlm_inno713_addresses;
|
||||
uint16_t *rlm_inno713_ports;
|
||||
int *rlm_inno713_handles;
|
||||
char *rlm_inno713_dynamicpss;
|
||||
char *rlm_inno713_pss;
|
||||
char *rlm_inno713_radiotexts;
|
||||
int *rlm_inno713_masters;
|
||||
int *rlm_inno713_aux1s;
|
||||
int *rlm_inno713_aux2s;
|
||||
|
||||
void rlm_inno713_Upcase(char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<strlen(str);i++) {
|
||||
str[i]=toupper(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_inno713_SendString(void *ptr,const struct rlm_pad *now,
|
||||
const struct rlm_pad *next,const char *tag,
|
||||
const char *fmt,const char *addr,uint16_t port,
|
||||
int handle)
|
||||
{
|
||||
char pkt[1024];
|
||||
|
||||
if(strlen(fmt)>0) {
|
||||
const char *str=RLMResolveNowNext(ptr,now,next,fmt);
|
||||
if(strlen(str)>0) {
|
||||
sprintf(pkt,"%s=%s\r\n",tag,str);
|
||||
rlm_inno713_Upcase(pkt);
|
||||
if(strlen(addr)>0) {
|
||||
RLMSendUdp(ptr,addr,port,pkt,strlen(pkt));
|
||||
}
|
||||
if(handle>=0) {
|
||||
RLMSendSerial(ptr,handle,pkt,strlen(pkt));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int rlm_inno713_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_inno713_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[17];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
char device[256];
|
||||
int speed;
|
||||
int parity;
|
||||
int wsize;
|
||||
int i=1;
|
||||
|
||||
rlm_inno713_devs=0;
|
||||
rlm_inno713_addresses=NULL;
|
||||
rlm_inno713_ports=NULL;
|
||||
rlm_inno713_handles=NULL;
|
||||
rlm_inno713_dynamicpss=NULL;
|
||||
rlm_inno713_masters=NULL;
|
||||
rlm_inno713_aux1s=NULL;
|
||||
rlm_inno713_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Rds%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
strncpy(device,RLMGetStringValue(ptr,arg,section,"Device",""),256);
|
||||
if((strlen(address)==0)&&(strlen(device)==0)) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_inno713: no RDS connections specified");
|
||||
return;
|
||||
}
|
||||
while((strlen(address)>0)||(strlen(device)>0)) {
|
||||
rlm_inno713_addresses=
|
||||
realloc(rlm_inno713_addresses,
|
||||
(rlm_inno713_devs+1)*(rlm_inno713_devs+1)*16);
|
||||
strcpy(rlm_inno713_addresses+16*rlm_inno713_devs,address);
|
||||
rlm_inno713_ports=realloc(rlm_inno713_ports,
|
||||
(rlm_inno713_devs+1)*sizeof(uint16_t));
|
||||
rlm_inno713_ports[rlm_inno713_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"UdpPort",0);
|
||||
speed=RLMGetIntegerValue(ptr,arg,section,"Speed",9600);
|
||||
parity=RLMGetIntegerValue(ptr,arg,section,"Parity",0);
|
||||
wsize=RLMGetIntegerValue(ptr,arg,section,"WordSize",8);
|
||||
rlm_inno713_handles=realloc(rlm_inno713_handles,
|
||||
(rlm_inno713_devs+1)*sizeof(int));
|
||||
rlm_inno713_handles[rlm_inno713_devs]=
|
||||
RLMOpenSerial(ptr,device,speed,parity,wsize);
|
||||
rlm_inno713_dynamicpss=realloc(rlm_inno713_dynamicpss,(rlm_inno713_devs+1)*256);
|
||||
strncpy(rlm_inno713_dynamicpss+256*rlm_inno713_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"DynamicPsString",""),256);
|
||||
|
||||
rlm_inno713_pss=realloc(rlm_inno713_pss,(rlm_inno713_devs+1)*256);
|
||||
strncpy(rlm_inno713_pss+256*rlm_inno713_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"PsString",""),256);
|
||||
rlm_inno713_radiotexts=realloc(rlm_inno713_radiotexts,
|
||||
(rlm_inno713_devs+1)*256);
|
||||
strncpy(rlm_inno713_radiotexts+256*rlm_inno713_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"RadiotextString",""),256);
|
||||
rlm_inno713_masters=realloc(rlm_inno713_masters,
|
||||
(rlm_inno713_devs+1)*sizeof(int));
|
||||
rlm_inno713_masters[rlm_inno713_devs]=
|
||||
rlm_inno713_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_inno713_aux1s=realloc(rlm_inno713_aux1s,
|
||||
(rlm_inno713_devs+1)*sizeof(int));
|
||||
rlm_inno713_aux1s[rlm_inno713_devs]=
|
||||
rlm_inno713_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_inno713_aux2s=realloc(rlm_inno713_aux2s,
|
||||
(rlm_inno713_devs+1)*sizeof(int));
|
||||
rlm_inno713_aux2s[rlm_inno713_devs]=
|
||||
rlm_inno713_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_inno713: configured destination \"%s:%d\"",address,
|
||||
rlm_inno713_ports[rlm_inno713_devs]);
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
if(strlen(device)>0) {
|
||||
if(rlm_inno713_handles[rlm_inno713_devs]<0) {
|
||||
sprintf(errtext,"rlm_inno713: unable to open serial device \"%s\"",device);
|
||||
}
|
||||
else {
|
||||
sprintf(errtext,"rlm_inno713: configured serial device \"%s\"",device);
|
||||
}
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
}
|
||||
rlm_inno713_devs++;
|
||||
sprintf(section,"Rds%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
strncpy(device,RLMGetStringValue(ptr,arg,section,"Device",""),256);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_inno713_RLMFree(void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
free(rlm_inno713_addresses);
|
||||
free(rlm_inno713_ports);
|
||||
for(i=0;i<rlm_inno713_devs;i++) {
|
||||
if(rlm_inno713_handles[i]>=0) {
|
||||
RLMCloseSerial(ptr,rlm_inno713_handles[i]);
|
||||
}
|
||||
}
|
||||
free(rlm_inno713_handles);
|
||||
free(rlm_inno713_dynamicpss);
|
||||
free(rlm_inno713_pss);
|
||||
free(rlm_inno713_radiotexts);
|
||||
free(rlm_inno713_masters);
|
||||
free(rlm_inno713_aux1s);
|
||||
free(rlm_inno713_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_inno713_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 msg[1500];
|
||||
|
||||
for(i=0;i<rlm_inno713_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_inno713_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_inno713_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_inno713_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
rlm_inno713_SendString(ptr,now,next,"DPS",rlm_inno713_dynamicpss+256*i,
|
||||
rlm_inno713_addresses+i*16,rlm_inno713_ports[i],
|
||||
rlm_inno713_handles[i]);
|
||||
rlm_inno713_SendString(ptr,now,next,"PS",rlm_inno713_pss+256*i,
|
||||
rlm_inno713_addresses+i*16,rlm_inno713_ports[i],
|
||||
rlm_inno713_handles[i]);
|
||||
rlm_inno713_SendString(ptr,now,next,"TEXT",rlm_inno713_radiotexts+256*i,
|
||||
rlm_inno713_addresses+i*16,rlm_inno713_ports[i],
|
||||
rlm_inno713_handles[i]);
|
||||
|
||||
const char *str=RLMResolveNowNext(ptr,now,next,rlm_inno713_pss+256*i);
|
||||
snprintf(msg,1500,"rlm_inno713: sending pad update: \"%s\"",str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
189
rlm/rlm_liqcomp.c
Normal file
189
rlm/rlm_liqcomp.c
Normal file
@@ -0,0 +1,189 @@
|
||||
/* rlm_liqcomp.c
|
||||
*
|
||||
* (C) Copyright 2009 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data to a
|
||||
* Liquid Compass Internet streaming encoder. Options are specified in the
|
||||
* configuration file pointed to by the plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_liqcomp.rlm rlm_liqcomp.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_liqcomp_devs;
|
||||
char *rlm_liqcomp_addresses;
|
||||
uint16_t *rlm_liqcomp_ports;
|
||||
char *rlm_liqcomp_titles;
|
||||
char *rlm_liqcomp_artists;
|
||||
char *rlm_liqcomp_albums;
|
||||
char *rlm_liqcomp_labels;
|
||||
int *rlm_liqcomp_masters;
|
||||
int *rlm_liqcomp_aux1s;
|
||||
int *rlm_liqcomp_aux2s;
|
||||
|
||||
int rlm_liqcomp_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_liqcomp_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[17];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_liqcomp_devs=0;
|
||||
rlm_liqcomp_addresses=NULL;
|
||||
rlm_liqcomp_ports=NULL;
|
||||
rlm_liqcomp_masters=NULL;
|
||||
rlm_liqcomp_aux1s=NULL;
|
||||
rlm_liqcomp_aux2s=NULL;
|
||||
|
||||
sprintf(section,"System%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
if(strlen(address)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_liqcomp: no encoder destinations specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(address)>0) {
|
||||
rlm_liqcomp_addresses=
|
||||
realloc(rlm_liqcomp_addresses,(rlm_liqcomp_devs+1)*(rlm_liqcomp_devs+1)*16);
|
||||
strcpy(rlm_liqcomp_addresses+16*rlm_liqcomp_devs,address);
|
||||
rlm_liqcomp_ports=realloc(rlm_liqcomp_ports,(rlm_liqcomp_devs+1)*sizeof(uint16_t));
|
||||
rlm_liqcomp_ports[rlm_liqcomp_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"UdpPort",0);
|
||||
rlm_liqcomp_titles=realloc(rlm_liqcomp_titles,(rlm_liqcomp_devs+1)*256);
|
||||
strncpy(rlm_liqcomp_titles+256*rlm_liqcomp_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Title",""),256);
|
||||
rlm_liqcomp_artists=realloc(rlm_liqcomp_artists,(rlm_liqcomp_devs+1)*256);
|
||||
strncpy(rlm_liqcomp_artists+256*rlm_liqcomp_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Artist",""),256);
|
||||
rlm_liqcomp_albums=realloc(rlm_liqcomp_albums,(rlm_liqcomp_devs+1)*256);
|
||||
strncpy(rlm_liqcomp_albums+256*rlm_liqcomp_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Album",""),256);
|
||||
rlm_liqcomp_labels=realloc(rlm_liqcomp_labels,(rlm_liqcomp_devs+1)*256);
|
||||
strncpy(rlm_liqcomp_labels+256*rlm_liqcomp_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Label",""),256);
|
||||
rlm_liqcomp_masters=realloc(rlm_liqcomp_masters,
|
||||
(rlm_liqcomp_devs+1)*sizeof(int));
|
||||
rlm_liqcomp_masters[rlm_liqcomp_devs]=
|
||||
rlm_liqcomp_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_liqcomp_aux1s=realloc(rlm_liqcomp_aux1s,
|
||||
(rlm_liqcomp_devs+1)*sizeof(int));
|
||||
rlm_liqcomp_aux1s[rlm_liqcomp_devs]=
|
||||
rlm_liqcomp_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_liqcomp_aux2s=realloc(rlm_liqcomp_aux2s,
|
||||
(rlm_liqcomp_devs+1)*sizeof(int));
|
||||
rlm_liqcomp_aux2s[rlm_liqcomp_devs]=
|
||||
rlm_liqcomp_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_liqcomp: configured destination \"%s:%d\"",address,
|
||||
rlm_liqcomp_ports[rlm_liqcomp_devs]);
|
||||
rlm_liqcomp_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"System%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_liqcomp_RLMFree(void *ptr)
|
||||
{
|
||||
free(rlm_liqcomp_addresses);
|
||||
free(rlm_liqcomp_ports);
|
||||
free(rlm_liqcomp_titles);
|
||||
free(rlm_liqcomp_artists);
|
||||
free(rlm_liqcomp_albums);
|
||||
free(rlm_liqcomp_labels);
|
||||
free(rlm_liqcomp_masters);
|
||||
free(rlm_liqcomp_aux1s);
|
||||
free(rlm_liqcomp_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_liqcomp_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 fmt[1500];
|
||||
char msg[1500];
|
||||
|
||||
for(i=0;i<rlm_liqcomp_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_liqcomp_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_liqcomp_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_liqcomp_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
snprintf(fmt,1500,"|%s|%s|%06u|%u|%s|%s|%s|\n",
|
||||
rlm_liqcomp_titles+256*i,
|
||||
rlm_liqcomp_artists+256*i,
|
||||
now->rlm_cartnum,
|
||||
now->rlm_len,
|
||||
now->rlm_group,
|
||||
rlm_liqcomp_albums+256*i,
|
||||
rlm_liqcomp_labels+256*i);
|
||||
const char *str=RLMResolveNowNext(ptr,now,next,fmt);
|
||||
RLMSendUdp(ptr,rlm_liqcomp_addresses+i*16,rlm_liqcomp_ports[i],str,
|
||||
strlen(str));
|
||||
snprintf(msg,1500,"rlm_liqcomp: sending pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
175
rlm/rlm_padpoint.c
Normal file
175
rlm/rlm_padpoint.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/* rlm_padpoint.c
|
||||
*
|
||||
* (C) Copyright 2012 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data via
|
||||
* UDP packets to one or more PadPoint PAD processors as specified in the
|
||||
* configuration file pointed to by the plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_padpoint.rlm rlm_padpoint.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_padpoint_devs;
|
||||
char *rlm_padpoint_addresses;
|
||||
uint16_t *rlm_padpoint_ports;
|
||||
int *rlm_padpoint_masters;
|
||||
int *rlm_padpoint_aux1s;
|
||||
int *rlm_padpoint_aux2s;
|
||||
|
||||
int rlm_padpoint_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_padpoint_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[17];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_padpoint_devs=0;
|
||||
rlm_padpoint_addresses=NULL;
|
||||
rlm_padpoint_ports=NULL;
|
||||
rlm_padpoint_masters=NULL;
|
||||
rlm_padpoint_aux1s=NULL;
|
||||
rlm_padpoint_aux2s=NULL;
|
||||
|
||||
sprintf(section,"PadPoint%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
if(strlen(address)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_padpoint: no padpoint destinations specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(address)>0) {
|
||||
rlm_padpoint_addresses=
|
||||
realloc(rlm_padpoint_addresses,(rlm_padpoint_devs+1)*(rlm_padpoint_devs+1)*16);
|
||||
strcpy(rlm_padpoint_addresses+16*rlm_padpoint_devs,address);
|
||||
rlm_padpoint_ports=realloc(rlm_padpoint_ports,(rlm_padpoint_devs+1)*sizeof(uint16_t));
|
||||
rlm_padpoint_ports[rlm_padpoint_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"UdpPort",0);
|
||||
rlm_padpoint_masters=realloc(rlm_padpoint_masters,
|
||||
(rlm_padpoint_devs+1)*sizeof(int));
|
||||
rlm_padpoint_masters[rlm_padpoint_devs]=
|
||||
rlm_padpoint_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_padpoint_aux1s=realloc(rlm_padpoint_aux1s,
|
||||
(rlm_padpoint_devs+1)*sizeof(int));
|
||||
rlm_padpoint_aux1s[rlm_padpoint_devs]=
|
||||
rlm_padpoint_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_padpoint_aux2s=realloc(rlm_padpoint_aux2s,
|
||||
(rlm_padpoint_devs+1)*sizeof(int));
|
||||
rlm_padpoint_aux2s[rlm_padpoint_devs]=
|
||||
rlm_padpoint_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_padpoint: configured destination \"%s:%d\"",address,
|
||||
rlm_padpoint_ports[rlm_padpoint_devs]);
|
||||
rlm_padpoint_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"PadPoint%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_padpoint_RLMFree(void *ptr)
|
||||
{
|
||||
free(rlm_padpoint_addresses);
|
||||
free(rlm_padpoint_ports);
|
||||
free(rlm_padpoint_masters);
|
||||
free(rlm_padpoint_aux1s);
|
||||
free(rlm_padpoint_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_padpoint_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[1501];
|
||||
char msg[2048];
|
||||
|
||||
for(i=0;i<rlm_padpoint_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_padpoint_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_padpoint_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_padpoint_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
snprintf(str,1501,"%06u~%u~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s~%s",
|
||||
now->rlm_cartnum,
|
||||
now->rlm_len,
|
||||
now->rlm_year,
|
||||
now->rlm_group,
|
||||
now->rlm_title,
|
||||
now->rlm_artist,
|
||||
now->rlm_album,
|
||||
now->rlm_label,
|
||||
now->rlm_client,
|
||||
now->rlm_agency,
|
||||
now->rlm_comp,
|
||||
now->rlm_pub,
|
||||
now->rlm_userdef,
|
||||
now->rlm_isrc,
|
||||
now->rlm_isci);
|
||||
RLMSendUdp(ptr,rlm_padpoint_addresses+i*16,rlm_padpoint_ports[i],
|
||||
str,strlen(str));
|
||||
snprintf(msg,1500,"rlm_padpoint: sending pad update: \"%s\"",str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
219
rlm/rlm_serial.c
Normal file
219
rlm/rlm_serial.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/* rlm_serial.c
|
||||
*
|
||||
* (C) Copyright 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data
|
||||
* to the tty device specified in the configuration file pointed to by the
|
||||
* plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_serial.rlm rlm_serial.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_serial_devs;
|
||||
int *rlm_serial_handles;
|
||||
char *rlm_serial_formats;
|
||||
int *rlm_serial_encodings;
|
||||
int *rlm_serial_null_updates;
|
||||
int *rlm_serial_masters;
|
||||
int *rlm_serial_aux1s;
|
||||
int *rlm_serial_aux2s;
|
||||
|
||||
int rlm_serial_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_serial_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
int handle;
|
||||
char device[256];
|
||||
int speed;
|
||||
int parity;
|
||||
int wsize;
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_serial_devs=0;
|
||||
rlm_serial_handles=NULL;
|
||||
rlm_serial_formats=NULL;
|
||||
rlm_serial_encodings=NULL;
|
||||
rlm_serial_null_updates=NULL;
|
||||
rlm_serial_masters=NULL;
|
||||
rlm_serial_aux1s=NULL;
|
||||
rlm_serial_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Serial%d",i++);
|
||||
strncpy(device,RLMGetStringValue(ptr,arg,section,"Device",""),256);
|
||||
if(strlen(device)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_serial: no serial devices specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(device)>0) {
|
||||
speed=RLMGetIntegerValue(ptr,arg,section,"Speed",9600);
|
||||
parity=RLMGetIntegerValue(ptr,arg,section,"Parity",0);
|
||||
wsize=RLMGetIntegerValue(ptr,arg,section,"WordSize",8);
|
||||
if((handle=RLMOpenSerial(ptr,device,speed,parity,wsize))>=0) {
|
||||
rlm_serial_handles=realloc(rlm_serial_handles,
|
||||
(rlm_serial_devs+1)*sizeof(int));
|
||||
rlm_serial_handles[rlm_serial_devs]=handle;
|
||||
rlm_serial_formats=realloc(rlm_serial_formats,(rlm_serial_devs+1)*256);
|
||||
strncpy(rlm_serial_formats+256*rlm_serial_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString",""),256);
|
||||
rlm_serial_masters=realloc(rlm_serial_masters,
|
||||
(rlm_serial_devs+1)*sizeof(int));
|
||||
rlm_serial_masters[rlm_serial_devs]=
|
||||
rlm_serial_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_serial_encodings=realloc(rlm_serial_encodings,
|
||||
(rlm_serial_devs+1)*sizeof(int));
|
||||
rlm_serial_encodings[rlm_serial_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"Encoding",RLM_ENCODE_NONE);
|
||||
|
||||
rlm_serial_null_updates=realloc(rlm_serial_null_updates,
|
||||
(rlm_serial_devs+1)*sizeof(int));
|
||||
rlm_serial_null_updates[rlm_serial_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"ProcessNullUpdates",0);
|
||||
|
||||
|
||||
|
||||
rlm_serial_aux1s=realloc(rlm_serial_aux1s,
|
||||
(rlm_serial_devs+1)*sizeof(int));
|
||||
rlm_serial_aux1s[rlm_serial_devs]=
|
||||
rlm_serial_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_serial_aux2s=realloc(rlm_serial_aux2s,
|
||||
(rlm_serial_devs+1)*sizeof(int));
|
||||
rlm_serial_aux2s[rlm_serial_devs]=
|
||||
rlm_serial_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
rlm_serial_devs++;
|
||||
sprintf(errtext,"rlm_serial: opened device \"%s\"",device);
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
}
|
||||
else {
|
||||
sprintf(errtext,"unable to open tty \"%s\"",device);
|
||||
RLMLog(ptr,LOG_WARNING,errtext);
|
||||
}
|
||||
sprintf(section,"Serial%d",i++);
|
||||
strncpy(device,RLMGetStringValue(ptr,arg,section,"Device",""),256);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_serial_RLMFree(void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<rlm_serial_devs;i++) {
|
||||
RLMCloseSerial(ptr,rlm_serial_handles[i]);
|
||||
}
|
||||
free(rlm_serial_handles);
|
||||
free(rlm_serial_formats);
|
||||
free(rlm_serial_encodings);
|
||||
free(rlm_serial_null_updates);
|
||||
free(rlm_serial_masters);
|
||||
free(rlm_serial_aux1s);
|
||||
free(rlm_serial_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_serial_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 msg[1500];
|
||||
|
||||
for(i=0;i<rlm_serial_devs;i++) {
|
||||
switch(rlm_serial_null_updates[i]) {
|
||||
case 0: /* Process all updates */
|
||||
break;
|
||||
|
||||
case 1: /* Process only non-null NOW updates */
|
||||
if(now->rlm_cartnum==0) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* Process only non-null NEXT updates */
|
||||
if(next->rlm_cartnum==0) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* Process only non-null NOW and NEXT updates */
|
||||
if((now->rlm_cartnum==0)||(next->rlm_cartnum==0)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_serial_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_serial_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_serial_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
const char *str=
|
||||
RLMResolveNowNextEncoded(ptr,now,next,rlm_serial_formats+256*i,
|
||||
rlm_serial_encodings[i]);
|
||||
RLMSendSerial(ptr,rlm_serial_handles[i],str,strlen(str));
|
||||
snprintf(msg,1500,"rlm_serial: sending pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
280
rlm/rlm_shoutcast1.c
Normal file
280
rlm/rlm_shoutcast1.c
Normal file
@@ -0,0 +1,280 @@
|
||||
/* rlm_shoutcast1.c
|
||||
*
|
||||
* (C) Copyright 2011 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
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_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<dOldSize;i++) {
|
||||
sString[i]=sString[i-dDiff];
|
||||
}
|
||||
return dNewSize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int rlm_shoutcast1_EncodeString(char *sString,int dMaxSize)
|
||||
{
|
||||
int i; /* General Purpose Counter */
|
||||
char sAccum[4]; /* General String Buffer */
|
||||
|
||||
i=0;
|
||||
while(sString[i]!=0) {
|
||||
if(((sString[i]!='*') && (sString[i]!='-') &&
|
||||
(sString[i]!='_') && (sString[i]!='.')) &&
|
||||
((sString[i]<'0') ||
|
||||
((sString[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;
|
||||
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;i<rlm_shoutcast1_devs;i++) {
|
||||
switch(log->log_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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
386
rlm/rlm_spinitron_plus.c
Normal file
386
rlm/rlm_spinitron_plus.c
Normal file
@@ -0,0 +1,386 @@
|
||||
/* rlm_spinitron_plus.c
|
||||
*
|
||||
* (C) Copyright 2013 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data
|
||||
* to the Spinitron account(s) specified in the configuration file pointed
|
||||
* to by the plugin argument. For information about Spinitron, see
|
||||
* http://www.spinitron.com/.
|
||||
*
|
||||
* Inspired by the original spinitron RLM by Eric Berg, Benjamin Yu
|
||||
* and Max Goldstein.
|
||||
*
|
||||
* 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_spinitron_plus.rlm rlm_spinitron_plus.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
#define RLM_SPINITRON_PLUS_LOGGER_NAME "Rivendell"
|
||||
|
||||
int rlm_spinitron_plus_devs;
|
||||
char *rlm_spinitron_plus_stations;
|
||||
char *rlm_spinitron_plus_usernames;
|
||||
char *rlm_spinitron_plus_passwords;
|
||||
int *rlm_spinitron_plus_playlist_modes;
|
||||
char *rlm_spinitron_plus_titles;
|
||||
char *rlm_spinitron_plus_artists;
|
||||
char *rlm_spinitron_plus_albums;
|
||||
char *rlm_spinitron_plus_labels;
|
||||
char *rlm_spinitron_plus_composers;
|
||||
char *rlm_spinitron_plus_notes;
|
||||
int *rlm_spinitron_plus_masters;
|
||||
int *rlm_spinitron_plus_aux1s;
|
||||
int *rlm_spinitron_plus_aux2s;
|
||||
|
||||
|
||||
int rlm_spinitron_plus_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<dOldSize;i++) {
|
||||
sString[i]=sString[i-dDiff];
|
||||
}
|
||||
return dNewSize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int rlm_spinitron_plus_EncodeString(char *sString,int dMaxSize)
|
||||
{
|
||||
int i; /* General Purpose Counter */
|
||||
char sAccum[4]; /* General String Buffer */
|
||||
|
||||
i=0;
|
||||
while(sString[i]!=0) {
|
||||
if(((sString[i]!=' ') && (sString[i]!='*') && (sString[i]!='-') &&
|
||||
(sString[i]!='_') && (sString[i]!='.')) &&
|
||||
((sString[i]<'0') ||
|
||||
((sString[i]>'9') && (sString[i]<'A')) ||
|
||||
((sString[i]>'Z') && (sString[i]<'a')) ||
|
||||
(sString[i]>'z'))) {
|
||||
if(rlm_spinitron_plus_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++;
|
||||
}
|
||||
return strlen(sString);
|
||||
}
|
||||
|
||||
|
||||
int rlm_spinitron_plus_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_spinitron_plus_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char station[256];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
char mode[256];
|
||||
int pmode;
|
||||
int i=1;
|
||||
|
||||
rlm_spinitron_plus_devs=0;
|
||||
rlm_spinitron_plus_stations=NULL;
|
||||
rlm_spinitron_plus_usernames=NULL;
|
||||
rlm_spinitron_plus_passwords=NULL;
|
||||
rlm_spinitron_plus_playlist_modes=NULL;
|
||||
rlm_spinitron_plus_titles=NULL;
|
||||
rlm_spinitron_plus_artists=NULL;
|
||||
rlm_spinitron_plus_albums=NULL;
|
||||
rlm_spinitron_plus_labels=NULL;
|
||||
rlm_spinitron_plus_composers=NULL;
|
||||
rlm_spinitron_plus_notes=NULL;
|
||||
rlm_spinitron_plus_masters=NULL;
|
||||
rlm_spinitron_plus_aux1s=NULL;
|
||||
rlm_spinitron_plus_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Spinitron%d",i++);
|
||||
strncpy(station,RLMGetStringValue(ptr,arg,section,"Station",""),255);
|
||||
station[255]=0;
|
||||
if(strlen(station)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_spinitron_plus: no spinitron accounts specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(station)>0) {
|
||||
rlm_spinitron_plus_stations=realloc(rlm_spinitron_plus_stations,
|
||||
(rlm_spinitron_plus_devs+1)*(rlm_spinitron_plus_devs+1)*256);
|
||||
strcpy(rlm_spinitron_plus_stations+256*rlm_spinitron_plus_devs,station);
|
||||
rlm_spinitron_plus_EncodeString(rlm_spinitron_plus_stations+256*rlm_spinitron_plus_devs,255);
|
||||
|
||||
rlm_spinitron_plus_usernames=realloc(rlm_spinitron_plus_usernames,
|
||||
(rlm_spinitron_plus_devs+1)*(rlm_spinitron_plus_devs+1)*256);
|
||||
strcpy(rlm_spinitron_plus_usernames+256*rlm_spinitron_plus_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Username",""));
|
||||
rlm_spinitron_plus_EncodeString(rlm_spinitron_plus_usernames+256*rlm_spinitron_plus_devs,255);
|
||||
|
||||
rlm_spinitron_plus_passwords=realloc(rlm_spinitron_plus_passwords,
|
||||
(rlm_spinitron_plus_devs+1)*(rlm_spinitron_plus_devs+1)*256);
|
||||
strcpy(rlm_spinitron_plus_passwords+256*rlm_spinitron_plus_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Password",""));
|
||||
rlm_spinitron_plus_EncodeString(rlm_spinitron_plus_passwords+256*rlm_spinitron_plus_devs,255);
|
||||
|
||||
pmode=3;
|
||||
strcpy(mode,RLMGetStringValue(ptr,arg,section,"PlaylistMode",""));
|
||||
if(strcasecmp(mode,"full")==0) {
|
||||
pmode=0;
|
||||
}
|
||||
if(strcasecmp(mode,"assist")==0) {
|
||||
pmode=2;
|
||||
}
|
||||
rlm_spinitron_plus_playlist_modes=
|
||||
realloc(rlm_spinitron_plus_playlist_modes,
|
||||
(rlm_spinitron_plus_devs+1)*sizeof(int));
|
||||
rlm_spinitron_plus_playlist_modes[rlm_spinitron_plus_devs]=pmode;
|
||||
|
||||
rlm_spinitron_plus_titles=realloc(rlm_spinitron_plus_titles,(rlm_spinitron_plus_devs+1)*256);
|
||||
strncpy(rlm_spinitron_plus_titles+256*rlm_spinitron_plus_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Title",""),256);
|
||||
|
||||
rlm_spinitron_plus_artists=realloc(rlm_spinitron_plus_artists,(rlm_spinitron_plus_devs+1)*256);
|
||||
strncpy(rlm_spinitron_plus_artists+256*rlm_spinitron_plus_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Artist",""),256);
|
||||
|
||||
rlm_spinitron_plus_albums=realloc(rlm_spinitron_plus_albums,(rlm_spinitron_plus_devs+1)*256);
|
||||
strncpy(rlm_spinitron_plus_albums+256*rlm_spinitron_plus_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Album",""),256);
|
||||
|
||||
rlm_spinitron_plus_labels=realloc(rlm_spinitron_plus_labels,(rlm_spinitron_plus_devs+1)*256);
|
||||
strncpy(rlm_spinitron_plus_labels+256*rlm_spinitron_plus_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Label",""),256);
|
||||
|
||||
rlm_spinitron_plus_composers=realloc(rlm_spinitron_plus_composers,(rlm_spinitron_plus_devs+1)*256);
|
||||
strncpy(rlm_spinitron_plus_composers+256*rlm_spinitron_plus_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Composer",""),256);
|
||||
|
||||
rlm_spinitron_plus_notes=realloc(rlm_spinitron_plus_notes,(rlm_spinitron_plus_devs+1)*256);
|
||||
strncpy(rlm_spinitron_plus_notes+256*rlm_spinitron_plus_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Notes",""),256);
|
||||
|
||||
|
||||
rlm_spinitron_plus_masters=realloc(rlm_spinitron_plus_masters,
|
||||
(rlm_spinitron_plus_devs+1)*sizeof(int));
|
||||
rlm_spinitron_plus_masters[rlm_spinitron_plus_devs]=
|
||||
rlm_spinitron_plus_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_spinitron_plus_aux1s=realloc(rlm_spinitron_plus_aux1s,
|
||||
(rlm_spinitron_plus_devs+1)*sizeof(int));
|
||||
rlm_spinitron_plus_aux1s[rlm_spinitron_plus_devs]=
|
||||
rlm_spinitron_plus_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_spinitron_plus_aux2s=realloc(rlm_spinitron_plus_aux2s,
|
||||
(rlm_spinitron_plus_devs+1)*sizeof(int));
|
||||
rlm_spinitron_plus_aux2s[rlm_spinitron_plus_devs]=
|
||||
rlm_spinitron_plus_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_spinitron_plus: configured account for station \"%s\"",
|
||||
station);
|
||||
|
||||
rlm_spinitron_plus_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"Spinitron%d",i++);
|
||||
strncpy(station,RLMGetStringValue(ptr,arg,section,"Station",""),255);
|
||||
station[255]=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_spinitron_plus_RLMFree(void *ptr)
|
||||
{
|
||||
free(rlm_spinitron_plus_stations);
|
||||
free(rlm_spinitron_plus_usernames);
|
||||
free(rlm_spinitron_plus_passwords);
|
||||
free(rlm_spinitron_plus_playlist_modes);
|
||||
free(rlm_spinitron_plus_titles);
|
||||
free(rlm_spinitron_plus_artists);
|
||||
free(rlm_spinitron_plus_albums);
|
||||
free(rlm_spinitron_plus_labels);
|
||||
free(rlm_spinitron_plus_composers);
|
||||
free(rlm_spinitron_plus_notes);
|
||||
free(rlm_spinitron_plus_masters);
|
||||
free(rlm_spinitron_plus_aux1s);
|
||||
free(rlm_spinitron_plus_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_spinitron_plus_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 title[1024];
|
||||
char artist[1024];
|
||||
char album[1024];
|
||||
char label[1024];
|
||||
char composer[1024];
|
||||
char notes[1024];
|
||||
char msg[8192];
|
||||
char sysmsg[8192];
|
||||
int pm;
|
||||
|
||||
for(i=0;i<rlm_spinitron_plus_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_spinitron_plus_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_spinitron_plus_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_spinitron_plus_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
strncpy(title,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_spinitron_plus_titles+256*i),256);
|
||||
rlm_spinitron_plus_EncodeString(title,1023);
|
||||
strncpy(artist,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_spinitron_plus_artists+256*i),256);
|
||||
rlm_spinitron_plus_EncodeString(artist,1023);
|
||||
strncpy(album,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_spinitron_plus_albums+256*i),256);
|
||||
rlm_spinitron_plus_EncodeString(album,1023);
|
||||
strncpy(label,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_spinitron_plus_labels+256*i),256);
|
||||
rlm_spinitron_plus_EncodeString(label,1023);
|
||||
strncpy(composer,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_spinitron_plus_composers+256*i),256);
|
||||
rlm_spinitron_plus_EncodeString(composer,1023);
|
||||
strncpy(notes,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_spinitron_plus_notes+256*i),256);
|
||||
rlm_spinitron_plus_EncodeString(notes,1023);
|
||||
if(rlm_spinitron_plus_playlist_modes[i]==3) {
|
||||
switch(log->log_mode) {
|
||||
case RLM_LOGMODE_AUTOMATIC:
|
||||
pm=0;
|
||||
break;
|
||||
|
||||
case RLM_LOGMODE_LIVEASSIST:
|
||||
case RLM_LOGMODE_MANUAL:
|
||||
default:
|
||||
pm=2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
pm=rlm_spinitron_plus_playlist_modes[i];
|
||||
}
|
||||
|
||||
if(strlen(now->rlm_title)!=0) {
|
||||
snprintf(msg,8192,
|
||||
"https://spinitron.com/member/logthis.php?un=%s&pw=%s&sn=%s&aw=%s&dn=%s&ln=%s&sc=%s&se=%s&df=%s&st=%s&sd=%d&pm=%d",
|
||||
rlm_spinitron_plus_usernames+256*i,
|
||||
rlm_spinitron_plus_passwords+256*i,
|
||||
title,
|
||||
artist,
|
||||
album,
|
||||
label,
|
||||
composer,
|
||||
notes,
|
||||
RLM_SPINITRON_PLUS_LOGGER_NAME,
|
||||
rlm_spinitron_plus_stations+256*i,
|
||||
now->rlm_len/1000,
|
||||
pm);
|
||||
if(fork()==0) {
|
||||
execlp("curl","curl",msg,(char *)NULL);
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_spinitron_plus: unable to execute curl(1)");
|
||||
exit(0);
|
||||
}
|
||||
snprintf(sysmsg,8192,"rlm_spinitron_plus: sending pad update: \"%s\"",
|
||||
(const char *)msg);
|
||||
RLMLog(ptr,LOG_DEBUG,sysmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
205
rlm/rlm_spottrap.c
Normal file
205
rlm/rlm_spottrap.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/* rlm_spottrap.c
|
||||
*
|
||||
* (C) Copyright 2012 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 processes Now&Next PAD data
|
||||
* on the basis of Group and Length as specified in the configuration file
|
||||
* pointed to by the plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_spottrap.rlm rlm_spottrap.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_spottrap_devs;
|
||||
char *rlm_spottrap_groups;
|
||||
char *rlm_spottrap_addresses;
|
||||
int *rlm_spottrap_minimums;
|
||||
int *rlm_spottrap_maximums;
|
||||
uint16_t *rlm_spottrap_ports;
|
||||
char *rlm_spottrap_formats;
|
||||
char *rlm_spottrap_default_formats;
|
||||
int *rlm_spottrap_masters;
|
||||
int *rlm_spottrap_aux1s;
|
||||
int *rlm_spottrap_aux2s;
|
||||
|
||||
int rlm_spottrap_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_spottrap_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[17];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_spottrap_devs=0;
|
||||
rlm_spottrap_groups=NULL;
|
||||
rlm_spottrap_addresses=NULL;
|
||||
rlm_spottrap_minimums=NULL;
|
||||
rlm_spottrap_maximums=NULL;
|
||||
rlm_spottrap_ports=NULL;
|
||||
rlm_spottrap_formats=NULL;
|
||||
rlm_spottrap_default_formats=NULL;
|
||||
rlm_spottrap_masters=NULL;
|
||||
rlm_spottrap_aux1s=NULL;
|
||||
rlm_spottrap_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Rule%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
if(strlen(address)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_spottrap: no rules specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(address)>0) {
|
||||
rlm_spottrap_addresses=
|
||||
realloc(rlm_spottrap_addresses,(rlm_spottrap_devs+1)*(rlm_spottrap_devs+1)*16);
|
||||
strcpy(rlm_spottrap_addresses+16*rlm_spottrap_devs,address);
|
||||
rlm_spottrap_groups=realloc(rlm_spottrap_groups,(rlm_spottrap_devs+1)*16);
|
||||
strncpy(rlm_spottrap_groups+16*rlm_spottrap_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"GroupName",""),10);
|
||||
rlm_spottrap_minimums=realloc(rlm_spottrap_minimums,(rlm_spottrap_devs+1)*sizeof(int));
|
||||
rlm_spottrap_minimums[rlm_spottrap_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"MinimumLength",0);
|
||||
rlm_spottrap_maximums=realloc(rlm_spottrap_maximums,(rlm_spottrap_devs+1)*sizeof(int));
|
||||
rlm_spottrap_maximums[rlm_spottrap_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"MaximumLength",0);
|
||||
rlm_spottrap_ports=realloc(rlm_spottrap_ports,(rlm_spottrap_devs+1)*sizeof(uint16_t));
|
||||
rlm_spottrap_ports[rlm_spottrap_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"UdpPort",0);
|
||||
rlm_spottrap_formats=realloc(rlm_spottrap_formats,(rlm_spottrap_devs+1)*256);
|
||||
strncpy(rlm_spottrap_formats+256*rlm_spottrap_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString",""),256);
|
||||
rlm_spottrap_default_formats=realloc(rlm_spottrap_default_formats,
|
||||
(rlm_spottrap_devs+1)*256);
|
||||
strncpy(rlm_spottrap_default_formats+256*rlm_spottrap_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"DefaultFormatString",""),256);
|
||||
rlm_spottrap_masters=realloc(rlm_spottrap_masters,
|
||||
(rlm_spottrap_devs+1)*sizeof(int));
|
||||
rlm_spottrap_masters[rlm_spottrap_devs]=
|
||||
rlm_spottrap_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_spottrap_aux1s=realloc(rlm_spottrap_aux1s,
|
||||
(rlm_spottrap_devs+1)*sizeof(int));
|
||||
rlm_spottrap_aux1s[rlm_spottrap_devs]=
|
||||
rlm_spottrap_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_spottrap_aux2s=realloc(rlm_spottrap_aux2s,
|
||||
(rlm_spottrap_devs+1)*sizeof(int));
|
||||
rlm_spottrap_aux2s[rlm_spottrap_devs]=
|
||||
rlm_spottrap_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_spottrap: configured rule for \"%s:%d\"",address,
|
||||
rlm_spottrap_ports[rlm_spottrap_devs]);
|
||||
rlm_spottrap_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"Rule%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_spottrap_RLMFree(void *ptr)
|
||||
{
|
||||
free(rlm_spottrap_addresses);
|
||||
free(rlm_spottrap_groups);
|
||||
free(rlm_spottrap_minimums);
|
||||
free(rlm_spottrap_maximums);
|
||||
free(rlm_spottrap_ports);
|
||||
free(rlm_spottrap_formats);
|
||||
free(rlm_spottrap_default_formats);
|
||||
free(rlm_spottrap_masters);
|
||||
free(rlm_spottrap_aux1s);
|
||||
free(rlm_spottrap_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_spottrap_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 msg[1500];
|
||||
|
||||
for(i=0;i<rlm_spottrap_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_spottrap_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_spottrap_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_spottrap_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
if((strcasecmp(now->rlm_group,rlm_spottrap_groups+16*i)==0)&&
|
||||
(now->rlm_len>=rlm_spottrap_minimums[i])&&
|
||||
(now->rlm_len<=rlm_spottrap_maximums[i])) {
|
||||
const char *str=
|
||||
RLMResolveNowNext(ptr,now,next,rlm_spottrap_formats+256*i);
|
||||
RLMSendUdp(ptr,rlm_spottrap_addresses+i*16,rlm_spottrap_ports[i],
|
||||
str,strlen(str));
|
||||
snprintf(msg,1500,"rlm_spottrap: sending pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
else {
|
||||
const char *str=
|
||||
RLMResolveNowNext(ptr,now,next,rlm_spottrap_default_formats+256*i);
|
||||
RLMSendUdp(ptr,rlm_spottrap_addresses+i*16,rlm_spottrap_ports[i],
|
||||
str,strlen(str));
|
||||
snprintf(msg,1500,"rlm_spottrap: sending default pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
153
rlm/rlm_test.c
Normal file
153
rlm/rlm_test.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/* rlm_test.c
|
||||
*
|
||||
* (C) Copyright 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sample Rivendell Loadable Module. All it does is print
|
||||
* Now & Next data to standard output for each event transition.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_test.rlm rlm_test.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
|
||||
void rlm_test_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char str[1024];
|
||||
sprintf(str,"rlm_test: started on %s",
|
||||
RLMDateTime(ptr,0,"MM/dd/yyyy at hh:mm:ss"));
|
||||
RLMLog(ptr,LOG_NOTICE,str);
|
||||
}
|
||||
|
||||
|
||||
void rlm_test_RLMFree(void *ptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void rlm_test_print_carttype(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case RLM_CARTTYPE_ALL:
|
||||
printf(" Type:\n");
|
||||
break;
|
||||
|
||||
case RLM_CARTTYPE_AUDIO:
|
||||
printf(" Type: AUDIO\n");
|
||||
break;
|
||||
|
||||
case RLM_CARTTYPE_MACRO:
|
||||
printf(" Type: MACRO\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rlm_test_RLMPadDataSent(void *ptr,const struct rlm_svc *svc,
|
||||
const struct rlm_log *log,
|
||||
const struct rlm_pad *now,
|
||||
const struct rlm_pad *next)
|
||||
{
|
||||
printf("Service: %s\n",svc->svc_name);
|
||||
printf("Program Code: %s\n",svc->svc_pgmcode);
|
||||
printf("Log Name: %s\n",log->log_name);
|
||||
if(log->log_onair==0) {
|
||||
printf(" OnAir = false\n");
|
||||
}
|
||||
else {
|
||||
printf(" OnAir = true\n");
|
||||
}
|
||||
switch(log->log_mode) {
|
||||
case RLM_LOGMODE_LIVEASSIST:
|
||||
printf(" Mode = Live Assist\n");
|
||||
break;
|
||||
|
||||
case RLM_LOGMODE_AUTOMATIC:
|
||||
printf(" Mode = Automatic\n");
|
||||
break;
|
||||
|
||||
case RLM_LOGMODE_MANUAL:
|
||||
printf(" Mode = Manual\n");
|
||||
break;
|
||||
}
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
printf(" -- On Main Log ---------------------------------------------\n");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
printf(" -- On Aux 1 Log --------------------------------------------\n");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
printf(" -- On Aux 2 Log --------------------------------------------\n");
|
||||
break;
|
||||
}
|
||||
printf("Playing NOW\n");
|
||||
printf(" Cart number: %06u\n",now->rlm_cartnum);
|
||||
rlm_test_print_carttype(now->rlm_carttype);
|
||||
printf("Start Date/Time: %04u-%02u-%02u %02u:%02u:%02u.%03u\n",
|
||||
now->rlm_start_year,now->rlm_start_mon,now->rlm_start_day,
|
||||
now->rlm_start_hour,now->rlm_start_min,now->rlm_start_sec,
|
||||
now->rlm_start_msec);
|
||||
printf(" Length: %u mS\n",now->rlm_len);
|
||||
printf(" Title: %s\n",now->rlm_title);
|
||||
printf(" Artist: %s\n",now->rlm_artist);
|
||||
printf(" Label: %s\n",now->rlm_label);
|
||||
printf(" Conductor: %s\n",now->rlm_conductor);
|
||||
printf(" SongId: %s\n",now->rlm_song_id);
|
||||
printf(" Client: %s\n",now->rlm_client);
|
||||
printf(" Agency: %s\n",now->rlm_agency);
|
||||
printf(" Composer: %s\n",now->rlm_comp);
|
||||
printf(" Publisher: %s\n",now->rlm_pub);
|
||||
printf(" UserDefined: %s\n",now->rlm_userdef);
|
||||
printf(" Outcue: %s\n",now->rlm_outcue);
|
||||
printf("Cut Description: %s\n",now->rlm_description);
|
||||
printf(" ISRC: %s\n",now->rlm_isrc);
|
||||
printf(" ISCI Code: %s\n",now->rlm_isci);
|
||||
printf(" Ext Data: %s\n",now->rlm_ext_data);
|
||||
printf(" Ext Event ID: %s\n",now->rlm_ext_eventid);
|
||||
printf(" Ext Annc Type: %s\n",now->rlm_ext_annctype);
|
||||
printf("\n");
|
||||
printf("Playing NEXT\n");
|
||||
printf(" Cart number: %06u\n",next->rlm_cartnum);
|
||||
rlm_test_print_carttype(next->rlm_carttype);
|
||||
printf("Start Date/Time: %04u-%02u-%02u %02u:%02u:%02u.%03u\n",
|
||||
next->rlm_start_year,next->rlm_start_mon,next->rlm_start_day,
|
||||
next->rlm_start_hour,next->rlm_start_min,next->rlm_start_sec,
|
||||
next->rlm_start_msec);
|
||||
printf(" Length: %u mS\n",next->rlm_len);
|
||||
printf(" Title: %s\n",next->rlm_title);
|
||||
printf(" Artist: %s\n",next->rlm_artist);
|
||||
printf(" Label: %s\n",next->rlm_label);
|
||||
printf(" Conductor: %s\n",next->rlm_conductor);
|
||||
printf(" SongId: %s\n",next->rlm_song_id);
|
||||
printf(" Client: %s\n",next->rlm_client);
|
||||
printf(" Agency: %s\n",next->rlm_agency);
|
||||
printf(" Composer: %s\n",next->rlm_comp);
|
||||
printf(" Publisher: %s\n",next->rlm_pub);
|
||||
printf(" UserDefined: %s\n",next->rlm_userdef);
|
||||
printf(" Outcue: %s\n",next->rlm_outcue);
|
||||
printf("Cut Description: %s\n",next->rlm_description);
|
||||
printf(" ISRC: %s\n",next->rlm_isrc);
|
||||
printf(" ISCI Code: %s\n",next->rlm_isci);
|
||||
printf(" Ext Data: %s\n",next->rlm_ext_data);
|
||||
printf(" Ext Event ID: %s\n",next->rlm_ext_eventid);
|
||||
printf(" Ext Annc Type: %s\n",next->rlm_ext_annctype);
|
||||
}
|
||||
264
rlm/rlm_twitter.c
Normal file
264
rlm/rlm_twitter.c
Normal file
@@ -0,0 +1,264 @@
|
||||
/* rlm_twitter.c
|
||||
*
|
||||
* (C) Copyright 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data
|
||||
* to the Twitter account(s) specified in the configuration file pointed
|
||||
* to by the plugin argument. For information about the Twitter service,
|
||||
* see http://www.twitter.com/.
|
||||
*
|
||||
* 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_twitter.rlm rlm_twitter.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_twitter_devs;
|
||||
char *rlm_twitter_addresses;
|
||||
char *rlm_twitter_passwords;
|
||||
char *rlm_twitter_formats;
|
||||
int *rlm_twitter_masters;
|
||||
int *rlm_twitter_aux1s;
|
||||
int *rlm_twitter_aux2s;
|
||||
|
||||
|
||||
int rlm_twitter_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<dOldSize;i++) {
|
||||
sString[i]=sString[i-dDiff];
|
||||
}
|
||||
return dNewSize;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int rlm_twitter_EncodeString(char *sString,int dMaxSize)
|
||||
{
|
||||
int i; /* General Purpose Counter */
|
||||
char sAccum[4]; /* General String Buffer */
|
||||
|
||||
i=0;
|
||||
while(sString[i]!=0) {
|
||||
if(((sString[i]!=' ') && (sString[i]!='*') && (sString[i]!='-') &&
|
||||
(sString[i]!='_') && (sString[i]!='.')) &&
|
||||
((sString[i]<'0') ||
|
||||
((sString[i]>'9') && (sString[i]<'A')) ||
|
||||
((sString[i]>'Z') && (sString[i]<'a')) ||
|
||||
(sString[i]>'z'))) {
|
||||
if(rlm_twitter_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++;
|
||||
}
|
||||
return strlen(sString);
|
||||
}
|
||||
|
||||
|
||||
int rlm_twitter_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_twitter_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[256];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_twitter_devs=0;
|
||||
rlm_twitter_addresses=NULL;
|
||||
rlm_twitter_passwords=NULL;
|
||||
rlm_twitter_formats=NULL;
|
||||
rlm_twitter_masters=NULL;
|
||||
rlm_twitter_aux1s=NULL;
|
||||
rlm_twitter_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Twitter%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"EmailAddress",""),255);
|
||||
address[255]=0;
|
||||
if(strlen(address)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_twitter: no twitter accounts specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(address)>0) {
|
||||
rlm_twitter_addresses=realloc(rlm_twitter_addresses,
|
||||
(rlm_twitter_devs+1)*(rlm_twitter_devs+1)*256);
|
||||
strcpy(rlm_twitter_addresses+256*rlm_twitter_devs,address);
|
||||
rlm_twitter_passwords=realloc(rlm_twitter_passwords,
|
||||
(rlm_twitter_devs+1)*(rlm_twitter_devs+1)*256);
|
||||
strcpy(rlm_twitter_passwords+256*rlm_twitter_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"Password",""));
|
||||
rlm_twitter_formats=realloc(rlm_twitter_formats,(rlm_twitter_devs+1)*256);
|
||||
strncpy(rlm_twitter_formats+256*rlm_twitter_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString",""),256);
|
||||
rlm_twitter_masters=realloc(rlm_twitter_masters,
|
||||
(rlm_twitter_devs+1)*sizeof(int));
|
||||
rlm_twitter_masters[rlm_twitter_devs]=
|
||||
rlm_twitter_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_twitter_aux1s=realloc(rlm_twitter_aux1s,
|
||||
(rlm_twitter_devs+1)*sizeof(int));
|
||||
rlm_twitter_aux1s[rlm_twitter_devs]=
|
||||
rlm_twitter_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_twitter_aux2s=realloc(rlm_twitter_aux2s,
|
||||
(rlm_twitter_devs+1)*sizeof(int));
|
||||
rlm_twitter_aux2s[rlm_twitter_devs]=
|
||||
rlm_twitter_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_twitter: configured account \"%s\"",address);
|
||||
rlm_twitter_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"Twitter%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"EmailAddress",""),255);
|
||||
address[255]=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_twitter_RLMFree(void *ptr)
|
||||
{
|
||||
free(rlm_twitter_addresses);
|
||||
free(rlm_twitter_passwords);
|
||||
free(rlm_twitter_formats);
|
||||
free(rlm_twitter_masters);
|
||||
free(rlm_twitter_aux1s);
|
||||
free(rlm_twitter_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_twitter_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 pad[1024];
|
||||
char msg[1500];
|
||||
|
||||
for(i=0;i<rlm_twitter_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_twitter_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_twitter_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_twitter_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
strncpy(str,RLMResolveNowNext(ptr,now,next,
|
||||
rlm_twitter_formats+256*i),256);
|
||||
rlm_twitter_EncodeString(str,1023);
|
||||
snprintf(account,1024,"%s:%s",rlm_twitter_addresses+256*i,
|
||||
rlm_twitter_passwords+256*i);
|
||||
snprintf(pad,1024,"status=%s",str);
|
||||
if(strlen(now->rlm_title)!=0) {
|
||||
if(fork()==0) {
|
||||
execlp("curl","curl","-u",account,"-d",pad,"-o","/dev/null","-s",
|
||||
"http://twitter.com/statuses/update.xml",(char *)NULL);
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_twitter: unable to execute curl(1)");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
snprintf(msg,1500,"rlm_twitter: sending pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
205
rlm/rlm_udp.c
Normal file
205
rlm/rlm_udp.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/* rlm_udp.c
|
||||
*
|
||||
* (C) Copyright 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data via
|
||||
* UDP packets to the destination(s) specified in the configuration file
|
||||
* pointed to by the plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_udp.rlm rlm_udp.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_udp_devs;
|
||||
char *rlm_udp_addresses;
|
||||
uint16_t *rlm_udp_ports;
|
||||
char *rlm_udp_formats;
|
||||
int *rlm_udp_encodings;
|
||||
int *rlm_udp_null_updates;
|
||||
int *rlm_udp_masters;
|
||||
int *rlm_udp_aux1s;
|
||||
int *rlm_udp_aux2s;
|
||||
|
||||
int rlm_udp_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_udp_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[17];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
|
||||
rlm_udp_devs=0;
|
||||
rlm_udp_addresses=NULL;
|
||||
rlm_udp_ports=NULL;
|
||||
rlm_udp_formats=NULL;
|
||||
rlm_udp_encodings=NULL;
|
||||
rlm_udp_null_updates=NULL;
|
||||
rlm_udp_masters=NULL;
|
||||
rlm_udp_aux1s=NULL;
|
||||
rlm_udp_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Udp%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
if(strlen(address)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_udp: no udp destinations specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(address)>0) {
|
||||
rlm_udp_addresses=
|
||||
realloc(rlm_udp_addresses,(rlm_udp_devs+1)*(rlm_udp_devs+1)*16);
|
||||
strcpy(rlm_udp_addresses+16*rlm_udp_devs,address);
|
||||
rlm_udp_ports=realloc(rlm_udp_ports,(rlm_udp_devs+1)*sizeof(uint16_t));
|
||||
rlm_udp_ports[rlm_udp_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"UdpPort",0);
|
||||
rlm_udp_formats=realloc(rlm_udp_formats,(rlm_udp_devs+1)*256);
|
||||
strncpy(rlm_udp_formats+256*rlm_udp_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString",""),256);
|
||||
rlm_udp_encodings=realloc(rlm_udp_encodings,
|
||||
(rlm_udp_devs+1)*sizeof(int));
|
||||
rlm_udp_encodings[rlm_udp_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"Encoding",RLM_ENCODE_NONE);
|
||||
rlm_udp_null_updates=realloc(rlm_udp_null_updates,
|
||||
(rlm_udp_devs+1)*sizeof(int));
|
||||
rlm_udp_null_updates[rlm_udp_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"ProcessNullUpdates",0);
|
||||
rlm_udp_masters=realloc(rlm_udp_masters,
|
||||
(rlm_udp_devs+1)*sizeof(int));
|
||||
rlm_udp_masters[rlm_udp_devs]=
|
||||
rlm_udp_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
|
||||
rlm_udp_aux1s=realloc(rlm_udp_aux1s,
|
||||
(rlm_udp_devs+1)*sizeof(int));
|
||||
rlm_udp_aux1s[rlm_udp_devs]=
|
||||
rlm_udp_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_udp_aux2s=realloc(rlm_udp_aux2s,
|
||||
(rlm_udp_devs+1)*sizeof(int));
|
||||
rlm_udp_aux2s[rlm_udp_devs]=
|
||||
rlm_udp_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
sprintf(errtext,"rlm_udp: configured destination \"%s:%d\"",address,
|
||||
rlm_udp_ports[rlm_udp_devs]);
|
||||
rlm_udp_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"Udp%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_udp_RLMFree(void *ptr)
|
||||
{
|
||||
free(rlm_udp_addresses);
|
||||
free(rlm_udp_ports);
|
||||
free(rlm_udp_formats);
|
||||
free(rlm_udp_encodings);
|
||||
free(rlm_udp_null_updates);
|
||||
free(rlm_udp_masters);
|
||||
free(rlm_udp_aux1s);
|
||||
free(rlm_udp_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_udp_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 msg[1500];
|
||||
|
||||
for(i=0;i<rlm_udp_devs;i++) {
|
||||
switch(rlm_udp_null_updates[i]) {
|
||||
case 0: /* Process all updates */
|
||||
break;
|
||||
|
||||
case 1: /* Process only non-null NOW updates */
|
||||
if(now->rlm_cartnum==0) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* Process only non-null NEXT updates */
|
||||
if(next->rlm_cartnum==0) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* Process only non-null NOW and NEXT updates */
|
||||
if((now->rlm_cartnum==0)||(next->rlm_cartnum==0)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_udp_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_udp_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_udp_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
const char *str=
|
||||
RLMResolveNowNextEncoded(ptr,now,next,rlm_udp_formats+256*i,
|
||||
rlm_udp_encodings[i]);
|
||||
RLMSendUdp(ptr,rlm_udp_addresses+i*16,rlm_udp_ports[i],str,strlen(str));
|
||||
snprintf(msg,1500,"rlm_udp: sending pad update: \"%s\"",
|
||||
(const char *)str);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
301
rlm/rlm_xds.c
Normal file
301
rlm/rlm_xds.c
Normal file
@@ -0,0 +1,301 @@
|
||||
/* rlm_xds.c
|
||||
*
|
||||
* (C) Copyright 2010 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends generates enhanced netcue
|
||||
* (aka CIC) packets for the Citadel/X-Digital Systems copy-splitting system,
|
||||
* using a configuration file pointed to by the plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_xds.rlm rlm_xds.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <limits.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
int rlm_xds_devs;
|
||||
char *rlm_xds_isci_prefixes;
|
||||
char *rlm_xds_addresses;
|
||||
uint16_t *rlm_xds_ports;
|
||||
int *rlm_xds_handles;
|
||||
char *rlm_xds_tty_buffers;
|
||||
int *rlm_xds_masters;
|
||||
int *rlm_xds_aux1s;
|
||||
int *rlm_xds_aux2s;
|
||||
|
||||
unsigned rlm_xds_GetChecksum(const char *pack)
|
||||
{
|
||||
unsigned ret=0;
|
||||
int i;
|
||||
|
||||
for(i=0;i<strlen(pack);i++) {
|
||||
ret+=pack[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const char *rlm_xds_FilterCharacters(const char *str)
|
||||
{
|
||||
static char ret[32];
|
||||
int i;
|
||||
|
||||
strncpy(ret,str,31);
|
||||
for(i=0;i<strlen(ret);i++) {
|
||||
switch(ret[i]) {
|
||||
case ' ':
|
||||
case ',':
|
||||
case '.':
|
||||
ret[i]='_';
|
||||
break;
|
||||
|
||||
case '"':
|
||||
ret[i]=39;
|
||||
break;
|
||||
|
||||
case '%':
|
||||
case '*':
|
||||
case '+':
|
||||
case '/':
|
||||
case ':':
|
||||
case ';':
|
||||
case '<':
|
||||
case '=':
|
||||
case '>':
|
||||
case '?':
|
||||
case '@':
|
||||
case '[':
|
||||
case '\\':
|
||||
case ']':
|
||||
case '^':
|
||||
case '{':
|
||||
case '|':
|
||||
case '}':
|
||||
ret[i]='-';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rlm_xds_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_xds_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
char address[17];
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int tty_speed;
|
||||
int i=1;
|
||||
|
||||
rlm_xds_devs=0;
|
||||
rlm_xds_addresses=NULL;
|
||||
rlm_xds_ports=NULL;
|
||||
rlm_xds_handles=NULL;
|
||||
rlm_xds_tty_buffers=NULL;
|
||||
rlm_xds_masters=NULL;
|
||||
rlm_xds_aux1s=NULL;
|
||||
rlm_xds_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Udp%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
if(strlen(address)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_xds: no xds destinations specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(address)>0) {
|
||||
rlm_xds_addresses=
|
||||
realloc(rlm_xds_addresses,(rlm_xds_devs+1)*(rlm_xds_devs+1)*16);
|
||||
strcpy(rlm_xds_addresses+16*rlm_xds_devs,address);
|
||||
rlm_xds_isci_prefixes=realloc(rlm_xds_isci_prefixes,(rlm_xds_devs+1)*32);
|
||||
strncpy(rlm_xds_isci_prefixes+32*rlm_xds_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"IsciPrefix",""),31);
|
||||
rlm_xds_ports=realloc(rlm_xds_ports,(rlm_xds_devs+1)*sizeof(uint16_t));
|
||||
rlm_xds_ports[rlm_xds_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"UdpPort",0);
|
||||
rlm_xds_handles=realloc(rlm_xds_handles,(rlm_xds_devs+1)*sizeof(int));
|
||||
rlm_xds_handles[rlm_xds_devs]=-1;
|
||||
tty_speed=RLMGetIntegerValue(ptr,arg,section,"TtySpeed",9600);
|
||||
printf("speed: %d\n",tty_speed);
|
||||
rlm_xds_handles[rlm_xds_devs]=
|
||||
RLMOpenSerial(ptr,RLMGetStringValue(ptr,arg,section,"TtyDevice",""),
|
||||
tty_speed,RLM_PARITY_NONE,1);
|
||||
rlm_xds_tty_buffers=realloc(rlm_xds_tty_buffers,(rlm_xds_devs+1)*256);
|
||||
memset(rlm_xds_tty_buffers+rlm_xds_devs,0,256);
|
||||
rlm_xds_masters=realloc(rlm_xds_masters,
|
||||
(rlm_xds_devs+1)*sizeof(int));
|
||||
rlm_xds_masters[rlm_xds_devs]=
|
||||
rlm_xds_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_xds_aux1s=realloc(rlm_xds_aux1s,
|
||||
(rlm_xds_devs+1)*sizeof(int));
|
||||
rlm_xds_aux1s[rlm_xds_devs]=
|
||||
rlm_xds_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_xds_aux2s=realloc(rlm_xds_aux2s,
|
||||
(rlm_xds_devs+1)*sizeof(int));
|
||||
rlm_xds_aux2s[rlm_xds_devs]=
|
||||
rlm_xds_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
if(rlm_xds_handles[rlm_xds_devs]<0) {
|
||||
sprintf(errtext,"rlm_xds: configured destination \"%s:%d\"",address,
|
||||
rlm_xds_ports[rlm_xds_devs]);
|
||||
}
|
||||
else {
|
||||
sprintf(errtext,"rlm_xds: configured destination \"%s\"",
|
||||
(const char *)RLMGetStringValue(ptr,arg,section,"TtyDevice",""));
|
||||
}
|
||||
rlm_xds_devs++;
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
sprintf(section,"Udp%d",i++);
|
||||
strncpy(address,RLMGetStringValue(ptr,arg,section,"IpAddress",""),15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_xds_RLMFree(void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<rlm_xds_devs;i++) {
|
||||
if(rlm_xds_handles[i]>=0) {
|
||||
RLMCloseSerial(ptr,rlm_xds_handles[i]);
|
||||
rlm_xds_handles[i]=-1;
|
||||
}
|
||||
}
|
||||
free(rlm_xds_addresses);
|
||||
free(rlm_xds_ports);
|
||||
free(rlm_xds_handles);
|
||||
free(rlm_xds_tty_buffers);
|
||||
free(rlm_xds_isci_prefixes);
|
||||
free(rlm_xds_masters);
|
||||
free(rlm_xds_aux1s);
|
||||
free(rlm_xds_aux2s);
|
||||
}
|
||||
|
||||
|
||||
void rlm_xds_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 packet[64];
|
||||
char tty_packet[256];
|
||||
char msg[1500];
|
||||
|
||||
if(strlen((now->rlm_ext_eventid))==0) {
|
||||
return;
|
||||
}
|
||||
for(i=0;i<rlm_xds_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_xds_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_xds_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_xds_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
packet[0]=0;
|
||||
snprintf(packet,64,"0:%s:%s%s:*",svc->svc_pgmcode,
|
||||
rlm_xds_isci_prefixes+i*32,
|
||||
rlm_xds_FilterCharacters(now->rlm_ext_eventid));
|
||||
if(rlm_xds_handles[i]<0) {
|
||||
RLMSendUdp(ptr,rlm_xds_addresses+i*16,rlm_xds_ports[i],
|
||||
packet,strlen(packet));
|
||||
snprintf(msg,1500,"rlm_xds: sending CIC NetCue: \"%s\" to %s:%d",
|
||||
(const char *)packet,rlm_xds_addresses+i*16,rlm_xds_ports[i]);
|
||||
}
|
||||
else {
|
||||
snprintf(tty_packet,256,"NC:%u:%s\r\n",
|
||||
rlm_xds_GetChecksum(packet),packet);
|
||||
RLMSendSerial(ptr,rlm_xds_handles[i],tty_packet,strlen(tty_packet));
|
||||
RLMSendSerial(ptr,rlm_xds_handles[i],tty_packet,strlen(tty_packet));
|
||||
snprintf(msg,1500,"rlm_xds: sending CIC NetCue: \"%s\" to tty",
|
||||
(const char *)packet);
|
||||
}
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_xds_RLMSerialDataReceived(void *ptr,int handle,
|
||||
const char *data,int len)
|
||||
{
|
||||
int dev;
|
||||
int i;
|
||||
char *buffer;
|
||||
|
||||
for(dev=0;dev<rlm_xds_devs;dev++) {
|
||||
if(handle==rlm_xds_handles[dev]) {
|
||||
buffer=rlm_xds_tty_buffers+256*dev;
|
||||
for(i=0;i<len;i++) {
|
||||
if(data[i]==13) {
|
||||
if(strcmp(buffer,"PINGRECV")==0) {
|
||||
RLMSendSerial(ptr,handle,"PONGRECV\r\n",10);
|
||||
}
|
||||
buffer[0]=0;
|
||||
}
|
||||
else {
|
||||
if(data[i]!=10) {
|
||||
buffer[strlen(buffer)+1]=0;
|
||||
buffer[strlen(buffer)]=data[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"rlm_xds: unknown tty handle %d\n",handle);
|
||||
}
|
||||
304
rlm/rlm_xmpad.c
Normal file
304
rlm/rlm_xmpad.c
Normal file
@@ -0,0 +1,304 @@
|
||||
/* rlm_xmpad.c
|
||||
*
|
||||
* (C) Copyright 2008 Fred Gleason <fredg@paravelsystems.com>
|
||||
*
|
||||
* 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 sends Now&Next PAD data
|
||||
* to an XM radio channel, using XM's in-house format.
|
||||
* plugin argument.
|
||||
*
|
||||
* To compile this module, just do:
|
||||
*
|
||||
* gcc -shared -o rlm_xmpad.rlm rlm_xmpad.c
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <rlm/rlm.h>
|
||||
|
||||
#define RLM_XMPAD_DELIMITER 0x02
|
||||
//#define RLM_XMPAD_DELIMITER 0x7C
|
||||
|
||||
|
||||
int rlm_xmpad_devs;
|
||||
int *rlm_xmpad_ids;
|
||||
int *rlm_xmpad_handles;
|
||||
int *rlm_xmpad_recordings;
|
||||
char *rlm_xmpad_format1s;
|
||||
char *rlm_xmpad_format2s;
|
||||
int *rlm_xmpad_display_size1s;
|
||||
int *rlm_xmpad_display_size2s;
|
||||
int *rlm_xmpad_masters;
|
||||
int *rlm_xmpad_aux1s;
|
||||
int *rlm_xmpad_aux2s;
|
||||
|
||||
int rlm_xmpad_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_xmpad_SendPad(void *ptr,int config,const char *line1,
|
||||
const char *line2,int len)
|
||||
{
|
||||
char str[1024];
|
||||
char sline1[17];
|
||||
char sline2[17];
|
||||
char flag1[1024];
|
||||
char flag2[1024];
|
||||
int i;
|
||||
|
||||
//
|
||||
// Log it
|
||||
//
|
||||
sprintf(str,"rlm_xmpad: sending pad update: |%s|%s|%d|",line1,line2,len);
|
||||
RLMLog(ptr,LOG_INFO,str);
|
||||
|
||||
//
|
||||
// Generate Display Strings and Flags
|
||||
//
|
||||
strncpy(sline1,line1,16);
|
||||
sline1[16]=0;
|
||||
flag1[0]=0;
|
||||
for(i=0;i<rlm_xmpad_display_size1s[config];i++) {
|
||||
strcat(flag1,"1");
|
||||
}
|
||||
strncpy(sline2,line2,16);
|
||||
sline2[16]=0;
|
||||
flag2[0]=0;
|
||||
for(i=0;i<rlm_xmpad_display_size2s[config];i++) {
|
||||
strcat(flag2,"1");
|
||||
}
|
||||
|
||||
//
|
||||
// Generate PAD Data
|
||||
// The B-4 packet
|
||||
//
|
||||
sprintf(str,"B-4%c%d%c%d%c%d%c%d%c%d%c%d%c%s%c%s%c%s%c%s%c%s%c%s%c%u\n",
|
||||
RLM_XMPAD_DELIMITER,!(rlm_xmpad_recordings[config]),
|
||||
RLM_XMPAD_DELIMITER,1,
|
||||
RLM_XMPAD_DELIMITER,len/432,
|
||||
RLM_XMPAD_DELIMITER,0,
|
||||
RLM_XMPAD_DELIMITER,rlm_xmpad_display_size1s[config],
|
||||
RLM_XMPAD_DELIMITER,rlm_xmpad_display_size2s[config],
|
||||
RLM_XMPAD_DELIMITER,flag1,
|
||||
RLM_XMPAD_DELIMITER,flag2,
|
||||
RLM_XMPAD_DELIMITER,sline2,
|
||||
RLM_XMPAD_DELIMITER,flag1,
|
||||
RLM_XMPAD_DELIMITER,flag2,
|
||||
RLM_XMPAD_DELIMITER,sline1,
|
||||
RLM_XMPAD_DELIMITER,rlm_xmpad_ids[config]);
|
||||
RLMSendSerial(ptr,rlm_xmpad_handles[config],str,strlen(str));
|
||||
RLMSendSerial(ptr,rlm_xmpad_handles[config],str,strlen(str));
|
||||
RLMSendSerial(ptr,rlm_xmpad_handles[config],str,strlen(str));
|
||||
|
||||
//
|
||||
// The A4 Packet
|
||||
//
|
||||
sprintf(str,"A4%c%d%c%s\n",RLM_XMPAD_DELIMITER,1,RLM_XMPAD_DELIMITER,line1);
|
||||
RLMSendSerial(ptr,rlm_xmpad_handles[config],str,strlen(str));
|
||||
|
||||
//
|
||||
// The A5 Packet
|
||||
//
|
||||
sprintf(str,"A5%c%d%c%s\n",RLM_XMPAD_DELIMITER,1,RLM_XMPAD_DELIMITER,line2);
|
||||
RLMSendSerial(ptr,rlm_xmpad_handles[config],str,strlen(str));
|
||||
}
|
||||
|
||||
|
||||
void rlm_xmpad_RLMStart(void *ptr,const char *arg)
|
||||
{
|
||||
int handle;
|
||||
char device[256];
|
||||
int speed;
|
||||
int parity;
|
||||
int wsize;
|
||||
char section[256];
|
||||
char errtext[256];
|
||||
int i=1;
|
||||
int interval;
|
||||
|
||||
rlm_xmpad_devs=0;
|
||||
rlm_xmpad_ids=NULL;
|
||||
rlm_xmpad_handles=NULL;
|
||||
rlm_xmpad_recordings=NULL;
|
||||
rlm_xmpad_format1s=NULL;
|
||||
rlm_xmpad_format2s=NULL;
|
||||
rlm_xmpad_display_size1s=NULL;
|
||||
rlm_xmpad_display_size2s=NULL;
|
||||
rlm_xmpad_masters=NULL;
|
||||
rlm_xmpad_aux1s=NULL;
|
||||
rlm_xmpad_aux2s=NULL;
|
||||
|
||||
sprintf(section,"Serial%d",i++);
|
||||
strncpy(device,RLMGetStringValue(ptr,arg,section,"Device",""),256);
|
||||
if(strlen(device)==0) {
|
||||
RLMLog(ptr,LOG_WARNING,"rlm_xmpad: no serial devices specified");
|
||||
return;
|
||||
}
|
||||
while(strlen(device)>0) {
|
||||
speed=RLMGetIntegerValue(ptr,arg,section,"Speed",9600);
|
||||
parity=RLMGetIntegerValue(ptr,arg,section,"Parity",0);
|
||||
wsize=RLMGetIntegerValue(ptr,arg,section,"WordSize",8);
|
||||
if((handle=RLMOpenSerial(ptr,device,speed,parity,wsize))>=0) {
|
||||
rlm_xmpad_handles=realloc(rlm_xmpad_handles,
|
||||
(rlm_xmpad_devs+1)*sizeof(int));
|
||||
rlm_xmpad_handles[rlm_xmpad_devs]=handle;
|
||||
rlm_xmpad_ids=realloc(rlm_xmpad_ids,(rlm_xmpad_devs+1)*sizeof(int));
|
||||
rlm_xmpad_ids[rlm_xmpad_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"ProgramID",0);
|
||||
rlm_xmpad_format1s=realloc(rlm_xmpad_format1s,(rlm_xmpad_devs+1)*256);
|
||||
strncpy(rlm_xmpad_format1s+256*rlm_xmpad_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString1",""),256);
|
||||
rlm_xmpad_format2s=realloc(rlm_xmpad_format2s,(rlm_xmpad_devs+1)*256);
|
||||
strncpy(rlm_xmpad_format2s+256*rlm_xmpad_devs,
|
||||
RLMGetStringValue(ptr,arg,section,"FormatString2",""),256);
|
||||
rlm_xmpad_display_size1s=realloc(rlm_xmpad_display_size1s,
|
||||
(rlm_xmpad_devs+1)*sizeof(int));
|
||||
rlm_xmpad_display_size1s[rlm_xmpad_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"DisplaySize1",8);
|
||||
rlm_xmpad_display_size2s=realloc(rlm_xmpad_display_size2s,
|
||||
(rlm_xmpad_devs+1)*sizeof(int));
|
||||
rlm_xmpad_display_size2s[rlm_xmpad_devs]=
|
||||
RLMGetIntegerValue(ptr,arg,section,"DisplaySize2",10);
|
||||
rlm_xmpad_recordings=realloc(rlm_xmpad_recordings,
|
||||
(rlm_xmpad_devs+1)*sizeof(int));
|
||||
rlm_xmpad_recordings[rlm_xmpad_devs]=
|
||||
RLMGetBooleanValue(ptr,arg,section,"Recording",1);
|
||||
rlm_xmpad_masters=realloc(rlm_xmpad_masters,
|
||||
(rlm_xmpad_devs+1)*sizeof(int));
|
||||
rlm_xmpad_masters[rlm_xmpad_devs]=
|
||||
rlm_xmpad_GetLogStatus(ptr,arg,section,"MasterLog");
|
||||
rlm_xmpad_aux1s=realloc(rlm_xmpad_aux1s,
|
||||
(rlm_xmpad_devs+1)*sizeof(int));
|
||||
rlm_xmpad_aux1s[rlm_xmpad_devs]=
|
||||
rlm_xmpad_GetLogStatus(ptr,arg,section,"Aux1Log");
|
||||
rlm_xmpad_aux2s=realloc(rlm_xmpad_aux2s,
|
||||
(rlm_xmpad_devs+1)*sizeof(int));
|
||||
rlm_xmpad_aux2s[rlm_xmpad_devs]=
|
||||
rlm_xmpad_GetLogStatus(ptr,arg,section,"Aux2Log");
|
||||
interval=RLMGetIntegerValue(ptr,arg,section,"HeartbeatInterval",30);
|
||||
if(interval>0) {
|
||||
RLMStartTimer(ptr,rlm_xmpad_devs,1000*interval,RLM_TIMER_REPEATING);
|
||||
}
|
||||
rlm_xmpad_devs++;
|
||||
sprintf(errtext,"rlm_xmpad: opened device \"%s\"",device);
|
||||
RLMLog(ptr,LOG_INFO,errtext);
|
||||
}
|
||||
else {
|
||||
sprintf(errtext,"unable to open tty \"%s\"",device);
|
||||
RLMLog(ptr,LOG_WARNING,errtext);
|
||||
}
|
||||
sprintf(section,"Serial%d",i++);
|
||||
strncpy(device,RLMGetStringValue(ptr,arg,section,"Device",""),256);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_xmpad_RLMFree(void *ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<rlm_xmpad_devs;i++) {
|
||||
RLMCloseSerial(ptr,rlm_xmpad_handles[i]);
|
||||
}
|
||||
free(rlm_xmpad_handles);
|
||||
free(rlm_xmpad_ids);
|
||||
free(rlm_xmpad_format1s);
|
||||
free(rlm_xmpad_format2s);
|
||||
free(rlm_xmpad_display_size1s);
|
||||
free(rlm_xmpad_display_size2s);
|
||||
free(rlm_xmpad_recordings);
|
||||
free(rlm_xmpad_masters);
|
||||
free(rlm_xmpad_aux1s);
|
||||
free(rlm_xmpad_aux2s);
|
||||
}
|
||||
|
||||
/*
|
||||
void rlm_xmpad_RLMPadDataSent(void *ptr,const char *svcname,int onair,
|
||||
int lognum,const struct rlm_pad *now,
|
||||
const struct rlm_pad *next)
|
||||
*/
|
||||
void rlm_xmpad_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 str1[33];
|
||||
char str2[33];
|
||||
char msg[1500];
|
||||
|
||||
if(now->rlm_cartnum==0) { // Suppress null PAD frames
|
||||
return;
|
||||
}
|
||||
for(i=0;i<rlm_xmpad_devs;i++) {
|
||||
switch(log->log_mach) {
|
||||
case 0:
|
||||
flag=rlm_xmpad_masters[i];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
flag=rlm_xmpad_aux1s[i];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
flag=rlm_xmpad_aux2s[i];
|
||||
break;
|
||||
}
|
||||
if((flag==1)||((flag==2)&&(log->log_onair!=0))) {
|
||||
strncpy(str1,RLMResolveNowNext(ptr,now,next,rlm_xmpad_format1s+256*i),32);
|
||||
str1[32]=0;
|
||||
strncpy(str2,RLMResolveNowNext(ptr,now,next,rlm_xmpad_format2s+256*i),32);
|
||||
str2[32]=0;
|
||||
rlm_xmpad_SendPad(ptr,i,str1,str2,now->rlm_len);
|
||||
snprintf(msg,1500,"rlm_xmpad: sending pad update: \"%s | %s\"",
|
||||
(const char *)str1,(const char *)str2);
|
||||
RLMLog(ptr,LOG_INFO,msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rlm_xmpad_RLMTimerExpired(void *ptr,int timernum)
|
||||
{
|
||||
RLMSendSerial(ptr,rlm_xmpad_handles[timernum],"H0\n",3);
|
||||
}
|
||||
Reference in New Issue
Block a user