From d54c61bf1315181670935d8e50434c2bed38d74a Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Tue, 2 Apr 2013 18:46:44 +0000 Subject: [PATCH] Added support for a default mount. See #1914. The default mount is a block in the config file that contains settings for all mount points that do not have a block in configfile themself. This is implemented by a -block. In this case the -block MUST NOT contain a -subblock. svn path=/icecast/trunk/icecast/; revision=18902 --- src/admin.c | 4 ++-- src/auth.c | 4 ++-- src/auth_url.c | 4 ++-- src/cfgfile.c | 40 ++++++++++++++++++++++++++++++++++------ src/cfgfile.h | 9 ++++++++- src/client.c | 2 +- src/connection.c | 4 ++-- src/format.c | 2 +- src/slave.c | 4 ++-- src/source.c | 15 ++++++++------- src/yp.c | 2 +- 11 files changed, 63 insertions(+), 27 deletions(-) diff --git a/src/admin.c b/src/admin.c index 43c79911..ddf49211 100644 --- a/src/admin.c +++ b/src/admin.c @@ -236,7 +236,7 @@ xmlDocPtr admin_build_sourcelist (const char *mount) xmlNewChild(srcnode, NULL, XMLSTR("listeners"), XMLSTR(buf)); config = config_get_config(); - mountinfo = config_find_mount (config, source->mount); + mountinfo = config_find_mount (config, source->mount, MOUNT_TYPE_NORMAL); if (mountinfo && mountinfo->auth) { xmlNewChild(srcnode, NULL, XMLSTR("authenticator"), @@ -742,7 +742,7 @@ static void command_manageauth(client_t *client, source_t *source, char *message = NULL; int ret = AUTH_OK; ice_config_t *config = config_get_config (); - mount_proxy *mountinfo = config_find_mount (config, source->mount); + mount_proxy *mountinfo = config_find_mount (config, source->mount, MOUNT_TYPE_NORMAL); do { diff --git a/src/auth.c b/src/auth.c index b5815076..a95594b4 100644 --- a/src/auth.c +++ b/src/auth.c @@ -485,7 +485,7 @@ int auth_postprocess_listener (auth_client *auth_user) client_t *client = auth_user->client; ice_config_t *config = config_get_config(); - mount_proxy *mountinfo = config_find_mount (config, auth_user->mount); + mount_proxy *mountinfo = config_find_mount (config, auth_user->mount, MOUNT_TYPE_NORMAL); ret = add_authenticated_listener (auth_user->mount, mountinfo, client); config_release_config(); @@ -530,7 +530,7 @@ void auth_add_listener (const char *mount, client_t *client) mount_proxy *mountinfo; ice_config_t *config = config_get_config(); - mountinfo = config_find_mount (config, mount); + mountinfo = config_find_mount (config, mount, MOUNT_TYPE_NORMAL); if (mountinfo && mountinfo->no_mount) { config_release_config (); diff --git a/src/auth_url.c b/src/auth_url.c index 9eefcafa..00a26ac9 100644 --- a/src/auth_url.c +++ b/src/auth_url.c @@ -412,7 +412,7 @@ static void url_stream_start (auth_client *auth_user) { char *mount, *server; ice_config_t *config = config_get_config (); - mount_proxy *mountinfo = config_find_mount (config, auth_user->mount); + mount_proxy *mountinfo = config_find_mount (config, auth_user->mount, MOUNT_TYPE_NORMAL); auth_t *auth = mountinfo->auth; auth_url *url = auth->state; char *stream_start_url; @@ -464,7 +464,7 @@ static void url_stream_end (auth_client *auth_user) { char *mount, *server; ice_config_t *config = config_get_config (); - mount_proxy *mountinfo = config_find_mount (config, auth_user->mount); + mount_proxy *mountinfo = config_find_mount (config, auth_user->mount, MOUNT_TYPE_NORMAL); auth_t *auth = mountinfo->auth; auth_url *url = auth->state; char *stream_end_url; diff --git a/src/cfgfile.c b/src/cfgfile.c index 518d9d87..42e9cb11 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -466,7 +466,7 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node, } else if (xmlStrcmp (node->name, XMLSTR("relay")) == 0) { _parse_relay(doc, node->xmlChildrenNode, configuration); } else if (xmlStrcmp (node->name, XMLSTR("mount")) == 0) { - _parse_mount(doc, node->xmlChildrenNode, configuration); + _parse_mount(doc, node, configuration); } else if (xmlStrcmp (node->name, XMLSTR("directory")) == 0) { _parse_directory(doc, node->xmlChildrenNode, configuration); } else if (xmlStrcmp (node->name, XMLSTR("paths")) == 0) { @@ -548,12 +548,30 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, mount_proxy *last=NULL; /* default settings */ + mount->mounttype = MOUNT_TYPE_NORMAL; mount->max_listeners = -1; mount->burst_size = -1; mount->mp3_meta_interval = -1; mount->yp_public = -1; mount->next = NULL; + tmp = (char *)xmlGetProp(node, XMLSTR("type")); + if (tmp) { + if (strcmp(tmp, "normal") == 0) { + mount->mounttype = MOUNT_TYPE_NORMAL; + } + else if (strcmp(tmp, "default") == 0) { + mount->mounttype = MOUNT_TYPE_DEFAULT; + } + else { + WARN1("Unknown mountpoint type: %s", tmp); + config_clear_mount (mount); + return; + } + } + + node = node->xmlChildrenNode; + do { if (node == NULL) break; if (xmlIsBlankNode(node)) continue; @@ -684,7 +702,7 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, } while ((node = node->next)); /* make sure we have at least the mountpoint name */ - if (mount->mountname == NULL) + if (mount->mountname == NULL && mount->mounttype != MOUNT_TYPE_DEFAULT) { config_clear_mount (mount); return; @@ -1126,16 +1144,26 @@ static void _add_server(xmlDocPtr doc, xmlNodePtr node, /* return the mount details that match the supplied mountpoint */ -mount_proxy *config_find_mount (ice_config_t *config, const char *mount) +mount_proxy *config_find_mount (ice_config_t *config, const char *mount, mount_type type) { mount_proxy *mountinfo = config->mounts; - while (mountinfo) + for (; mountinfo; mountinfo = mountinfo->next) { - if (strcmp (mountinfo->mountname, mount) == 0) + if (mountinfo->mounttype != type) + continue; + + if (mount == NULL || mountinfo->mountname == NULL) + break; + + if (strcmp (mountinfo->mountname, mount) == 0) break; - mountinfo = mountinfo->next; } + + /* retry with default mount */ + if (!mountinfo && type == MOUNT_TYPE_NORMAL) + mountinfo = config_find_mount(config, mount, MOUNT_TYPE_DEFAULT); + return mountinfo; } diff --git a/src/cfgfile.h b/src/cfgfile.h index a8122baf..37bc1b1c 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -44,9 +44,16 @@ typedef struct _config_options { struct _config_options *next; } config_options_t; +typedef enum _mount_type { + MOUNT_TYPE_NORMAL, + MOUNT_TYPE_DEFAULT +} mount_type; + typedef struct _mount_proxy { char *mountname; /* The mountpoint this proxy is used for */ + mount_type mounttype; /* The type of the mount point */ + char *username; /* Username and password for this mountpoint. If unset, */ char *password; /* falls back to global source password */ @@ -198,7 +205,7 @@ int config_parse_cmdline(int arg, char **argv); void config_set_config(ice_config_t *config); listener_t *config_clear_listener (listener_t *listener); void config_clear(ice_config_t *config); -mount_proxy *config_find_mount (ice_config_t *config, const char *mount); +mount_proxy *config_find_mount (ice_config_t *config, const char *mount, mount_type type); listener_t *config_get_listen_sock (ice_config_t *config, connection_t *con); int config_rehash(void); diff --git a/src/client.c b/src/client.c index a3b1e8ac..2684869f 100644 --- a/src/client.c +++ b/src/client.c @@ -133,7 +133,7 @@ int client_check_source_auth (client_t *client, const char *mount) char *pass = config->source_password; char *user = "source"; int ret = -1; - mount_proxy *mountinfo = config_find_mount (config, mount); + mount_proxy *mountinfo = config_find_mount (config, mount, MOUNT_TYPE_NORMAL); do { diff --git a/src/connection.c b/src/connection.c index b6ddc2a3..a9a5782b 100644 --- a/src/connection.c +++ b/src/connection.c @@ -851,7 +851,7 @@ int connection_complete_source (source_t *source, int response) global_unlock(); source->running = 1; - mountinfo = config_find_mount (config, source->mount); + mountinfo = config_find_mount (config, source->mount, MOUNT_TYPE_NORMAL); source_update_settings (config, source, mountinfo); config_release_config(); slave_rebuild_mounts(); @@ -1178,7 +1178,7 @@ static void _handle_shoutcast_compatible (client_queue_t *node) if (node->shoutcast == 1) { char *source_password, *ptr, *headers; - mount_proxy *mountinfo = config_find_mount (config, shoutcast_mount); + mount_proxy *mountinfo = config_find_mount (config, shoutcast_mount, MOUNT_TYPE_NORMAL); if (mountinfo && mountinfo->password) source_password = strdup (mountinfo->password); diff --git a/src/format.c b/src/format.c index 34d65639..88f42c7c 100644 --- a/src/format.c +++ b/src/format.c @@ -339,7 +339,7 @@ static int format_prepare_headers (source_t *source, client_t *client) mount_proxy *mountinfo; config = config_get_config(); - mountinfo = config_find_mount (config, source->mount); + mountinfo = config_find_mount (config, source->mount, MOUNT_TYPE_NORMAL); if (mountinfo && mountinfo->stream_name) bytes = snprintf (ptr, remaining, "icy-name:%s\r\n", mountinfo->stream_name); diff --git a/src/slave.c b/src/slave.c index 29aa2067..c0d7353f 100644 --- a/src/slave.c +++ b/src/slave.c @@ -407,7 +407,7 @@ static void check_relay_stream (relay_server *relay) if (relay->on_demand) { ice_config_t *config = config_get_config (); - mount_proxy *mountinfo = config_find_mount (config, relay->localmount); + mount_proxy *mountinfo = config_find_mount (config, relay->localmount, MOUNT_TYPE_NORMAL); if (mountinfo == NULL) source_update_settings (config, relay->source, mountinfo); config_release_config (); @@ -474,7 +474,7 @@ static void check_relay_stream (relay_server *relay) if (relay->on_demand && relay->source) { ice_config_t *config = config_get_config (); - mount_proxy *mountinfo = config_find_mount (config, relay->localmount); + mount_proxy *mountinfo = config_find_mount (config, relay->localmount, MOUNT_TYPE_NORMAL); source_update_settings (config, relay->source, mountinfo); config_release_config (); stats_event (relay->localmount, "listeners", "0"); diff --git a/src/source.c b/src/source.c index 948fc16e..1b463ef1 100644 --- a/src/source.c +++ b/src/source.c @@ -170,7 +170,7 @@ source_t *source_find_mount (const char *mount) /* we either have a source which is not active (relay) or no source * at all. Check the mounts list for fallback settings */ - mountinfo = config_find_mount (config, mount); + mountinfo = config_find_mount (config, mount, MOUNT_TYPE_NORMAL); source = NULL; if (mountinfo == NULL) @@ -662,7 +662,7 @@ static void source_init (source_t *source) source->prev_listeners = -1; source->running = 1; - mountinfo = config_find_mount (config_get_config(), source->mount); + mountinfo = config_find_mount (config_get_config(), source->mount, MOUNT_TYPE_NORMAL); if (mountinfo) { if (mountinfo->on_connect) @@ -870,7 +870,7 @@ static void source_shutdown (source_t *source) source->running = 0; INFO1("Source \"%s\" exiting", source->mount); - mountinfo = config_find_mount (config_get_config(), source->mount); + mountinfo = config_find_mount (config_get_config(), source->mount, MOUNT_TYPE_NORMAL); if (mountinfo) { if (mountinfo->on_disconnect) @@ -1423,8 +1423,11 @@ void source_recheck_mounts (int update_all) if (update_all) stats_clear_virtual_mounts (); - while (mount) + for (; mount; mount = mount->next) { + if (mount->mounttype != MOUNT_TYPE_NORMAL) + continue; + source_t *source = source_find_mount (mount->mountname); if (source) @@ -1432,7 +1435,7 @@ void source_recheck_mounts (int update_all) source = source_find_mount_raw (mount->mountname); if (source) { - mount_proxy *mountinfo = config_find_mount (config, source->mount); + mount_proxy *mountinfo = config_find_mount (config, source->mount, MOUNT_TYPE_NORMAL); source_update_settings (config, source, mountinfo); } else if (update_all) @@ -1460,8 +1463,6 @@ void source_recheck_mounts (int update_all) strdup (mount->fallback_mount), THREAD_DETACHED); } } - - mount = mount->next; } avl_tree_unlock (global.source_tree); config_release_config(); diff --git a/src/yp.c b/src/yp.c index 2f8a1760..7cf30318 100644 --- a/src/yp.c +++ b/src/yp.c @@ -593,7 +593,7 @@ static ypdata_t *create_yp_entry (const char *mount) snprintf (url, ret, "http://%s:%d%s", config->hostname, config->port, mount); } - mountproxy = config_find_mount (config, mount); + mountproxy = config_find_mount (config, mount, MOUNT_TYPE_NORMAL); if (mountproxy && mountproxy->cluster_password) add_yp_info (yp, mountproxy->cluster_password, YP_CLUSTER_PASSWORD); config_release_config();