static ypdata_t *create_yp_entry (const char *mount) { ypdata_t *yp; char *s; yp = calloc (1, sizeof (ypdata_t)); do { unsigned len = 512; int ret; char *url; mount_proxy *mountproxy = NULL; ice_config_t *config; if (yp == NULL) break; yp->mount = strdup (mount); yp->server_name = strdup (""); yp->server_desc = strdup (""); yp->server_genre = strdup (""); yp->bitrate = strdup (""); yp->server_type = strdup (""); yp->cluster_password = strdup (""); yp->url = strdup (""); yp->current_song = strdup (""); yp->audio_info = strdup (""); yp->subtype = strdup (""); yp->process = do_yp_add; url = malloc (len); if (url == NULL) break; config = config_get_config(); 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, mount); } mountproxy = config_find_mount (config, mount); if (mountproxy && mountproxy->cluster_password) add_yp_info (yp, mountproxy->cluster_password, YP_CLUSTER_PASSWORD); config_release_config(); yp->listen_url = util_url_escape (url); free (url); if (yp->listen_url == NULL) break; yp_schedule (yp, 0); return yp; } while (0); yp_destroy_ypdata (yp); return NULL; }
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"); 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", yp->server_name, yp->server_genre, yp->cluster_password, yp->server_desc, yp->url, yp->listen_url, yp->server_type, yp->subtype, yp->bitrate, yp->audio_info); if (ret >= (signed)len) return ret+1; if (send_to_yp ("add", yp, s) == 0) { yp->process = do_yp_touch; /* force first touch in 5 secs */ yp->next_update = time(NULL) + 5; } return 0; }
/* the incoming rate can vary a fair bit so to get the expected value I add about 10% * (to handle lower figures) and then refer to the most significant 3 bits using shift * ops. This should give us a resoanble estimation for YP */ static void set_bitrate_from_inrate (ypdata_t *yp) { char *value = stats_get_value (yp->mount, "incoming_bitrate"); if (value) { long v = atol (value), c = 0; char buf [12]; v = (long)(v*1.1) + 5; for (; v > 7; c++) v >>= 1; v <<= c; v /= 1024; snprintf (buf, sizeof buf, "%ld", v); add_yp_info (yp, buf, YP_BITRATE); free (value); } }
static unsigned do_yp_touch (ypdata_t *yp, char *s, unsigned len) { unsigned listeners = 0; char *val, *artist, *title; int ret; artist = (char *)stats_get_value (yp->mount, "artist"); title = (char *)stats_get_value (yp->mount, "title"); if (artist || title) { char *song; char *separator = " - "; if (artist == NULL) { artist = strdup(""); separator = ""; } if (title == NULL) title = strdup(""); song = malloc (strlen (artist) + strlen (title) + strlen (separator) +1); if (song) { sprintf (song, "%s%s%s", artist, separator, title); add_yp_info(yp, "yp_currently_playing", song, YP_CURRENT_SONG); free (song); } } free (artist); free (title); val = (char *)stats_get_value (yp->mount, "listeners"); if (val) { listeners = atoi (val); free (val); } ret = snprintf (s, len, "action=touch&sid=%s&st=%s&listeners=%u\r\n", yp->sid, yp->current_song, listeners); if (ret >= (signed)len) return ret+1; /* space required for above text and nul*/ send_to_yp ("touch", yp, s); return 0; }
static ypdata_t *create_yp_entry (source_t *source) { ypdata_t *yp; char *s; if (source->running == 0 || source->yp_public == 0) return NULL; yp = calloc (1, sizeof (ypdata_t)); do { unsigned len = 512; int ret; char *url; ice_config_t *config; if (yp == NULL) break; yp->mount = strdup (source->mount); yp->server_name = strdup (""); yp->server_desc = strdup (""); yp->server_genre = strdup (""); yp->bitrate = strdup (""); yp->server_desc = strdup (""); yp->server_type = strdup (""); yp->cluster_password = strdup (""); yp->url = strdup (""); yp->current_song = strdup (""); yp->audio_info = strdup (""); yp->process = do_yp_add; url = malloc (len); if (url == NULL) break; config = config_get_config(); ret = snprintf (url, len, "http://%s:%d%s", config->hostname, config->port, source->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); } config_release_config(); yp->listen_url = util_url_escape (url); free (url); if (yp->listen_url == NULL) break; /* ice-* is icecast, icy-* is shoutcast */ add_yp_info (yp, "server_type", source->format->format_description, 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); yp_destroy_ypdata (yp); return NULL; }
static int do_yp_touch (ypdata_t *yp, char *s, unsigned len) { unsigned listeners = 0, max_listeners = 1; char *val, *artist, *title; int ret; artist = (char *)stats_get_value (yp->mount, "artist"); title = (char *)stats_get_value (yp->mount, "title"); if (artist || title) { char *song; char *separator = " - "; if (artist == NULL) { artist = strdup(""); separator = ""; } if (title == NULL) title = strdup(""); song = malloc (strlen (artist) + strlen (title) + strlen (separator) +1); if (song) { sprintf (song, "%s%s%s", artist, separator, title); add_yp_info(yp, song, YP_CURRENT_SONG); stats_event_flags (yp->mount, "yp_currently_playing", song, STATS_COUNTERS); free (song); } } free (artist); free (title); val = (char *)stats_get_value (yp->mount, "listeners"); if (val) { listeners = atoi (val); free (val); } val = stats_get_value (yp->mount, "max_listeners"); if (val == NULL || strcmp (val, "unlimited") == 0 || atoi(val) < 0) max_listeners = client_limit; else max_listeners = atoi (val); free (val); val = stats_get_value (yp->mount, "subtype"); if (val) { add_yp_info (yp, val, YP_SUBTYPE); free (val); } ret = snprintf (s, len, "action=touch&sid=%s&st=%s" "&listeners=%u&max_listeners=%u&stype=%s\r\n", yp->sid, yp->current_song, listeners, max_listeners, yp->subtype); if (ret >= (signed)len) return ret+1; /* space required for above text and nul*/ if (send_to_yp ("touch", yp, s) == 0) { yp_schedule (yp, yp->touch_interval); return 0; } return -1; }
static int 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"); if (value) { add_yp_info (yp, value, YP_BITRATE); free (value); } else set_bitrate_from_inrate (yp); 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"); 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); if (yp->server_name[0] == 0 || yp->server_genre[0] == 0 || yp->server_type[0] == 0 || yp->bitrate[0] == 0) { INFO1 ("mount %s requires stats (sn, genre, type, bitrate)", yp->mount); yp_schedule (yp, 600); return -1; } 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", yp->server_name, yp->server_genre, yp->cluster_password, yp->server_desc, yp->url, yp->listen_url, yp->server_type, yp->subtype, yp->bitrate, yp->audio_info); if (ret >= (signed)len) return ret+1; ret = send_to_yp ("add", yp, s); if (ret == 0) { yp->process = do_yp_touch; /* force first touch in 5 secs */ yp_schedule (yp, 5); } return ret; }