Exemplo n.º 1
0
static int command_list_log (client_t *client, int response)
{
    refbuf_t *content;
    const char *logname = httpp_get_query_param (client->parser, "log");
    int log = -1;
    ice_config_t *config;

    if (logname == NULL)
        return client_send_400 (client, "No log specified");

    config = config_get_config ();
    if (strcmp (logname, "errorlog") == 0)
        log = config->error_log.logid;
    else if (strcmp (logname, "accesslog") == 0)
        log = config->access_log.logid;
    else if (strcmp (logname, "playlistlog") == 0)
        log = config->playlist_log.logid;

    if (log < 0)
    {
        config_release_config();
        WARN1 ("request to show unknown log \"%s\"", logname);
        return client_send_400 (client, "unknown");
    }
    content = refbuf_new (0);
    log_contents (log, &content->data, &content->len);
    config_release_config();

    if (response == XSLT)
    {
        xmlNodePtr xmlnode;
        xmlDocPtr doc;

        doc = xmlNewDoc(XMLSTR("1.0"));
        xmlnode = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
        xmlDocSetRootElement(doc, xmlnode);
        xmlNewTextChild (xmlnode, NULL, XMLSTR("log"), XMLSTR(content->data));
        refbuf_release (content);

        return admin_send_response (doc, client, XSLT, "showlog.xsl");
    }
    else
    {
        refbuf_t *http = refbuf_new (100);
        int len = snprintf (http->data, 100, "%s",
                "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\n\r\n");
        http->len = len;
        http->next = content; 
        client->respcode = 200;
        client_set_queue (client, http);
        return fserve_setup_client (client);
    }
}
Exemplo n.º 2
0
refbuf_t *refbuf_copy(refbuf_t *orig)
{
    refbuf_t *ret = refbuf_new (orig->len), *ref = ret;
    memcpy (ref->data, orig->data, orig->len);
    orig = orig->associated;
    while (orig)
    {
        ref->associated = refbuf_new (orig->len);
        ref = ref->associated;
        memcpy (ref->data, orig->data, orig->len);
        orig = orig->associated;
    }
    return ret;
}
Exemplo n.º 3
0
int command_list_mounts(client_t *client, int response)
{
    DEBUG0("List mounts request");

    client_set_queue (client, NULL);
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    if (response == TEXT)
    {
        redirector_update (client);

        snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
                "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
        client->refbuf->len = strlen (client->refbuf->data);
        client->respcode = 200;

        if (strcmp (httpp_getvar (client->parser, HTTPP_VAR_URI), "/admin/streams") == 0)
            client->refbuf->next = stats_get_streams (1);
        else
            client->refbuf->next = stats_get_streams (0);
        return fserve_setup_client (client);
    }
    else
    {
        xmlDocPtr doc;
        avl_tree_rlock (global.source_tree);
        doc = admin_build_sourcelist(NULL);
        avl_tree_unlock (global.source_tree);

        return admin_send_response (doc, client, response, "listmounts.xsl");
    }
}
Exemplo n.º 4
0
static int ebml_create_client_data (format_plugin_t *format, client_t *client)
{

    ebml_client_data_t *ebml_client_data = calloc(1, sizeof(ebml_client_data_t));
    ebml_source_state_t *ebml_source_state = format->_state;

    int ret = 0;

    if ((ebml_client_data) && (ebml_source_state->header))
    {
        ebml_client_data->header = ebml_source_state->header;
        refbuf_addref (ebml_client_data->header);   // broken, assumes too much currently
    }
    client->format_data = ebml_client_data;
    client->free_client_data = ebml_free_client_data;

    if (client->refbuf == NULL)
        client->refbuf = refbuf_new (4096);
    client->refbuf->len = 0;
    if (format_general_headers (format, client) < 0)
        return -1;

    return ret;

}
Exemplo n.º 5
0
static void _add_stats_to_stats_client (client_t *client, const char *fmt, va_list ap)
{
    event_listener_t *listener = client->shared_data;
    refbuf_t *r = listener->recent_block;

    if (r && (r->flags & STATS_BLOCK_CONNECTION) == 0)
    {
        /* lets see if we can append to an existing block */
        if (r->len < 1390)
        {
            int written = _append_to_bufferv (r, 1400, fmt, ap);
            if (written > 0)
            {
                listener->content_len += written;
                return;
            }
        }
    }
    r = refbuf_new (1400);
    r->len = 0;
    if (_append_to_bufferv (r, 1400, fmt, ap) < 0)
    {
        WARN1 ("stat details are too large \"%s\"", fmt);
        refbuf_release (r);
        return;
    }
    _add_node_to_stats_client (client, r);
    client->schedule_ms = 0;
}
Exemplo n.º 6
0
int client_send_404 (client_t *client, const char *message)
{
    int ret = -1;

    if (client->worker == NULL)   /* client is not on any worker now */
    {
        client_destroy (client);
        return 0;
    }
    client_set_queue (client, NULL);
    if (client->respcode)
    {
        worker_t *worker = client->worker;
        if (client->respcode >= 300)
            client->flags = client->flags & ~CLIENT_AUTHENTICATED;
        client->flags |= CLIENT_ACTIVE;
        worker_wakeup (worker);
    }
    else
    {
        if (client->parser->req_type == httpp_req_head || message == NULL)
            message = "Not Available";
        ret = strlen (message);
        client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
        snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
                "HTTP/1.0 404 Not Available\r\n"
                "%s\r\nContent-Length: %d\r\nContent-Type: text/html\r\n\r\n"
                "%s", client_keepalive_header (client), ret,
                message ? message: "");
        client->respcode = 404;
        client->refbuf->len = strlen (client->refbuf->data);
        ret = fserve_setup_client (client);
    }
    return ret;
}
Exemplo n.º 7
0
int client_send_404 (client_t *client, const char *message)
{
    int ret = -1;

    if (client->worker == NULL)   /* client is not on any worker now */
    {
        client_destroy (client);
        return 0;
    }
    client_set_queue (client, NULL);
    if (client->respcode)
    {
        worker_t *worker = client->worker;
        if (client->respcode >= 300)
            client->flags = client->flags & ~CLIENT_AUTHENTICATED;
        client->flags |= CLIENT_ACTIVE;
        worker_wakeup (worker);
    }
    else
    {
        if (message == NULL)
            message = "Not Available";
        client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
        snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
                "HTTP/1.0 404 Not Available\r\n"
                "Content-Type: text/html\r\n\r\n"
                "<b>%s</b>\r\n", message);
        client->respcode = 404;
        client->refbuf->len = strlen (client->refbuf->data);
        ret = fserve_setup_client (client);
    }
    return ret;
}
Exemplo n.º 8
0
/* create a client_t with the provided connection and parser details. Return
 * 0 on success, -1 if server limit has been reached.  In either case a
 * client_t is returned just in case a message needs to be returned. Should
 * be called with global lock held.
 */
int client_create (client_t **c_ptr, connection_t *con, http_parser_t *parser)
{
    ice_config_t *config;
    client_t *client = (client_t *)calloc(1, sizeof(client_t));
    int ret = -1;

    if (client == NULL)
        abort();

    config = config_get_config ();

    global.clients++;
    if (config->client_limit < global.clients)
        WARN2 ("server client limit reached (%d/%d)", config->client_limit, global.clients);
    else
        ret = 0;

    config_release_config ();

    stats_event_args (NULL, "clients", "%d", global.clients);
    client->con = con;
    client->parser = parser;
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    client->refbuf->len = 0; /* force reader code to ignore buffer contents */
    client->pos = 0;
    client->write_to_client = format_generic_write_to_client;
    *c_ptr = client;

    return ret;
}
Exemplo n.º 9
0
static int xslt_write_callback (void *ctxt, const char *data, int len)
{
    struct bufs *x = ctxt;
    refbuf_t *r;
    int loop = 10;

    if (len == 0)
        return 0;
    if (len < 0 || len > 2000000)
    {
        ERROR1 ("%d length requested", len);
        return -1;
    }
    while (loop)
    {
        r = *x->tail;
        if (r)
        {
            x->tail = &r->next;
            loop--;
            continue;
        }
        *x->tail = r = refbuf_new (len);
        memcpy (r->data, data, len);
        x->len += len;
        break;
    }
    return len;
}
Exemplo n.º 10
0
static int xslt_write_callback (void *ctxt, const char *data, int len)
{
    struct bufs *x = ctxt;
    refbuf_t *r;
    int loop = 10;

    if (len == 0)
        return 0;
    if (len < 0 || len > 2000000)
    {
        ERROR1 ("%d length requested", len);
        return -1;
    }
    while (loop)
    {
        int size = len > 4096 ? len : 4096;
        if (*x->tail == NULL)
        {
            *x->tail = refbuf_new (size);
            (*x->tail)->len = 0;
        }
        r = *x->tail;
        if (r->len + len > size)
        {
            x->tail = &r->next;
            loop--;
            continue;
        }
        memcpy (r->data + r->len, data, len);
        r->len += len;
        x->len += len;
        break;
    }
    return len;
}
Exemplo n.º 11
0
refbuf_t *make_refbuf_with_page (ogg_page *page)
{
    refbuf_t *refbuf = refbuf_new (page->header_len + page->body_len);

    memcpy (refbuf->data, page->header, page->header_len);
    memcpy (refbuf->data+page->header_len, page->body, page->body_len);
    return refbuf;
}
Exemplo n.º 12
0
int format_file_read (client_t *client, format_plugin_t *plugin, FILE *fp)
{
    refbuf_t *refbuf = client->refbuf;
    size_t bytes = -1;
    int unprocessed = 0;

    do
    {
        if (refbuf == NULL)
        {
            if (fp == NULL)
                return -2;
            refbuf = client->refbuf = refbuf_new (4096);
            client->pos = refbuf->len;
            client->intro_offset = 0;
            client->queue_pos = 0;
        }
        if (client->pos < refbuf->len)
            break;
        if (fp == NULL || client->flags & CLIENT_HAS_INTRO_CONTENT)
        {
            if (refbuf->next)
            {
                //DEBUG1 ("next intro block is %d", refbuf->next->len);
                client->refbuf = refbuf->next;
                refbuf->next = NULL;
                refbuf_release (refbuf);
                client->pos = 0;
                return 0;
            }
            //DEBUG0 ("No more intro data ");
            client_set_queue (client, NULL);
            client->flags &= ~CLIENT_HAS_INTRO_CONTENT;
            client->intro_offset = client->connection.sent_bytes;
            refbuf = NULL;
            continue;
        }

        if (fseek (fp, client->intro_offset, SEEK_SET) < 0 ||
                (bytes = fread (refbuf->data, 1, 4096, fp)) <= 0)
        {
            return bytes < 0 ? -2 : -1;
        }
        refbuf->len = bytes;
        client->pos = 0;
        if (plugin->align_buffer)
        {
            /* here the buffer may require truncating to keep the buffers aligned on
             * certain boundaries */
            unprocessed = plugin->align_buffer (client, plugin);
            if (unprocessed < 0 || unprocessed >= bytes)
                unprocessed = 0;
        }
        client->intro_offset += (bytes - unprocessed);
    } while (1);
    return 0;
}
Exemplo n.º 13
0
static void _handle_source_request (client_t *client, char *uri, int auth_style)
{
    source_t *source;

    INFO1("Source logging in at mountpoint \"%s\"", uri);

    if (uri[0] != '/')
    {
        WARN0 ("source mountpoint not starting with /");
        client_send_401 (client);
        return;
    }
    if (auth_style == ICECAST_SOURCE_AUTH) {
        if (connection_check_source_pass (client->parser, uri) == 0)
        {
            /* We commonly get this if the source client is using the wrong
             * protocol: attempt to diagnose this and return an error
             */
            /* TODO: Do what the above comment says */
            INFO1("Source (%s) attempted to login with invalid or missing password", uri);
            client_send_401(client);
            return;
        }
    }
    source = source_reserve (uri);
    if (source)
    {
        if (auth_style == SHOUTCAST_SOURCE_AUTH) {
            source->shoutcast_compat = 1;
        }
        source->client = client;
        source->parser = client->parser;
        source->con = client->con;
        if (connection_complete_source (source, 1) < 0)
        {
            source_clear_source (source);
            source_free_source (source);
        }
        else
        {
            refbuf_t *ok = refbuf_new (PER_CLIENT_REFBUF_SIZE);
            client->respcode = 200;
            snprintf (ok->data, PER_CLIENT_REFBUF_SIZE,
                    "HTTP/1.0 200 OK\r\n\r\n");
            ok->len = strlen (ok->data);
            /* we may have unprocessed data read in, so don't overwrite it */
            ok->associated = client->refbuf;
            client->refbuf = ok;
            fserve_add_client_callback (client, source_client_callback, source);
        }
    }
    else
    {
        client_send_404 (client, "Mountpoint in use");
        WARN1 ("Mountpoint %s in use", uri);
    }
}
Exemplo n.º 14
0
/* return a list of blocks which contain lines of text. Each line is a mountpoint
 * reference that a slave will use for relaying.  The prepend setting is to indicate
 * if some something else needs to be added to each line.
 */
refbuf_t *stats_get_streams (int prepend)
{
#define STREAMLIST_BLKSIZE  4096
    avl_node *node;
    unsigned int remaining = STREAMLIST_BLKSIZE, prelen;
    refbuf_t *start = refbuf_new (remaining), *cur = start;
    const char *pre = "";
    char *buffer = cur->data;

    if (prepend)
        pre = "/admin/streams?mount=";
    prelen = strlen (pre);

    /* now the stats for each source */
    avl_tree_rlock (_stats.source_tree);
    node = avl_get_first(_stats.source_tree);
    while (node)
    {
        int ret;
        stats_source_t *source = (stats_source_t *)node->key;

        if ((source->flags & STATS_HIDDEN) == 0)
        {
            if (remaining <= strlen (source->source) + prelen + 3)
            {
                cur->len = STREAMLIST_BLKSIZE - remaining;
                cur->next = refbuf_new (STREAMLIST_BLKSIZE);
                remaining = STREAMLIST_BLKSIZE;
                cur = cur->next;
                buffer = cur->data;
            }
            ret = snprintf (buffer, remaining, "%s%s\r\n", pre, source->source);
            if (ret > 0)
            {
                buffer += ret;
                remaining -= ret;
            }
        }
        node = avl_get_next(node);
    }
    avl_tree_unlock (_stats.source_tree);
    cur->len = STREAMLIST_BLKSIZE - remaining;
    return start;
}
Exemplo n.º 15
0
int client_send_501(client_t *client)
{
    client_set_queue (client, NULL);
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
            "HTTP/1.0 501 Not Implemented\r\n\r\n");
    client->respcode = 501;
    client->refbuf->len = strlen (client->refbuf->data);
    return fserve_setup_client (client);
}
Exemplo n.º 16
0
int client_send_416(client_t *client)
{
    client_set_queue (client, NULL);
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
            "HTTP/1.0 416 Request Range Not Satisfiable\r\n\r\n");
    client->respcode = 416;
    client->refbuf->len = strlen (client->refbuf->data);
    return fserve_setup_client (client);
}
Exemplo n.º 17
0
int format_file_read (client_t *client, format_plugin_t *plugin, icefile_handle f)
{
    refbuf_t *refbuf = client->refbuf;
    ssize_t bytes = -1;
    int unprocessed = 0;

    do
    {
        if (refbuf == NULL)
        {
            if (file_in_use (f) == 0)
                return -2;
            refbuf = client->refbuf = refbuf_new (8192);
            client->flags |= CLIENT_HAS_INTRO_CONTENT;
            client->pos = refbuf->len;
            client->queue_pos = 0;
        }
        if (client->pos < refbuf->len)
            break;

        if (refbuf->next)
        {
            //DEBUG1 ("next intro block is %d", refbuf->next->len);
            client->refbuf = refbuf->next;
            refbuf->next = NULL;
            refbuf_release (refbuf);
            client->pos = 0;
            return 0;
        }

        if (file_in_use (f) == 0) return -2;

        bytes = pread (f, refbuf->data, 8192, client->intro_offset);
        if (bytes <= 0)
            return bytes < 0 ? -2 : -1;

        refbuf->len = bytes;
        client->pos = 0;
        if (plugin && plugin->align_buffer)
        {
            /* here the buffer may require truncating to keep the buffers aligned on
             * certain boundaries */
            unprocessed = plugin->align_buffer (client, plugin);
            if (unprocessed == bytes)
                return -1;
            if (unprocessed < 0 || unprocessed > bytes)
            {
                unprocessed = 0;
                client->connection.error = 1;
            }
        }
        client->intro_offset += (bytes - unprocessed);
    } while (1);
    return refbuf->len - client->pos;
}
Exemplo n.º 18
0
static refbuf_t *ebml_get_buffer (source_t *source)
{

    ebml_source_state_t *ebml_source_state = source->format->_state;
    format_plugin_t *format = source->format;
    char *data = NULL;
    int bytes = 0;
    refbuf_t *refbuf;
    int ret;

    while (1)
    {

        if ((bytes = ebml_read_space(ebml_source_state->ebml)) > 0)
        {
            refbuf = refbuf_new(bytes);
            ebml_read(ebml_source_state->ebml, refbuf->data, bytes);

            if (ebml_source_state->header == NULL)
            {
                ebml_source_state->header = refbuf;
                continue;
            }

            if (ebml_last_was_sync(ebml_source_state->ebml))
            {
                refbuf->flags |= SOURCE_BLOCK_SYNC;
            }
            if (refbuf->len > 0)
            {
                source->client->queue_pos += refbuf->len;
            }
            return refbuf;

        }
        else
        {

            data = ebml_write_buffer(ebml_source_state->ebml, EBML_SLICE_SIZE);
            bytes = client_read_bytes (source->client, data, EBML_SLICE_SIZE);
            if (bytes <= 0)
            {
                ebml_wrote (ebml_source_state->ebml, 0);
                return NULL;
            }
            format->read_bytes += bytes;
            ret = ebml_wrote (ebml_source_state->ebml, bytes);
            if (ret != bytes) {
                ERROR0 ("Problem processing stream");
                source->flags &= ~SOURCE_RUNNING;
                return NULL;
            }
        }
    }
}
Exemplo n.º 19
0
static size_t handle_returned_data (void *ptr, size_t size, size_t nmemb, void *stream)
{
    auth_client *auth_user = stream;
    unsigned bytes = size * nmemb;
    client_t *client = auth_user->client;
    refbuf_t *r = client->refbuf;

    if (client && client->respcode == 0 && r &&
         client->flags & CLIENT_HAS_INTRO_CONTENT)
    {
        refbuf_t *n;
        struct build_intro_contents *x = (void*)r->data;

        n = refbuf_new (bytes);
        memcpy (n->data, ptr, bytes);
        if (x->type)
        {
            int unprocessed = mpeg_complete_frames (&x->sync, n, 0);
            if (unprocessed < 0)
            {
                mpeg_data_insert (&x->sync, n); /* maybe short read, less than frame */
                return (int)(bytes);
            }
            if (unprocessed > 0)
            {
                refbuf_t *next = refbuf_new (unprocessed);
                memcpy (next->data, n->data + n->len, unprocessed);
                next->len = unprocessed;
                mpeg_data_insert (&x->sync, next);
            }
        }
        if (n->len == 0)
            refbuf_release (n);
        else
        {
            *x->tailp = n;
            x->tailp = &n->next;
            x->intro_len += n->len;
        }
    }
    return (int)(bytes);
}
Exemplo n.º 20
0
int client_send_400(client_t *client, const char *message)
{
    client_set_queue (client, NULL);
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
            "HTTP/1.0 400 Bad Request\r\n"
            "Content-Type: text/html\r\n\r\n"
            "<b>%s</b>\r\n", message?message:"");
    client->respcode = 400;
    client->refbuf->len = strlen (client->refbuf->data);
    return fserve_setup_client (client);
}
Exemplo n.º 21
0
refbuf_t *make_refbuf_with_page (ogg_codec_t *codec, ogg_page *page)
{
    refbuf_t *refbuf;

    if (codec && codec->filtered)
        return NULL;
    refbuf = refbuf_new (page->header_len + page->body_len);

    memcpy (refbuf->data, page->header, page->header_len);
    memcpy (refbuf->data+page->header_len, page->body, page->body_len);
    return refbuf;
}
Exemplo n.º 22
0
int client_send_302(client_t *client, const char *location)
{
    client_set_queue (client, NULL);
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
            "HTTP/1.0 302 Temporarily Moved\r\n"
            "Content-Type: text/html\r\n"
            "Location: %s\r\n\r\n"
            "Moved <a href=\"%s\">here</a>\r\n", location, location);
    client->respcode = 302;
    client->refbuf->len = strlen (client->refbuf->data);
    return fserve_setup_client (client);
}
Exemplo n.º 23
0
int client_send_options(client_t *client)
{
    client_set_queue (client, NULL);
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
            "HTTP/1.1 200 OK\r\n"
            "Access-Control-Allow-Origin: *\r\n"
            "Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type\r\n"
            "Access-Control-Allow-Methods: GET, OPTIONS, STATS\r\n\r\n");
    client->respcode = 200;
    client->refbuf->len = strlen (client->refbuf->data);
    return fserve_setup_client (client);
}
Exemplo n.º 24
0
int client_send_403(client_t *client, const char *reason)
{
    if (reason == NULL)
        reason = "Forbidden";
    client_set_queue (client, NULL);
    client->refbuf = refbuf_new (PER_CLIENT_REFBUF_SIZE);
    snprintf (client->refbuf->data, PER_CLIENT_REFBUF_SIZE,
            "HTTP/1.0 403 %s\r\n"
            "Content-Type: text/html\r\n\r\n", reason);
    client->respcode = 403;
    client->refbuf->len = strlen (client->refbuf->data);
    return fserve_setup_client (client);
}
Exemplo n.º 25
0
refbuf_t *stats_get_streams (void)
{
#define STREAMLIST_BLKSIZE  4096
    avl_node *node;
    unsigned int remaining = STREAMLIST_BLKSIZE;
    refbuf_t *start = refbuf_new (remaining), *cur = start;
    char *buffer = cur->data;

    /* now the stats for each source */
    thread_mutex_lock (&_stats_mutex);
    node = avl_get_first(_stats.source_tree);
    while (node)
    {
        int ret;
        stats_source_t *source = (stats_source_t *)node->key;

        if (source->hidden == 0)
        {
            if (remaining <= strlen (source->source) + 3)
            {
                cur->len = STREAMLIST_BLKSIZE - remaining;
                cur->next = refbuf_new (STREAMLIST_BLKSIZE);
                remaining = STREAMLIST_BLKSIZE;
                cur = cur->next;
                buffer = cur->data;
            }
            ret = snprintf (buffer, remaining, "%s\r\n", source->source);
            if (ret > 0)
            {
                buffer += ret;
                remaining -= ret;
            }
        }
        node = avl_get_next(node);
    }
    thread_mutex_unlock(&_stats_mutex);
    cur->len = STREAMLIST_BLKSIZE - remaining;
    return start;
}
Exemplo n.º 26
0
static refbuf_t *ebml_get_buffer(source_t *source)
{

    ebml_source_state_t *ebml_source_state = source->format->_state;
    format_plugin_t *format = source->format;
    char *data = NULL;
    int bytes = 0;
    refbuf_t *refbuf;
    int ret;

    while (1)
    {

        if ((bytes = ebml_read_space(ebml_source_state->ebml)) > 0)
        {
            refbuf = refbuf_new(bytes);
            ebml_read(ebml_source_state->ebml, refbuf->data, bytes);

            if (ebml_source_state->header == NULL)
            {
                ebml_source_state->header = refbuf;
                continue;
            }

            if (ebml_last_was_sync(ebml_source_state->ebml))
            {
                refbuf->sync_point = 1;
            }
            return refbuf;

        }
        else
        {

            data = ebml_write_buffer(ebml_source_state->ebml, EBML_SLICE_SIZE);
            bytes = client_read_bytes (source->client, data, EBML_SLICE_SIZE);
            if (bytes <= 0)
            {
                ebml_wrote (ebml_source_state->ebml, 0);
                return NULL;
            }
            format->read_bytes += bytes;
            ret = ebml_wrote (ebml_source_state->ebml, bytes);
            if (ret != bytes) {
                ICECAST_LOG_ERROR("Problem processing stream");
                source->running = 0;
                return NULL;
            }
        }
    }
}
Exemplo n.º 27
0
/* called from the source thread when the metadata has been updated.
 * The artist title are checked and made ready for clients to send
 */
static void mp3_set_title (source_t *source)
{
    const char meta[] = "StreamTitle='";
    int size;
    unsigned char len_byte;
    refbuf_t *p;
    unsigned int len = sizeof(meta) + 2; /* the StreamTitle, quotes, ; and null */
    mp3_state *source_mp3 = source->format->_state;

    /* make sure the url data does not disappear from under us */
    thread_mutex_lock (&source_mp3->url_lock);

    /* work out message length */
    if (source_mp3->url_artist)
        len += strlen (source_mp3->url_artist);
    if (source_mp3->url_title)
        len += strlen (source_mp3->url_title);
    if (source_mp3->url_artist && source_mp3->url_title)
        len += 3;
#define MAX_META_LEN 255*16
    if (len > MAX_META_LEN)
    {
        thread_mutex_unlock (&source_mp3->url_lock);
        WARN1 ("Metadata too long at %d chars", len);
        return;
    }
    /* work out the metadata len byte */
    len_byte = (len-1) / 16 + 1;

    /* now we know how much space to allocate, +1 for the len byte */
    size = len_byte * 16 + 1;

    p = refbuf_new (size);
    if (p)
    {
        mp3_state *source_mp3 = source->format->_state;

        memset (p->data, '\0', size);
        if (source_mp3->url_artist && source_mp3->url_title)
            snprintf (p->data, size, "%c%s%s - %s';", len_byte, meta,
                    source_mp3->url_artist, source_mp3->url_title);
        else
            snprintf (p->data, size, "%c%s%s';", len_byte, meta,
                    source_mp3->url_title);
        filter_shoutcast_metadata (source, p->data, size);

        refbuf_release (source_mp3->metadata);
        source_mp3->metadata = p;
    }
    thread_mutex_unlock (&source_mp3->url_lock);
}
Exemplo n.º 28
0
int format_mp3_get_plugin (source_t *source)
{
    const char *metadata;
    format_plugin_t *plugin;
    mp3_state *state = calloc(1, sizeof(mp3_state));
    refbuf_t *meta;

    plugin = (format_plugin_t *)calloc(1, sizeof(format_plugin_t));

    plugin->type = FORMAT_TYPE_GENERIC;
    plugin->get_buffer = mp3_get_no_meta;
    plugin->write_buf_to_client = format_mp3_write_buf_to_client;
    plugin->write_buf_to_file = write_mp3_to_file;
    plugin->create_client_data = format_mp3_create_client_data;
    plugin->free_plugin = format_mp3_free_plugin;
    plugin->set_tag = mp3_set_tag;
    plugin->apply_settings = format_mp3_apply_settings;

    plugin->contenttype = httpp_getvar (source->parser, "content-type");
    if (plugin->contenttype == NULL) {
        /* We default to MP3 audio for old clients without content types */
        plugin->contenttype = "audio/mpeg";
    }

    plugin->_state = state;

    /* initial metadata needs to be blank for sending to clients and for
       comparing with new metadata */
    meta = refbuf_new (17);
    memcpy (meta->data, "\001StreamTitle='';", 17);
    state->metadata = meta;
    state->interval = -1;

    metadata = httpp_getvar (source->parser, "icy-metaint");
    if (metadata)
    {
        state->inline_metadata_interval = atoi (metadata);
        if (state->inline_metadata_interval > 0)
        {
            state->offset = 0;
            plugin->get_buffer = mp3_get_filter_meta;
            state->interval = state->inline_metadata_interval;
        }
    }
    source->format = plugin;
    thread_mutex_create (&state->url_lock);

    return 0;
}
Exemplo n.º 29
0
void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client)
{
    xmlDocPtr    res;
    xsltStylesheetPtr cur;
    xmlChar *string;
    int len, problem = 0;

    xmlSetGenericErrorFunc ("", log_parse_failure);
    xsltSetGenericErrorFunc ("", log_parse_failure);

    thread_mutex_lock(&xsltlock);
    cur = xslt_get_stylesheet(xslfilename);

    if (cur == NULL)
    {
        thread_mutex_unlock(&xsltlock);
        ERROR1 ("problem reading stylesheet \"%s\"", xslfilename);
        client_send_404 (client, "Could not parse XSLT file");
        return;
    }

    res = xsltApplyStylesheet(cur, doc, NULL);

    if (xsltSaveResultToString (&string, &len, res, cur) < 0)
        problem = 1;
    thread_mutex_unlock(&xsltlock);
    if (problem == 0)
    {
        const char *http = "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nContent-Length: ";
        int buf_len = strlen (http) + 20 + len;

        if (string == NULL)
            string = xmlStrdup ("");
        client->respcode = 200;
        client_set_queue (client, NULL);
        client->refbuf = refbuf_new (buf_len);
        len = snprintf (client->refbuf->data, buf_len, "%s%d\r\n\r\n%s", http, len, string);
        client->refbuf->len = len;
        fserve_add_client (client, NULL);
        xmlFree (string);
    }
    else
    {
        WARN1 ("problem applying stylesheet \"%s\"", xslfilename);
        client_send_404 (client, "XSLT problem");
    }
    xmlFreeDoc(res);
}
Exemplo n.º 30
0
refbuf_t *refbuf_realloc (refbuf_t *refbuf, size_t newsize) {
	char *newdata;

	dprintf("reallocing to %d\n", newsize);

	if (!refbuf)
		return refbuf_new (newsize);

	newdata = realloc(refbuf->data, newsize);
	if (!newdata)
		return NULL;

	refbuf->len = newsize;
	refbuf->data = newdata;

	return refbuf;
}