mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-11-03 04:17:17 -05:00
allow for more updating over HUP. Made the YP engine only read the stats instead
of updating them, so source header parsing is done in the apply mount. Per-mount stream settings also allow for overriding the incoming settings. svn path=/icecast/trunk/icecast/; revision=9325
This commit is contained in:
parent
d57a19acac
commit
79adab0133
@ -347,7 +347,14 @@ If you are relaying a Shoutcast stream, you need to specify this indicator to al
|
||||
<dump-file>/tmp/dump-example1.ogg</dump-file>
|
||||
<fallback-mount>/example2.ogg</fallback-mount>
|
||||
<fallback-override>1</fallback-override>
|
||||
<no-yp>1</no-yp>
|
||||
<public>1</public>
|
||||
<stream-name>My audio stream</stream-name>
|
||||
<stream-description>My audio description</stream-description>
|
||||
<stream-url>http://some.place.com</stream-url>
|
||||
<genre>classical</genre>
|
||||
<bitrate>64</bitrate>
|
||||
<type>application/ogg</type>
|
||||
<subtype>vorbis</subtype>
|
||||
<hidden>1</hidden>
|
||||
<burst-size>65536</burst-size>
|
||||
<mp3-metadata-interval>4096</mp3-metadata-interval>
|
||||
@ -358,7 +365,16 @@ If you are relaying a Shoutcast stream, you need to specify this indicator to al
|
||||
|
||||
</mount>
|
||||
</pre>
|
||||
<p>This section contains settings which apply only to a specific mountpoint. Within this section you can reserve a specific mountpoint and set a source username/password for that mountpoint (not yet implemented) as well as specify individual settings which will apply only to the supplied mountpoint.
|
||||
<p>This section contains the settings which apply only to a specific mountpoint and applies to
|
||||
an incoming stream whether it is a relay or a source client. The purpose of the mount definition
|
||||
is to state certain information that can override either global/default settings or settings
|
||||
provided from the incoming stream.
|
||||
</p>
|
||||
<p>A mount does not need to be stated for each incoming source although you may want to
|
||||
specific certain settings like the maximum number of listeners or a mountpoint specific
|
||||
username/password. As a general rule, only define what you need to but each mount definition
|
||||
needs at least the mount-name. Changes to most of these will apply across a configuration file
|
||||
re-read even on active streams, however some only apply when the stream starts or ends.
|
||||
</p>
|
||||
<h4>mount-name</h4>
|
||||
<div class="indentedbox">
|
||||
@ -397,11 +413,67 @@ This multi-level fallback allows clients to cascade several mountpoints.
|
||||
When enabled, this allows a connecting source client or relay on this mountpoint to move
|
||||
listening clients back from the fallback mount.
|
||||
</div>
|
||||
<h4>no-yp</h4>
|
||||
<h4>no-yp (deprecated)</h4>
|
||||
<div class="indentedbox">
|
||||
Setting this option prevents this mountpoint from advertising on YP. The default is 0 so YP
|
||||
advertising occurs however you may want to prevent it here if you intend listeners to connect
|
||||
to a local relay instead
|
||||
<p>Setting this option prevents this mountpoint from advertising on YP. The default is 0
|
||||
so YP advertising can occur however you may want to prevent it here if you intend listeners
|
||||
to connect to a local relay instead. Deprecated option, replaced by <public>
|
||||
</p>
|
||||
</div>
|
||||
<h4>public</h4>
|
||||
<div class="indentedbox">
|
||||
<p>The default setting for this is -1 indicating that it is up to the source client or
|
||||
relay to determine if this mountpoint should advertise. A setting of 0 will prevent any
|
||||
advertising and a setting of 1 will force it to advertise. If you do force advertising
|
||||
you may need to set other settings listed below as the YP server can refuse to advertise
|
||||
if there is not enough information provided.
|
||||
</p>
|
||||
</div>
|
||||
<h4>stream-name</h4>
|
||||
<div class="indentedbox">
|
||||
<p>Setting this will add the specified name to the stats (and therefore YP) for this
|
||||
mountpoint even if the source client/relay provide one.
|
||||
</p>
|
||||
</div>
|
||||
<h4>stream-description</h4>
|
||||
<div class="indentedbox">
|
||||
<p>Setting this will add the specified description to the stats (and therefore YP) for
|
||||
this mountpoint even if the source client/relay provide one.
|
||||
</p>
|
||||
</div>
|
||||
<h4>stream-url</h4>
|
||||
<div class="indentedbox">
|
||||
<p>Setting this will add the specified URL to the stats (and therefore YP) for this
|
||||
mountpoint even if the source client/relay provide one. The URL is generally for
|
||||
directing people to a website.
|
||||
</p>
|
||||
</div>
|
||||
<h4>genre</h4>
|
||||
<div class="indentedbox">
|
||||
<p>Setting this will add the specified genre to the stats (and therefore YP) for this
|
||||
mountpoint even if the source client/relay provide one. This can be anything be using
|
||||
certain key words can help searches in the YP directories.
|
||||
</p>
|
||||
</div>
|
||||
<h4>bitrate</h4>
|
||||
<div class="indentedbox">
|
||||
<p>Setting this will add the specified bitrate to the stats (and therefore YP) for this
|
||||
mountpoint even if the source client/relay provide one. This is stated in kbps.
|
||||
</p>
|
||||
</div>
|
||||
<h4>type</h4>
|
||||
<div class="indentedbox">
|
||||
<p>Setting this will add the specified mime type to the stats (and therefore YP) for
|
||||
this mountpoint even if the source client/relay provide one. It is very unlikely that
|
||||
this will be needed.
|
||||
</p>
|
||||
</div>
|
||||
<h4>subtype</h4>
|
||||
<div class="indentedbox">
|
||||
<p>Setting this will add the specified subtype to the stats (and therefore YP) for
|
||||
this mountpoint. The subtype is really to help the YP server to identify the components
|
||||
of the type. An example setting is vorbis/theora do indicate the codecs in an Ogg stream
|
||||
</p>
|
||||
</div>
|
||||
<h4>burst-size</h4>
|
||||
<div class="indentedbox">
|
||||
|
@ -191,6 +191,12 @@ void config_clear(ice_config_t *c)
|
||||
xmlFree(mount->password);
|
||||
xmlFree(mount->dumpfile);
|
||||
xmlFree(mount->fallback_mount);
|
||||
xmlFree(mount->stream_name);
|
||||
xmlFree(mount->stream_description);
|
||||
xmlFree(mount->stream_url);
|
||||
xmlFree(mount->stream_genre);
|
||||
xmlFree(mount->bitrate);
|
||||
xmlFree(mount->type);
|
||||
if (mount->cluster_password) {
|
||||
xmlFree(mount->cluster_password);
|
||||
}
|
||||
@ -529,6 +535,7 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
|
||||
mount->max_listeners = -1;
|
||||
mount->burst_size = -1;
|
||||
mount->mp3_meta_interval = -1;
|
||||
mount->yp_public = -1;
|
||||
mount->next = NULL;
|
||||
|
||||
do {
|
||||
@ -577,7 +584,7 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
|
||||
}
|
||||
else if (strcmp(node->name, "no-yp") == 0) {
|
||||
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||
mount->no_yp = atoi(tmp);
|
||||
mount->yp_public = atoi(tmp) == 0 ? -1 : 0;
|
||||
if(tmp) xmlFree(tmp);
|
||||
}
|
||||
else if (strcmp(node->name, "hidden") == 0) {
|
||||
@ -635,10 +642,36 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
|
||||
} else if (strcmp(node->name, "cluster-password") == 0) {
|
||||
mount->cluster_password = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
} else if (strcmp(node->name, "stream-name") == 0) {
|
||||
mount->stream_name = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
} else if (strcmp(node->name, "stream-description") == 0) {
|
||||
mount->stream_description = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
} else if (strcmp(node->name, "stream-url") == 0) {
|
||||
mount->stream_url = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
} else if (strcmp(node->name, "genre") == 0) {
|
||||
mount->stream_genre = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
} else if (strcmp(node->name, "bitrate") == 0) {
|
||||
mount->bitrate = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
} else if (strcmp(node->name, "public") == 0) {
|
||||
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||
mount->yp_public = atoi (tmp);
|
||||
if(tmp) xmlFree(tmp);
|
||||
} else if (strcmp(node->name, "type") == 0) {
|
||||
mount->type = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
} else if (strcmp(node->name, "subtype") == 0) {
|
||||
mount->subtype = (char *)xmlNodeListGetString(
|
||||
doc, node->xmlChildrenNode, 1);
|
||||
}
|
||||
} while ((node = node->next));
|
||||
}
|
||||
|
||||
|
||||
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
|
||||
ice_config_t *configuration)
|
||||
{
|
||||
|
@ -57,7 +57,6 @@ typedef struct _mount_proxy {
|
||||
int burst_size; /* amount to send to a new client if possible, -1 take
|
||||
* from global setting */
|
||||
unsigned int queue_size_limit;
|
||||
int no_yp; /* Do we prevent YP on this mount */
|
||||
int hidden; /* Do we list this on the xsl pages */
|
||||
unsigned int source_timeout; /* source timeout in seconds */
|
||||
int mp3_meta_interval; /* outgoing per-stream metadata interval */
|
||||
@ -65,6 +64,16 @@ typedef struct _mount_proxy {
|
||||
char *auth_type; /* Authentication type */
|
||||
char *cluster_password;
|
||||
config_options_t *auth_options; /* Options for this type */
|
||||
|
||||
char *stream_name;
|
||||
char *stream_description;
|
||||
char *stream_url;
|
||||
char *stream_genre;
|
||||
char *bitrate;
|
||||
char *type;
|
||||
char *subtype;
|
||||
int yp_public;
|
||||
|
||||
struct _mount_proxy *next;
|
||||
} mount_proxy;
|
||||
|
||||
|
@ -449,6 +449,7 @@ int connection_complete_source (source_t *source)
|
||||
if (global.sources < config->source_limit)
|
||||
{
|
||||
char *contenttype;
|
||||
mount_proxy *mountinfo;
|
||||
format_type_t format_type;
|
||||
|
||||
/* setup format handler */
|
||||
@ -488,11 +489,6 @@ int connection_complete_source (source_t *source)
|
||||
global.sources++;
|
||||
global_unlock();
|
||||
|
||||
/* set global settings first */
|
||||
source->queue_size_limit = config->queue_size_limit;
|
||||
source->timeout = config->source_timeout;
|
||||
source->burst_size = config->burst_size;
|
||||
|
||||
/* for relays, we don't yet have a client, however we do require one
|
||||
* to retrieve the stream from. This is created here, quite late,
|
||||
* because we can't use this client to return an error code/message,
|
||||
@ -515,7 +511,11 @@ int connection_complete_source (source_t *source)
|
||||
}
|
||||
}
|
||||
|
||||
source_update_settings (config, source);
|
||||
source->running = 1;
|
||||
mountinfo = config_find_mount (config, source->mount);
|
||||
if (mountinfo == NULL)
|
||||
source_update_settings (config, source, mountinfo);
|
||||
source_recheck_mounts ();
|
||||
config_release_config();
|
||||
|
||||
source->shutdown_rwlock = &_source_shutdown_rwlock;
|
||||
|
@ -201,7 +201,7 @@ static void format_mp3_apply_settings (client_t *client, format_plugin_t *format
|
||||
{
|
||||
mp3_state *source_mp3 = format->_state;
|
||||
|
||||
if (mount->mp3_meta_interval <= 0)
|
||||
if (mount== NULL || mount->mp3_meta_interval <= 0)
|
||||
{
|
||||
char *metadata = httpp_getvar (client->parser, "icy-metaint");
|
||||
source_mp3->interval = -1;
|
||||
@ -214,7 +214,7 @@ static void format_mp3_apply_settings (client_t *client, format_plugin_t *format
|
||||
}
|
||||
else
|
||||
source_mp3->interval = mount->mp3_meta_interval;
|
||||
DEBUG2 ("mp3 interval %d, %d", mount->mp3_meta_interval, source_mp3->interval);
|
||||
DEBUG1 ("mp3 interval %d", source_mp3->interval);
|
||||
}
|
||||
|
||||
|
||||
|
253
src/source.c
253
src/source.c
@ -240,8 +240,6 @@ void source_clear_source (source_t *source)
|
||||
source->no_mount = 0;
|
||||
source->shoutcast_compat = 0;
|
||||
source->max_listeners = -1;
|
||||
source->yp_public = 0;
|
||||
source->yp_prevent = 0;
|
||||
source->hidden = 0;
|
||||
source->client_stats_update = 0;
|
||||
util_dict_free (source->audio_info);
|
||||
@ -514,7 +512,6 @@ static void source_init (source_t *source)
|
||||
ice_config_t *config = config_get_config();
|
||||
char *listenurl, *str;
|
||||
int listen_url_size;
|
||||
char *s;
|
||||
|
||||
/* 6 for max size of port */
|
||||
listen_url_size = strlen("http://") + strlen(config->hostname) +
|
||||
@ -526,23 +523,6 @@ static void source_init (source_t *source)
|
||||
config->hostname, config->port, source->mount);
|
||||
config_release_config();
|
||||
|
||||
do
|
||||
{
|
||||
str = "0";
|
||||
if (source->yp_prevent)
|
||||
break;
|
||||
if ((str = httpp_getvar(source->parser, "ice-public")))
|
||||
break;
|
||||
if ((str = httpp_getvar(source->parser, "icy-pub")))
|
||||
break;
|
||||
/* handle header from icecast v2 release */
|
||||
if ((str = httpp_getvar(source->parser, "icy-public")))
|
||||
break;
|
||||
str = "0";
|
||||
} while (0);
|
||||
source->yp_public = atoi (str);
|
||||
stats_event (source->mount, "public", str);
|
||||
|
||||
str = httpp_getvar(source->parser, "ice-audio-info");
|
||||
source->audio_info = util_dict_new();
|
||||
if (str)
|
||||
@ -601,23 +581,6 @@ static void source_init (source_t *source)
|
||||
|
||||
avl_tree_unlock(global.source_tree);
|
||||
}
|
||||
slave_rebuild_mounts ();
|
||||
if (source->yp_public) {
|
||||
yp_add (source);
|
||||
}
|
||||
else {
|
||||
/* If we are a private server, see if ic*-name and description
|
||||
is provided, and if so, add them to the stats */
|
||||
if ((s = httpp_getvar(source->parser, "ice-name"))) {
|
||||
stats_event (source->mount, "server_name", s);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "icy-name"))) {
|
||||
stats_event (source->mount, "server_name", s);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "ice-description"))) {
|
||||
stats_event (source->mount, "server_description", s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -882,64 +845,202 @@ static void _parse_audio_info (source_t *source, const char *s)
|
||||
/* Apply the mountinfo details to the source */
|
||||
static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
|
||||
{
|
||||
char *str;
|
||||
int val;
|
||||
http_parser_t *parser = NULL;
|
||||
|
||||
DEBUG1("Applying mount information for \"%s\"", source->mount);
|
||||
source->max_listeners = mountinfo->max_listeners;
|
||||
source->fallback_override = mountinfo->fallback_override;
|
||||
source->no_mount = mountinfo->no_mount;
|
||||
source->hidden = mountinfo->hidden;
|
||||
stats_event_hidden (source->mount, NULL, source->hidden);
|
||||
if (mountinfo)
|
||||
{
|
||||
source->max_listeners = mountinfo->max_listeners;
|
||||
source->fallback_override = mountinfo->fallback_override;
|
||||
source->no_mount = mountinfo->no_mount;
|
||||
source->hidden = mountinfo->hidden;
|
||||
}
|
||||
|
||||
if (mountinfo->fallback_mount)
|
||||
/* if a setting is available in the mount details then use it, else
|
||||
* check the parser details. */
|
||||
|
||||
if (source->client)
|
||||
parser = source->client->parser;
|
||||
|
||||
/* public */
|
||||
if (mountinfo && mountinfo->yp_public >= 0)
|
||||
val = mountinfo->yp_public;
|
||||
else
|
||||
{
|
||||
do {
|
||||
str = httpp_getvar (parser, "ice-public");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "icy-pub");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "x-audiocast-public");
|
||||
if (str) break;
|
||||
/* handle header from icecast v2 release */
|
||||
str = httpp_getvar (parser, "icy-public");
|
||||
if (str) break;
|
||||
str = "0";
|
||||
} while (0);
|
||||
val = atoi (str);
|
||||
}
|
||||
stats_event_args (source->mount, "public", "%d", val);
|
||||
if (source->yp_public != val)
|
||||
{
|
||||
DEBUG1 ("YP changed to %d", val);
|
||||
if (val)
|
||||
yp_add (source->mount);
|
||||
else
|
||||
yp_remove (source->mount);
|
||||
source->yp_public = val;
|
||||
}
|
||||
|
||||
/* stream name */
|
||||
if (mountinfo && mountinfo->stream_name)
|
||||
str = mountinfo->stream_name;
|
||||
else
|
||||
{
|
||||
do {
|
||||
str = httpp_getvar (parser, "ice-name");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "icy-name");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "x-audiocast-name");
|
||||
if (str) break;
|
||||
str = "Unspecified name";
|
||||
} while (0);
|
||||
}
|
||||
stats_event (source->mount, "server_name", str);
|
||||
|
||||
/* stream description */
|
||||
if (mountinfo && mountinfo->stream_description)
|
||||
str = mountinfo->stream_description;
|
||||
else
|
||||
{
|
||||
do {
|
||||
str = httpp_getvar (parser, "ice-description");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "icy-description");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "x-audiocast-description");
|
||||
if (str) break;
|
||||
str = "Unspecified description";
|
||||
} while (0);
|
||||
}
|
||||
stats_event (source->mount, "server_description", str);
|
||||
|
||||
/* stream URL */
|
||||
if (mountinfo && mountinfo->stream_url)
|
||||
str = mountinfo->stream_url;
|
||||
else
|
||||
{
|
||||
do {
|
||||
str = httpp_getvar (parser, "ice-url");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "icy-url");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "x-audiocast-url");
|
||||
if (str) break;
|
||||
} while (0);
|
||||
}
|
||||
stats_event (source->mount, "server_url", str);
|
||||
|
||||
/* stream genre */
|
||||
if (mountinfo && mountinfo->stream_genre)
|
||||
str = mountinfo->stream_genre;
|
||||
else
|
||||
{
|
||||
do {
|
||||
str = httpp_getvar (parser, "ice-genre");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "icy-genre");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "x-audiocast-genre");
|
||||
if (str) break;
|
||||
str = "various";
|
||||
} while (0);
|
||||
}
|
||||
stats_event (source->mount, "genre", str);
|
||||
|
||||
/* stream bitrate */
|
||||
if (mountinfo && mountinfo->bitrate)
|
||||
str = mountinfo->bitrate;
|
||||
else
|
||||
{
|
||||
do {
|
||||
str = httpp_getvar (parser, "ice-bitrate");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "icy-br");
|
||||
if (str) break;
|
||||
str = httpp_getvar (parser, "x-audiocast-bitrate");
|
||||
} while (0);
|
||||
}
|
||||
stats_event (source->mount, "bitrate", str);
|
||||
|
||||
/* handle MIME-type */
|
||||
if (mountinfo && mountinfo->type)
|
||||
stats_event (source->mount, "server_type", mountinfo->type);
|
||||
else
|
||||
if (source->format)
|
||||
stats_event (source->mount, "server_type", source->format->contenttype);
|
||||
|
||||
if (mountinfo && mountinfo->subtype)
|
||||
stats_event (source->mount, "subtype", mountinfo->subtype);
|
||||
|
||||
if (mountinfo && mountinfo->fallback_mount)
|
||||
{
|
||||
char *mount = source->fallback_mount;
|
||||
source->fallback_mount = strdup (mountinfo->fallback_mount);
|
||||
free (mount);
|
||||
}
|
||||
else
|
||||
source->fallback_mount = NULL;
|
||||
|
||||
if (mountinfo->auth_type != NULL)
|
||||
if (mountinfo && mountinfo->auth_type != NULL && source->authenticator == NULL)
|
||||
{
|
||||
source->authenticator = auth_get_authenticator(
|
||||
mountinfo->auth_type, mountinfo->auth_options);
|
||||
stats_event(source->mount, "authenticator", mountinfo->auth_type);
|
||||
}
|
||||
if (mountinfo->dumpfile)
|
||||
{
|
||||
free (source->dumpfilename);
|
||||
source->dumpfilename = strdup (mountinfo->dumpfile);
|
||||
}
|
||||
|
||||
if (mountinfo->queue_size_limit)
|
||||
if (mountinfo && mountinfo->dumpfile)
|
||||
{
|
||||
char *filename = source->dumpfilename;
|
||||
source->dumpfilename = strdup (mountinfo->dumpfile);
|
||||
free (filename);
|
||||
}
|
||||
else
|
||||
source->dumpfilename = NULL;
|
||||
|
||||
if (mountinfo && mountinfo->queue_size_limit)
|
||||
source->queue_size_limit = mountinfo->queue_size_limit;
|
||||
|
||||
if (mountinfo->source_timeout)
|
||||
if (mountinfo && mountinfo->source_timeout)
|
||||
source->timeout = mountinfo->source_timeout;
|
||||
|
||||
if (mountinfo->burst_size >= 0)
|
||||
if (mountinfo && mountinfo->burst_size >= 0)
|
||||
source->burst_size = (unsigned int)mountinfo->burst_size;
|
||||
|
||||
if (mountinfo->no_yp)
|
||||
source->yp_prevent = 1;
|
||||
|
||||
if (source->format && source->format->apply_settings)
|
||||
source->format->apply_settings (source->client, source->format, mountinfo);
|
||||
}
|
||||
|
||||
|
||||
void source_update_settings (ice_config_t *config, source_t *source)
|
||||
/* update the specified source with details from the config or mount.
|
||||
* mountinfo can be NULL in which case default settings should be taken
|
||||
*/
|
||||
void source_update_settings (ice_config_t *config, source_t *source, mount_proxy *mountinfo)
|
||||
{
|
||||
mount_proxy *mountinfo = config_find_mount (config, source->mount);
|
||||
|
||||
/* set global settings first */
|
||||
source->queue_size_limit = config->queue_size_limit;
|
||||
source->timeout = config->source_timeout;
|
||||
source->burst_size = config->burst_size;
|
||||
source->dumpfilename = NULL;
|
||||
|
||||
if (mountinfo)
|
||||
source_apply_mount (source, mountinfo);
|
||||
source_apply_mount (source, mountinfo);
|
||||
|
||||
if (source->fallback_mount)
|
||||
DEBUG1 ("fallback %s", source->fallback_mount);
|
||||
if (source->dumpfilename)
|
||||
DEBUG1 ("Dumping stream to %s", source->dumpfilename);
|
||||
if (source->yp_prevent)
|
||||
DEBUG0 ("preventing YP listings");
|
||||
if (source->hidden)
|
||||
{
|
||||
stats_event_hidden (source->mount, NULL, 1);
|
||||
@ -1006,33 +1107,19 @@ void source_recheck_mounts (void)
|
||||
|
||||
while (mount)
|
||||
{
|
||||
int update_stats = 0;
|
||||
int hidden;
|
||||
source_t *source = source_find_mount (mount->mountname);
|
||||
|
||||
hidden = mount->hidden;
|
||||
if (source)
|
||||
{
|
||||
/* something is active, maybe a fallback */
|
||||
if (strcmp (source->mount, mount->mountname) == 0)
|
||||
{
|
||||
/* this is for inactive relays */
|
||||
if (source->running == 0)
|
||||
update_stats = 1;
|
||||
}
|
||||
else
|
||||
update_stats = 1;
|
||||
}
|
||||
else
|
||||
stats_event (mount->mountname, NULL, NULL);
|
||||
if (update_stats)
|
||||
{
|
||||
source = source_find_mount_raw (mount->mountname);
|
||||
if (source)
|
||||
source_update_settings (config, source);
|
||||
{
|
||||
mount_proxy *mountinfo = config_find_mount (config, source->mount);
|
||||
source_update_settings (config, source, mountinfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
stats_event_hidden (mount->mountname, NULL, hidden);
|
||||
stats_event_hidden (mount->mountname, NULL, mount->hidden);
|
||||
stats_event (mount->mountname, "listeners", "0");
|
||||
if (mount->max_listeners < 0)
|
||||
stats_event (mount->mountname, "max_listeners", "unlimited");
|
||||
@ -1040,6 +1127,8 @@ void source_recheck_mounts (void)
|
||||
stats_event_args (mount->mountname, "max_listeners", "%d", mount->max_listeners);
|
||||
}
|
||||
}
|
||||
else
|
||||
stats_event (mount->mountname, NULL, NULL);
|
||||
|
||||
mount = mount->next;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ typedef struct source_tag
|
||||
|
||||
source_t *source_reserve (const char *mount);
|
||||
void *source_client_thread (void *arg);
|
||||
void source_update_settings (ice_config_t *config, source_t *source);
|
||||
void source_update_settings (ice_config_t *config, source_t *source, mount_proxy *mountinfo);
|
||||
void source_clear_source (source_t *source);
|
||||
source_t *source_find_mount(const char *mount);
|
||||
source_t *source_find_mount_raw(const char *mount);
|
||||
|
112
src/yp.c
112
src/yp.c
@ -92,7 +92,7 @@ static time_t now;
|
||||
static thread_type *yp_thread;
|
||||
|
||||
static void *yp_update_thread(void *arg);
|
||||
static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type);
|
||||
static void add_yp_info (ypdata_t *yp, void *info, int type);
|
||||
static unsigned do_yp_remove (ypdata_t *yp, char *s, unsigned len);
|
||||
static unsigned do_yp_add (ypdata_t *yp, char *s, unsigned len);
|
||||
static unsigned do_yp_touch (ypdata_t *yp, char *s, unsigned len);
|
||||
@ -334,12 +334,37 @@ static unsigned do_yp_add (ypdata_t *yp, char *s, unsigned len)
|
||||
int ret;
|
||||
char *value;
|
||||
|
||||
value = stats_get_value (yp->mount, "server_type");
|
||||
add_yp_info (yp, value, YP_SERVER_TYPE);
|
||||
free (value);
|
||||
|
||||
value = stats_get_value (yp->mount, "server_name");
|
||||
add_yp_info (yp, value, YP_SERVER_NAME);
|
||||
free (value);
|
||||
|
||||
value = stats_get_value (yp->mount, "server_url");
|
||||
add_yp_info (yp, value, YP_SERVER_URL);
|
||||
free (value);
|
||||
|
||||
value = stats_get_value (yp->mount, "genre");
|
||||
add_yp_info (yp, value, YP_SERVER_GENRE);
|
||||
free (value);
|
||||
|
||||
value = stats_get_value (yp->mount, "bitrate");
|
||||
add_yp_info (yp, value, YP_BITRATE);
|
||||
free (value);
|
||||
|
||||
value = stats_get_value (yp->mount, "server_description");
|
||||
add_yp_info (yp, value, YP_SERVER_DESC);
|
||||
free (value);
|
||||
|
||||
value = stats_get_value (yp->mount, "subtype");
|
||||
if (value)
|
||||
{
|
||||
add_yp_info (yp, "subtype", value, YP_SUBTYPE);
|
||||
free (value);
|
||||
}
|
||||
add_yp_info (yp, value, YP_SUBTYPE);
|
||||
free (value);
|
||||
|
||||
value = stats_get_value (yp->mount, "audio_info");
|
||||
add_yp_info (yp, value, YP_AUDIO_INFO);
|
||||
free (value);
|
||||
|
||||
ret = snprintf (s, len, "action=add&sn=%s&genre=%s&cpswd=%s&desc="
|
||||
"%s&url=%s&listenurl=%s&type=%s&stype=%s&b=%s&%s\r\n",
|
||||
@ -382,7 +407,8 @@ static unsigned do_yp_touch (ypdata_t *yp, char *s, unsigned len)
|
||||
if (song)
|
||||
{
|
||||
sprintf (song, "%s%s%s", artist, separator, title);
|
||||
add_yp_info(yp, "yp_currently_playing", song, YP_CURRENT_SONG);
|
||||
add_yp_info(yp, song, YP_CURRENT_SONG);
|
||||
stats_event (yp->mount, "yp_currently_playing", song);
|
||||
free (song);
|
||||
}
|
||||
}
|
||||
@ -404,7 +430,7 @@ static unsigned do_yp_touch (ypdata_t *yp, char *s, unsigned len)
|
||||
val = stats_get_value (yp->mount, "subtype");
|
||||
if (val)
|
||||
{
|
||||
add_yp_info (yp, "subtype", val, YP_SUBTYPE);
|
||||
add_yp_info (yp, val, YP_SUBTYPE);
|
||||
free (val);
|
||||
}
|
||||
|
||||
@ -472,13 +498,11 @@ static void yp_process_server (struct yp_server *server)
|
||||
|
||||
|
||||
|
||||
static ypdata_t *create_yp_entry (source_t *source)
|
||||
static ypdata_t *create_yp_entry (const char *mount)
|
||||
{
|
||||
ypdata_t *yp;
|
||||
char *s;
|
||||
|
||||
if (source->running == 0 || source->yp_public == 0)
|
||||
return NULL;
|
||||
yp = calloc (1, sizeof (ypdata_t));
|
||||
do
|
||||
{
|
||||
@ -490,7 +514,7 @@ static ypdata_t *create_yp_entry (source_t *source)
|
||||
|
||||
if (yp == NULL)
|
||||
break;
|
||||
yp->mount = strdup (source->mount);
|
||||
yp->mount = strdup (mount);
|
||||
yp->server_name = strdup ("");
|
||||
yp->server_desc = strdup ("");
|
||||
yp->server_genre = strdup ("");
|
||||
@ -507,17 +531,17 @@ static ypdata_t *create_yp_entry (source_t *source)
|
||||
if (url == NULL)
|
||||
break;
|
||||
config = config_get_config();
|
||||
ret = snprintf (url, len, "http://%s:%d%s", config->hostname, config->port, source->mount);
|
||||
ret = snprintf (url, len, "http://%s:%d%s", config->hostname, config->port, mount);
|
||||
if (ret >= (signed)len)
|
||||
{
|
||||
s = realloc (url, ++ret);
|
||||
if (s) url = s;
|
||||
snprintf (url, ret, "http://%s:%d%s", config->hostname, config->port, source->mount);
|
||||
snprintf (url, ret, "http://%s:%d%s", config->hostname, config->port, mount);
|
||||
}
|
||||
|
||||
mountproxy = config_find_mount (config, source->mount);
|
||||
mountproxy = config_find_mount (config, mount);
|
||||
if (mountproxy && mountproxy->cluster_password)
|
||||
add_yp_info (yp, "cluster_password", mountproxy->cluster_password, YP_CLUSTER_PASSWORD);
|
||||
add_yp_info (yp, mountproxy->cluster_password, YP_CLUSTER_PASSWORD);
|
||||
config_release_config();
|
||||
|
||||
yp->listen_url = util_url_escape (url);
|
||||
@ -525,39 +549,6 @@ static ypdata_t *create_yp_entry (source_t *source)
|
||||
if (yp->listen_url == NULL)
|
||||
break;
|
||||
|
||||
/* ice-* is icecast, icy-* is shoutcast */
|
||||
add_yp_info (yp, "server_type", source->format->contenttype, YP_SERVER_TYPE);
|
||||
if ((s = httpp_getvar(source->parser, "ice-name"))) {
|
||||
add_yp_info (yp, "server_name", s, YP_SERVER_NAME);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "icy-name"))) {
|
||||
add_yp_info (yp, "server_name", s, YP_SERVER_NAME);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "ice-url"))) {
|
||||
add_yp_info(yp, "server_url", s, YP_SERVER_URL);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "icy-url"))) {
|
||||
add_yp_info(yp, "server_url", s, YP_SERVER_URL);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "ice-genre"))) {
|
||||
add_yp_info(yp, "genre", s, YP_SERVER_GENRE);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "icy-genre"))) {
|
||||
add_yp_info(yp, "genre", s, YP_SERVER_GENRE);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "ice-bitrate"))) {
|
||||
add_yp_info(yp, "bitrate", s, YP_BITRATE);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "icy-br"))) {
|
||||
add_yp_info(yp, "bitrate", s, YP_BITRATE);
|
||||
}
|
||||
if ((s = httpp_getvar(source->parser, "ice-description"))) {
|
||||
add_yp_info(yp, "server_description", s, YP_SERVER_DESC);
|
||||
}
|
||||
s = util_dict_urlencode (source->audio_info, '&');
|
||||
if (s)
|
||||
add_yp_info (yp, "audio_info", s, YP_AUDIO_INFO);
|
||||
free(s);
|
||||
return yp;
|
||||
} while (0);
|
||||
|
||||
@ -606,7 +597,7 @@ static void check_servers ()
|
||||
ypdata_t *yp;
|
||||
|
||||
source_t *source = node->key;
|
||||
if ((yp = create_yp_entry (source)) != NULL)
|
||||
if ((yp = create_yp_entry (source->mount)) != NULL)
|
||||
{
|
||||
DEBUG1 ("Adding existing mount %s", source->mount);
|
||||
yp->server = server;
|
||||
@ -764,7 +755,7 @@ static void yp_destroy_ypdata(ypdata_t *ypdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
static void add_yp_info (ypdata_t *yp, void *info, int type)
|
||||
{
|
||||
char *escaped;
|
||||
|
||||
@ -780,7 +771,6 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
if (yp->server_name)
|
||||
free (yp->server_name);
|
||||
yp->server_name = escaped;
|
||||
stats_event (yp->mount, stat_name, (char *)info);
|
||||
}
|
||||
break;
|
||||
case YP_SERVER_DESC:
|
||||
@ -790,7 +780,6 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
if (yp->server_desc)
|
||||
free (yp->server_desc);
|
||||
yp->server_desc = escaped;
|
||||
stats_event(yp->mount, stat_name, (char *)info);
|
||||
}
|
||||
break;
|
||||
case YP_SERVER_GENRE:
|
||||
@ -800,7 +789,6 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
if (yp->server_genre)
|
||||
free (yp->server_genre);
|
||||
yp->server_genre = escaped;
|
||||
stats_event (yp->mount, stat_name, (char *)info);
|
||||
}
|
||||
break;
|
||||
case YP_SERVER_URL:
|
||||
@ -810,7 +798,6 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
if (yp->url)
|
||||
free (yp->url);
|
||||
yp->url = escaped;
|
||||
stats_event (yp->mount, stat_name, (char *)info);
|
||||
}
|
||||
break;
|
||||
case YP_BITRATE:
|
||||
@ -820,13 +807,15 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
if (yp->bitrate)
|
||||
free (yp->bitrate);
|
||||
yp->bitrate = escaped;
|
||||
stats_event (yp->mount, stat_name, (char *)info);
|
||||
}
|
||||
break;
|
||||
case YP_AUDIO_INFO:
|
||||
if (yp->audio_info)
|
||||
escaped = util_url_escape(info);
|
||||
if (escaped)
|
||||
{
|
||||
free (yp->audio_info);
|
||||
yp->audio_info = strdup (info);
|
||||
yp->audio_info = escaped;
|
||||
}
|
||||
break;
|
||||
case YP_SERVER_TYPE:
|
||||
escaped = util_url_escape(info);
|
||||
@ -844,7 +833,6 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
if (yp->current_song)
|
||||
free (yp->current_song);
|
||||
yp->current_song = escaped;
|
||||
stats_event (yp->mount, "yp_currently_playing", (char *)info);
|
||||
}
|
||||
break;
|
||||
case YP_CLUSTER_PASSWORD:
|
||||
@ -869,7 +857,7 @@ static void add_yp_info (ypdata_t *yp, char *stat_name, void *info, int type)
|
||||
|
||||
|
||||
/* Add YP entries to active servers */
|
||||
void yp_add (source_t *source)
|
||||
void yp_add (const char *mount)
|
||||
{
|
||||
struct yp_server *server;
|
||||
|
||||
@ -883,9 +871,9 @@ void yp_add (source_t *source)
|
||||
{
|
||||
ypdata_t *yp;
|
||||
/* add new ypdata to each servers pending yp */
|
||||
if ((yp = create_yp_entry (source)) != NULL)
|
||||
if ((yp = create_yp_entry (mount)) != NULL)
|
||||
{
|
||||
DEBUG2 ("Adding %s to %s", source->mount, server->url);
|
||||
DEBUG2 ("Adding %s to %s", mount, server->url);
|
||||
yp->server = server;
|
||||
yp->touch_interval = server->touch_interval;
|
||||
yp->next = server->pending_mounts;
|
||||
|
4
src/yp.h
4
src/yp.h
@ -25,12 +25,10 @@
|
||||
#define YP_CLUSTER_PASSWORD 9
|
||||
#define YP_SUBTYPE 10
|
||||
|
||||
struct source_tag;
|
||||
|
||||
#define YP_ADD_ALL -1
|
||||
|
||||
#ifdef USE_YP
|
||||
void yp_add (struct source_tag *source);
|
||||
void yp_add (const char *mount);
|
||||
void yp_remove (const char *mount);
|
||||
void yp_touch (const char *mount);
|
||||
void yp_recheck_config (ice_config_t *config);
|
||||
|
Loading…
Reference in New Issue
Block a user