/* Apply the mountinfo details to the source */ static void source_apply_mount (source_t *source, mount_proxy *mountinfo) { const char *str; int val; http_parser_t *parser = NULL; DEBUG1("Applying mount information for \"%s\"", source->mount); avl_tree_rlock (source->client_tree); stats_event_args (source->mount, "listener_peak", "%lu", source->peak_listeners); if (mountinfo) { source->max_listeners = mountinfo->max_listeners; source->fallback_override = mountinfo->fallback_override; source->hidden = mountinfo->hidden; } /* if a setting is available in the mount details then use it, else * check the parser details. */ if (source->client) parser = source->client->parser; /* to be done before possible non-utf8 stats */ if (source->format && source->format->apply_settings) source->format->apply_settings (source->client, source->format, mountinfo); /* 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) stats_event (source->mount, "server_name", 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); if (source->format) stats_event_conv (source->mount, "server_name", str, source->format->charset); } /* stream description */ if (mountinfo && mountinfo->stream_description) stats_event (source->mount, "server_description", 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); if (source->format) stats_event_conv (source->mount, "server_description", str, source->format->charset); } /* stream URL */ if (mountinfo && mountinfo->stream_url) stats_event (source->mount, "server_url", 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); if (str && source->format) stats_event_conv (source->mount, "server_url", str, source->format->charset); } /* stream genre */ if (mountinfo && mountinfo->stream_genre) stats_event (source->mount, "genre", 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); if (source->format) stats_event_conv (source->mount, "genre", str, source->format->charset); } /* 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->auth) stats_event (source->mount, "authenticator", mountinfo->auth->type); else stats_event (source->mount, "authenticator", NULL); 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 && mountinfo->dumpfile) { char *filename = source->dumpfilename; source->dumpfilename = strdup (mountinfo->dumpfile); free (filename); } else source->dumpfilename = NULL; if (source->intro_file) { fclose (source->intro_file); source->intro_file = NULL; } if (mountinfo && mountinfo->intro_filename) { ice_config_t *config = config_get_config_unlocked (); unsigned int len = strlen (config->webroot_dir) + strlen (mountinfo->intro_filename) + 2; char *path = malloc (len); if (path) { FILE *f; snprintf (path, len, "%s" PATH_SEPARATOR "%s", config->webroot_dir, mountinfo->intro_filename); f = fopen (path, "rb"); if (f) source->intro_file = f; else WARN2 ("Cannot open intro file \"%s\": %s", path, strerror(errno)); free (path); } } if (mountinfo && mountinfo->queue_size_limit) source->queue_size_limit = mountinfo->queue_size_limit; if (mountinfo && mountinfo->source_timeout) source->timeout = mountinfo->source_timeout; if (mountinfo && mountinfo->burst_size >= 0) source->burst_size = (unsigned int)mountinfo->burst_size; if (mountinfo && mountinfo->fallback_when_full) source->fallback_when_full = mountinfo->fallback_when_full; avl_tree_unlock (source->client_tree); }
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) + strlen(":") + 6 + strlen(source->mount) + 1; listenurl = malloc (listen_url_size); memset (listenurl, '\000', listen_url_size); snprintf (listenurl, listen_url_size, "http://%s:%d%s", 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) { _parse_audio_info (source, str); stats_event (source->mount, "audio_info", str); } stats_event (source->mount, "listenurl", listenurl); if (listenurl) { free(listenurl); } if (source->dumpfilename != NULL) { source->dumpfile = fopen (source->dumpfilename, "ab"); if (source->dumpfile == NULL) { WARN2("Cannot open dump file \"%s\" for appending: %s, disabling.", source->dumpfilename, strerror(errno)); } } /* grab a read lock, to make sure we get a chance to cleanup */ thread_rwlock_rlock (source->shutdown_rwlock); /* start off the statistics */ source->listeners = 0; stats_event_inc (NULL, "sources"); stats_event_inc (NULL, "source_total_connections"); stats_event (source->mount, "listeners", "0"); sock_set_blocking (source->con->sock, SOCK_NONBLOCK); DEBUG0("Source creation complete"); source->last_read = time (NULL); source->running = 1; /* ** 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 ** after a failure and they should be gotten back from the waiting ** loop or jingle track or whatever the fallback is used for */ if (source->fallback_override && source->fallback_mount) { source_t *fallback_source; avl_tree_rlock(global.source_tree); fallback_source = source_find_mount(source->fallback_mount); if (fallback_source) source_move_clients (fallback_source, source); avl_tree_unlock(global.source_tree); } 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); } } }