Ejemplo n.º 1
0
/* build an XML doc containing information about currently running sources.
 * If a mountpoint is passed then that source will not be added to the XML
 * doc even if the source is running */
xmlDocPtr admin_build_sourcelist (const char *mount)
{
    avl_node *node;
    source_t *source;
    xmlNodePtr xmlnode, srcnode;
    xmlDocPtr doc;
    char buf[22];
    time_t now = time(NULL);

    doc = xmlNewDoc(XMLSTR("1.0"));
    xmlnode = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
    xmlDocSetRootElement(doc, xmlnode);

    if (mount) {
        xmlNewChild(xmlnode, NULL, XMLSTR("current_source"), XMLSTR(mount));
    }

    node = avl_get_first(global.source_tree);
    while(node) {
        source = (source_t *)node->key;
        if (mount && strcmp (mount, source->mount) == 0)
        {
            node = avl_get_next (node);
            continue;
        }

        thread_mutex_lock (&source->lock);
        if (source_available (source))
        {
            ice_config_t *config;
            mount_proxy *mountinfo;

            srcnode = xmlNewChild (xmlnode, NULL, XMLSTR("source"), NULL);
            xmlSetProp (srcnode, XMLSTR("mount"), XMLSTR(source->mount));

            snprintf (buf, sizeof(buf), "%lu", source->listeners);
            xmlNewChild (srcnode, NULL, XMLSTR("listeners"), XMLSTR(buf));

            config = config_get_config();
            mountinfo = config_find_mount (config, source->mount);
            if (mountinfo)
            {
                if (mountinfo->auth)
                {
                    xmlNewChild (srcnode, NULL, XMLSTR("authenticator"), 
                            XMLSTR(mountinfo->auth->type));
                }
                if (mountinfo->fallback_mount)
                    xmlNewChild (srcnode, NULL, XMLSTR("fallback"), 
                            XMLSTR(mountinfo->fallback_mount));
            }
            config_release_config();

            if (source_running (source))
            {
                if (source->client)
                {
                    snprintf (buf, sizeof(buf), "%lu",
                            (unsigned long)(now - source->client->connection.con_time));
                    xmlNewChild (srcnode, NULL, XMLSTR("Connected"), XMLSTR(buf));
                }
                xmlNewChild (srcnode, NULL, XMLSTR("content-type"), 
                        XMLSTR(source->format->contenttype));
            }
        }
        thread_mutex_unlock (&source->lock);
        node = avl_get_next(node);
    }
    return(doc);
}
Ejemplo n.º 2
0
static int command_metadata (client_t *client, source_t *source, int response)
{
    const char *song, *title, *artist, *artwork, *charset, *url;
    format_plugin_t *plugin;
    xmlDocPtr doc;
    xmlNodePtr node;
    int same_ip = 1;

    doc = xmlNewDoc(XMLSTR("1.0"));
    node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
    xmlDocSetRootElement(doc, node);

    DEBUG0("Got metadata update request");

    COMMAND_OPTIONAL(client, "song", song);
    COMMAND_OPTIONAL(client, "title", title);
    COMMAND_OPTIONAL(client, "artist", artist);
    COMMAND_OPTIONAL(client, "url", url);
    COMMAND_OPTIONAL(client, "artwork", artwork);
    COMMAND_OPTIONAL(client, "charset", charset);

    plugin = source->format;
    if (source_running (source))
        if (strcmp (client->connection.ip, source->client->connection.ip) != 0)
            if (response == RAW && connection_check_admin_pass (client->parser) == 0)
                same_ip = 0;

    do
    {
        if (same_ip == 0 || plugin == NULL)
            break;
        if (artwork)
            stats_event (source->mount, "artwork", artwork);
        if (plugin->set_tag)
        {
            if (url)
            {
                plugin->set_tag (plugin, "url", url, charset);
                INFO2 ("Metadata url on %s set to \"%s\"", source->mount, url);
            }
            if (song)
            {
                plugin->set_tag (plugin, "artist", NULL, NULL);
                plugin->set_tag (plugin, "title", song, charset);
                INFO2("Metadata song on %s set to \"%s\"", source->mount, song);
            }
            if (artist)
            {
                plugin->set_tag (plugin, "artist", artist, charset);
                INFO2 ("Metadata artist on %s changed to \"%s\"", source->mount, artist);
            }
            if (title)
            {
                plugin->set_tag (plugin, "title", title, charset);
                INFO2 ("Metadata title on %s changed to \"%s\"", source->mount, title);
            }
            /* updates are now done, let them be pushed into the stream */
            plugin->set_tag (plugin, NULL, NULL, charset);
        }
        else
        {
            break;
        }
        thread_mutex_unlock (&source->lock);
        xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR("Metadata update successful"));
        xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
        return admin_send_response(doc, client, response, "response.xsl");

    } while (0);
    INFO1 ("Metadata on mountpoint %s prevented", source->mount);
    thread_mutex_unlock (&source->lock);
    xmlNewChild(node, NULL, XMLSTR("message"), 
            XMLSTR("Mountpoint will not accept this URL update"));
    xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
    return admin_send_response(doc, client, response, "response.xsl");
}
Ejemplo n.º 3
0
static int command_metadata (client_t *client, source_t *source, int response)
{
    const char *song, *title, *artist, *artwork, *charset, *url;
    format_plugin_t *plugin;
    xmlDocPtr doc;
    xmlNodePtr node;
    int same_ip = 1;

    doc = xmlNewDoc(XMLSTR("1.0"));
    node = xmlNewDocNode(doc, NULL, XMLSTR("iceresponse"), NULL);
    xmlDocSetRootElement(doc, node);

    DEBUG0("Got metadata update request");

    COMMAND_OPTIONAL(client, "song", song);
    COMMAND_OPTIONAL(client, "title", title);
    COMMAND_OPTIONAL(client, "artist", artist);
    COMMAND_OPTIONAL(client, "url", url);
    COMMAND_OPTIONAL(client, "artwork", artwork);
    COMMAND_OPTIONAL(client, "charset", charset);

    plugin = source->format;
    if (source_running (source))
        if (strcmp (client->connection.ip, source->client->connection.ip) != 0)
            if (response == RAW && connection_check_admin_pass (client->parser) == 0)
                same_ip = 0;

	/* Update stream metadata if needed */
	if (same_ip) {
		static const struct {
			const char		*param;
			const char		*stat_name;
			const char		*hdr[3];
		} fwd[] = {
			{"xstreamname",			"server_name", 			{"ice-name",		"icy-name",			"x-audiocast-name"}},
			{"xstreamdesc",			"server_description",	{"ice-description",	"icy-description",	"x-audiocast-description"}},
			{"xstreamurl",			"server_url",			{"ice-url",			"icy-url",			"x-audiocast-url"}},
			{"xstreamgenre",		"genre",				{"ice-genre",		"icy-genre",		"x-audiocast-genre"}}
		};
		unsigned i;
		for (i = 0; i < sizeof(fwd) / sizeof(*fwd); i++) {
			const char *value;
			unsigned j;
			COMMAND_OPTIONAL(client, fwd[i].param, value);
			if (value && *value) {
				value = auto_recode(value);
				if (source->format->charset)
					stats_set_conv (source->stats, fwd[i].stat_name, value, source->format->charset);
				else
					stats_set (source->stats, fwd[i].stat_name, value);
			} else if (value) {
				stats_set (source->stats, fwd[i].stat_name, NULL);
			}
			for (j = 0; j < 3; j++) {
				if (j == 0 && value && *value) {
					httpp_setvar(source->format->parser, fwd[i].hdr[j], value);
				} else if (value && !*value) {
					httpp_deletevar(source->format->parser, fwd[i].hdr[j]);
				}
			}
		}

	}

    do
    {
        if (same_ip == 0 || plugin == NULL)
            break;
		/* Charset detection (if none specified) */
		if (!charset) {
			const char *r;
			int len;
			charset = "UTF8";
#define CCONV(s) \
			if (s && (r = auto_recode(s))) { \
				len = strlen(r); \
				s = alloca(len + 1); \
				memcpy((char*)s, r, len + 1); \
			}
			CCONV(title);
			CCONV(song);
			CCONV(artist);
		}
		/* Now send prepared metadata */
        if (artwork)
            stats_event (source->mount, "artwork", artwork);
        if (plugin->set_tag)
        {
            if (url)
            {
                plugin->set_tag (plugin, "url", url, charset);
                INFO2 ("Metadata url on %s set to \"%s\"", source->mount, url);
            }
            if (song)
            {
                plugin->set_tag (plugin, "artist", NULL, NULL);
                plugin->set_tag (plugin, "title", song, charset);
                INFO2("Metadata song on %s set to \"%s\"", source->mount, song);
            }
            if (artist)
            {
                plugin->set_tag (plugin, "artist", artist, charset);
                INFO2 ("Metadata artist on %s changed to \"%s\"", source->mount, artist);
            }
            if (title)
            {
                plugin->set_tag (plugin, "title", title, charset);
                INFO2 ("Metadata title on %s changed to \"%s\"", source->mount, title);
            }
            /* updates are now done, let them be pushed into the stream */
            plugin->set_tag (plugin, NULL, NULL, NULL);
        }
        else
        {
            break;
        }
        thread_mutex_unlock (&source->lock);
        xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR("Metadata update successful"));
        xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
        return admin_send_response(doc, client, response, "response.xsl");

    } while (0);
    thread_mutex_unlock (&source->lock);
    xmlNewChild(node, NULL, XMLSTR("message"), 
            XMLSTR("Mountpoint will not accept this URL update"));
    xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
    return admin_send_response(doc, client, response, "response.xsl");
}