mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
merge per-mount on-[dis]connect script handling
svn path=/icecast/trunk/icecast/; revision=9424
This commit is contained in:
parent
84a0892cff
commit
05a14555d9
@ -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
|
||||
<option name="filename" value="myauth"/>
|
||||
<option name="allow_duplicate_users" value="0"/>
|
||||
</authentication>
|
||||
|
||||
<on-connect>/home/icecast/bin/source-start</on-connect>
|
||||
<on-disconnect>/home/icecast/bin/source-end</on-disconnect>
|
||||
</mount>
|
||||
</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
|
||||
}
|
||||
|
||||
|
58
src/source.c
58
src/source.c
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user