Commit 05a14555 authored by Karl Heyes's avatar Karl Heyes

merge per-mount on-[dis]connect script handling

svn path=/icecast/trunk/icecast/; revision=9424
parent 84a0892c
......@@ -105,6 +105,8 @@
<option name="filename" value="myauth"/>
<option name="allow_duplicate_users" value="0"/>
</authentication>
<on-connect>/home/icecast/bin/stream-start</on-connect>
<on-disconnect>/home/icecast/bin/stream-stop</on-disconnect>
</mount>
-->
......
......@@ -380,7 +380,8 @@ If you are relaying a Shoutcast stream, you need to specify this indicator to al
&lt;option name="filename" value="myauth"/&gt;
&lt;option name="allow_duplicate_users" value="0"/&gt;
&lt;/authentication&gt;
&lt;on-connect&gt;/home/icecast/bin/source-start&lt;/on-connect&gt;
&lt;on-disconnect&gt;/home/icecast/bin/source-end&lt;/on-disconnect&gt;
&lt;/mount&gt;
</pre>
<p>This section contains the settings which apply only to a specific mountpoint and applies to
......@@ -524,6 +525,20 @@ relay to be shown
<div class="indentedbox">
This specifies that the named mount point will require listener authentication. Currently, we only support a file-based authentication scheme (type=htpasswd). Users and encrypted password are placed in this file (separated by a :) and all requests for this mountpoint will require that a user and password be supplied for authentication purposes. These values are passed in via normal HTTP Basic Authentication means (i.e. http://user:password@stream:port/mountpoint.ogg). Users and Passwords are maintained via the web admin interface. A mountpoint configured with an authenticator will display a red key next to the mount point name on the admin screens. You can read more about listener authentication <a href="icecast2_listenerauth.html">here</a>.
</div>
<h4>on-connect</h4>
<div class="indentedbox">
<p>State a program that is run when the source is started. It is passed a parameter which
is the name of the mountpoint that is starting. The processing of the stream does not wait
for the script to end. This option is not available on win32
</p>
</div>
<h4>on-disconnect</h4>
<div class="indentedbox">
<p>State a program that is run when the source ends. It is passed a parameter which is the
name of the mountpoint that has ended. The processing of the stream does not wait for the
script to end. This option is not available on win32
</p>
</div>
<p>
<br />
<br />
......
......@@ -191,6 +191,8 @@ void config_clear(ice_config_t *c)
xmlFree(mount->password);
xmlFree(mount->dumpfile);
xmlFree(mount->intro_filename);
xmlFree(mount->on_connect);
xmlFree(mount->on_disconnect);
xmlFree(mount->fallback_mount);
xmlFree(mount->stream_name);
xmlFree(mount->stream_description);
......@@ -633,6 +635,14 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
option = option->next;
}
}
else if (strcmp(node->name, "on-connect") == 0) {
mount->on_connect = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (strcmp(node->name, "on-disconnect") == 0) {
mount->on_disconnect = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (strcmp(node->name, "queue-size") == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->queue_size_limit = atoi (tmp);
......
......@@ -65,6 +65,8 @@ typedef struct _mount_proxy {
char *auth_type; /* Authentication type */
char *cluster_password;
config_options_t *auth_options; /* Options for this type */
char *on_connect;
char *on_disconnect;
char *stream_name;
char *stream_description;
......
......@@ -41,6 +41,7 @@ void sighandler_initialize(void)
signal(SIGINT, _sig_die);
signal(SIGTERM, _sig_die);
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
#endif
}
......
......@@ -26,6 +26,7 @@
#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/wait.h>
#else
#include <winsock2.h>
#include <windows.h>
......@@ -62,6 +63,11 @@ static int _compare_clients(void *compare_arg, void *a, void *b);
static int _free_client(void *key);
static void _parse_audio_info (source_t *source, const char *s);
static void source_shutdown (source_t *source);
#ifdef _WIN32
#define source_run_script(x,y) WARN0("on [dis]connect scripts disabled");
#else
static void source_run_script (char *command, char *mountpoint);
#endif
/* Allocate a new source with the stated mountpoint, if one already
* exists with that mountpoint in the global source tree then return
......@@ -534,6 +540,7 @@ static void source_init (source_t *source)
ice_config_t *config = config_get_config();
char *listenurl, *str;
int listen_url_size;
mount_proxy *mountinfo;
/* 6 for max size of port */
listen_url_size = strlen("http://") + strlen(config->hostname) +
......@@ -584,6 +591,11 @@ static void source_init (source_t *source)
source->last_read = time (NULL);
source->running = 1;
mountinfo = config_find_mount (config_get_config(), source->mount);
if (mountinfo && mountinfo->on_connect)
source_run_script (mountinfo->on_connect, source->mount);
config_release_config();
/*
** Now, if we have a fallback source and override is on, we want
** to steal its clients, because it means we've come back online
......@@ -769,9 +781,16 @@ void source_main (source_t *source)
static void source_shutdown (source_t *source)
{
mount_proxy *mountinfo;
source->running = 0;
INFO1("Source \"%s\" exiting", source->mount);
mountinfo = config_find_mount (config_get_config(), source->mount);
if (mountinfo && mountinfo->on_disconnect)
source_run_script (mountinfo->on_disconnect, source->mount);
config_release_config();
/* we have de-activated the source now, so no more clients will be
* added, now move the listeners we have to the fallback (if any)
*/
......@@ -1089,6 +1108,10 @@ void source_update_settings (ice_config_t *config, source_t *source, mount_proxy
DEBUG1 ("intro file is %s", mountinfo->intro_filename);
if (source->dumpfilename)
DEBUG1 ("Dumping stream to %s", source->dumpfilename);
if (mountinfo && mountinfo->on_connect)
DEBUG1 ("connect script \"%s\"", mountinfo->on_connect);
if (mountinfo && mountinfo->on_disconnect)
DEBUG1 ("disconnect script \"%s\"", mountinfo->on_disconnect);
if (source->on_demand)
{
DEBUG0 ("on_demand set");
......@@ -1156,6 +1179,41 @@ void *source_client_thread (void *arg)
}
#ifndef _WIN32
static void source_run_script (char *command, char *mountpoint)
{
pid_t pid, external_pid;
/* do a fork twice so that the command has init as parent */
external_pid = fork();
switch (external_pid)
{
case 0:
switch (pid = fork ())
{
case -1:
ERROR2 ("Unable to fork %s (%s)", command, strerror (errno));
break;
case 0: /* child */
DEBUG1 ("Starting command %s", command);
execl (command, command, mountpoint, NULL);
ERROR2 ("Unable to run command %s (%s)", command, strerror (errno));
exit(0);
default: /* parent */
break;
}
exit (0);
case -1:
ERROR1 ("Unable to fork %s", strerror (errno));
break;
default: /* parent */
waitpid (external_pid, NULL, 0);
break;
}
}
#endif
/* rescan the mount list, so that xsl files are updated to show
* unconnected but active fallback mountpoints
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment