Exemplo n.º 1
0
int xslt_transform (xmlDocPtr doc, const char *xslfilename, client_t *client)
{
    int     i, ret;
    xsl_req *x;

    thread_rwlock_rlock (&xslt_lock);
    i = xslt_cached (xslfilename, NULL, client->worker->current_time.tv_sec);
    i = xslt_req_sheet (client, doc, xslfilename, i);
    x = client->shared_data;
    switch (i)
    {
    case -1:
        thread_rwlock_unlock (&xslt_lock);
        xmlFreeDoc (doc);
        client->shared_data = NULL;
        ret = client_send_404 (client, "Could not parse XSLT file");
        break;
    case CACHESIZE:   // delayed
        thread_rwlock_unlock (&xslt_lock);
        return 0;
    default:  // found it and ok to use
        ret = xslt_send_sheet (client, doc, i);
        break;
    }
    if (x)
    {
        free (x->cache.filename);
        free (x->cache.disposition);
        free (x);
    }
    return ret;
}
Exemplo n.º 2
0
static int directory_recheck (client_t *client)
{
    int ret = -1;

    thread_rwlock_rlock (&yp_lock);
    do {
        if (ypclient.connection.error)
            break;
        if (active_yps || yp_update)
        {
            ret = 0;
            if (yp_update || active_yps->mounts)
            {
                if (yp_update || client->counter <= client->worker->current_time.tv_sec)
                {
                    client->counter = (uint64_t)-1;
                    client->flags &= ~CLIENT_ACTIVE;
                    thread_create ("YP Thread", yp_update_thread, NULL, THREAD_DETACHED);
                    break;
                }
            }
        }
        client->schedule_ms = client->worker->time_ms + 1000;
    } while (0);
    thread_rwlock_unlock (&yp_lock);
    return ret;
}
Exemplo n.º 3
0
static auth_result htpasswd_auth (auth_client *auth_user)
{
    auth_t *auth = auth_user->client->auth;
    htpasswd_auth_state *htpasswd = auth->state;
    client_t *client = auth_user->client;
    htpasswd_user entry;
    void *result;

    if (client->username == NULL || client->password == NULL)
        return AUTH_FAILED;

    htpasswd_recheckfile (htpasswd);

    thread_rwlock_rlock (&htpasswd->file_rwlock);
    entry.name = client->username;
    if (avl_get_by_key (htpasswd->users, &entry, &result) == 0)
    {
        htpasswd_user *found = result;
        char *hashed_pw;

        thread_rwlock_unlock (&htpasswd->file_rwlock);
        hashed_pw = get_hash (client->password, strlen (client->password));
        if (strcmp (found->pass, hashed_pw) == 0)
        {
            free (hashed_pw);
            return AUTH_OK;
        }
        free (hashed_pw);
        DEBUG0 ("incorrect password for client");
        return AUTH_FAILED;
    }
    DEBUG1 ("no such username: %s", client->username);
    thread_rwlock_unlock (&htpasswd->file_rwlock);
    return AUTH_FAILED;
}
Exemplo n.º 4
0
/* Add YP entries to active servers */
void yp_add (const char *mount)
{
    struct yp_server *server;

    /* make sure YP thread is not modifying the lists */
    thread_rwlock_rlock (&yp_lock);

    /* make sure we don't race against another yp_add */
    thread_mutex_lock (&yp_pending_lock);
    server = (struct yp_server *)active_yps;
    while (server)
    {
        ypdata_t *yp;
        /* add new ypdata to each servers pending yp */
        if ((yp = create_yp_entry (mount)) != NULL)
        {
            DEBUG2 ("Adding %s to %s", mount, server->url);
            yp->server = server;
            yp->touch_interval = server->touch_interval;
            yp->next = server->pending_mounts;
            yp->next_update = time(NULL) + 5;
            server->pending_mounts = yp;
            yp_update = 1;
        }
        server = server->next;
    }
    thread_mutex_unlock (&yp_pending_lock);
    thread_rwlock_unlock (&yp_lock);
}
Exemplo n.º 5
0
/* Mark an existing entry in the YP list as to be marked for deletion */
void yp_remove (const char *mount)
{
    struct yp_server *server = (struct yp_server *)active_yps;

    thread_rwlock_rlock (&yp_lock);
    while (server)
    {
        ypdata_t *list = server->mounts;

        while (1)
        {
            ypdata_t *yp = find_yp_mount (list, mount);
            if (yp == NULL)
                break;
            if (yp->release || yp->remove)
            {
                list = yp->next;
                continue;   /* search again these are old entries */
            }
            DEBUG2 ("release %s on YP %s", mount, server->url);
            yp->release = 1;
            yp->next_update = 0;
            yp_update = 1;
        }
        server = server->next;
    }
    thread_rwlock_unlock (&yp_lock);
}
Exemplo n.º 6
0
/* This is similar to yp_remove, but we force a touch
 * attempt */
void yp_touch (const char *mount)
{
    struct yp_server *server = (struct yp_server *)active_yps;
    time_t trigger;
    ypdata_t *search_list = NULL;

    thread_rwlock_rlock (&yp_lock);
    /* do update in 3 secs, give stats chance to update */
    trigger = time(NULL) + 3;
    if (server)
        search_list = server->mounts;

    while (server)
    {
        ypdata_t *yp = find_yp_mount (search_list, mount);
        if (yp)
        {
            /* we may of found old entries not purged yet, so skip them */
            if (yp->release != 0 || yp->remove != 0)
            {
                search_list = yp->next;
                continue;
            }
            /* only force if touch */
            if (yp->process == do_yp_touch)
                yp->next_update = trigger;
        }
        server = server->next;
        if (server)
            search_list = server->mounts;
    }
    thread_rwlock_unlock (&yp_lock);
}
Exemplo n.º 7
0
/* This is similar to yp_remove, but we force a touch
 * attempt */
void yp_touch (const char *mount)
{
    struct yp_server *server = (struct yp_server *)active_yps;
    ypdata_t *search_list = NULL;

    thread_rwlock_rlock (&yp_lock);

    if (server)
        search_list = server->mounts;

    while (server)
    {
        ypdata_t *yp = find_yp_mount (search_list, mount);
        if (yp)
        {
            /* we may of found old entries not purged yet, so skip them */
            if (yp->release != 0 || yp->remove != 0)
            {
                search_list = yp->next;
                continue;
            }
            /* don't update the directory if there is a touch scheduled soon */
            if (yp->process == do_yp_touch && now + yp->touch_interval - yp->next_update > 60)
                yp_schedule (yp, 0);
        }
        server = server->next;
        if (server)
            search_list = server->mounts;
    }
    thread_rwlock_unlock (&yp_lock);
}
Exemplo n.º 8
0
Arquivo: yp.c Projeto: miksago/icecast
void yp_recheck_config (ice_config_t *config)
{
    int i;
    struct yp_server *server;

    DEBUG0("Updating YP configuration");
    thread_rwlock_rlock (&yp_lock);

    server = (struct yp_server *)active_yps;
    while (server)
    {
        server->remove = 1;
        server = server->next;
    }
    /* for each yp url in config, check to see if one exists 
       if not, then add it. */
    for (i=0 ; i < config->num_yp_directories; i++)
    {
        server = find_yp_server (config->yp_url[i]);
        if (server == NULL)
        {
            server = calloc (1, sizeof (struct yp_server));

            if (server == NULL)
            {
                destroy_yp_server (server);
                break;
            }
            server->url = strdup (config->yp_url[i]);
            server->url_timeout = config->yp_url_timeout[i];
            server->touch_interval = config->yp_touch_interval[i];
            server->curl = curl_easy_init();
            if (server->curl == NULL)
            {
                destroy_yp_server (server);
                break;
            }
            if (server->touch_interval < 30)
                server->touch_interval = 30;
            curl_easy_setopt (server->curl, CURLOPT_URL, server->url);
            curl_easy_setopt (server->curl, CURLOPT_HEADERFUNCTION, handle_returned_header);
            curl_easy_setopt (server->curl, CURLOPT_WRITEFUNCTION, handle_returned_data);
            curl_easy_setopt (server->curl, CURLOPT_WRITEDATA, server->curl);
            curl_easy_setopt (server->curl, CURLOPT_TIMEOUT, server->url_timeout);
            curl_easy_setopt (server->curl, CURLOPT_NOSIGNAL, 1L);
            curl_easy_setopt (server->curl, CURLOPT_ERRORBUFFER, &(server->curl_error[0]));
            server->next = (struct yp_server *)pending_yps;
            pending_yps = server;
            INFO3 ("Adding new YP server \"%s\" (timeout %ds, default interval %ds)",
                    server->url, server->url_timeout, server->touch_interval);
        }
        else
        {
            server->remove = 0;
        }
    }
    thread_rwlock_unlock (&yp_lock);
    yp_update = 1;
}
Exemplo n.º 9
0
/* Check for changes in the YP servers configured */
static void check_servers (void)
{
    struct yp_server *server = (struct yp_server *)active_yps,
                     **server_p = (struct yp_server **)&active_yps;

    while (server)
    {
        if (server->remove)
        {
            struct yp_server *to_go = server;
            DEBUG1 ("YP server \"%s\"removed", server->url);
            *server_p = server->next;
            server = server->next;
            destroy_yp_server (to_go);
            continue;
        }
        server_p = &server->next;
        server = server->next;
    }
    /* add new server entries */
    while (pending_yps)
    {
        avl_node *node;

        server = (struct yp_server *)pending_yps;
        pending_yps = server->next;

        DEBUG1("Add pending yps %s", server->url);
        server->next = (struct yp_server *)active_yps;
        active_yps = server;

        /* new YP server configured, need to populate with existing sources */
        avl_tree_rlock (global.source_tree);
        node = avl_get_first (global.source_tree);
        while (node)
        {
            ypdata_t *yp;

            source_t *source = node->key;
            thread_rwlock_rlock (&source->lock);
            if (source->yp_public && (yp = create_yp_entry (source->mount)) != NULL)
            {
                DEBUG1 ("Adding existing mount %s", source->mount);
                yp->server = server;
                yp->touch_interval = server->touch_interval;
                yp->next = server->mounts;
                server->mounts = yp;
            }
            thread_rwlock_unlock (&source->lock);
            node = avl_get_next (node);
        }
        avl_tree_unlock (global.source_tree);
    }
}
Exemplo n.º 10
0
static void *yp_update_thread(void *arg)
{
    if (!kitsune_is_updating()) { /**DSU control */
        INFO0("YP update thread started");
        yp_running = 1;
    }

    while (yp_running)
    {
      kitsune_update("yp_update"); /**DSU updatepoint */
        struct yp_server *server;

        thread_sleep (200000);

        /* do the YP communication */
        thread_rwlock_rlock (&yp_lock);
        server = (struct yp_server *)active_yps;
        while (server)
        {
            /* DEBUG1 ("trying %s", server->url); */
            yp_process_server (server);
            server = server->next;
        }
        thread_rwlock_unlock (&yp_lock);

        /* update the local YP structure */
        if (yp_update)
        {
            thread_rwlock_wlock (&yp_lock);
            check_servers ();
            server = (struct yp_server *)active_yps;
            while (server)
            {
                /* DEBUG1 ("Checking yps %s", server->url); */
                add_pending_yp (server);
                delete_marked_yp (server);
                server = server->next;
            }
            yp_update = 0;
            thread_rwlock_unlock (&yp_lock);
        }
    }
    thread_rwlock_destroy (&yp_lock);
    thread_mutex_destroy (&yp_pending_lock);
    /* free server and ypdata left */
    while (active_yps)
    {
        struct yp_server *server = (struct yp_server *)active_yps;
        active_yps = server->next;
        destroy_yp_server (server);
    }

    return NULL;
}
Exemplo n.º 11
0
/* Not efficient; opens and scans the entire file for every request */
static auth_result htpasswd_auth(auth_t *auth, source_t *source, char *username, char *password)
{
    htpasswd_auth_state *state = auth->state;
    FILE *passwdfile = NULL;
    char line[MAX_LINE_LEN];
    char *sep;

    thread_rwlock_rlock(&state->file_rwlock);
    if (!state->allow_duplicate_users) {
        if (auth_is_listener_connected(source, username)) {
            thread_rwlock_unlock(&state->file_rwlock);
            return AUTH_FORBIDDEN;
        }
    }
    passwdfile = fopen(state->filename, "rb");
    if(passwdfile == NULL) {
        WARN2("Failed to open authentication database \"%s\": %s", 
                state->filename, strerror(errno));
        thread_rwlock_unlock(&state->file_rwlock);
        return AUTH_FAILED;
    }

    while(get_line(passwdfile, line, MAX_LINE_LEN)) {
        if(!line[0] || line[0] == '#')
            continue;

        sep = strchr(line, ':');
        if(sep == NULL) {
            DEBUG0("No seperator in line");
            continue;
        }

        *sep = 0;
        if(!strcmp(username, line)) {
            /* Found our user, now: does the hash of password match hash? */
            char *hash = sep+1;
            char *hashed_password = get_hash(password, strlen(password));
            if(!strcmp(hash, hashed_password)) {
                fclose(passwdfile);
                free(hashed_password);
                thread_rwlock_unlock(&state->file_rwlock);
                return AUTH_OK;
            }
            free(hashed_password);
            /* We don't keep searching through the file */
            break; 
        }
    }

    fclose(passwdfile);

    thread_rwlock_unlock(&state->file_rwlock);
    return AUTH_FAILED;
}
Exemplo n.º 12
0
void client_add_incoming (client_t *client)
{
    worker_t *handler;

    thread_rwlock_rlock (&workers_lock);
    handler = worker_incoming;
    thread_spin_lock (&handler->lock);
    thread_rwlock_unlock (&workers_lock);

    worker_add_client (handler, client);
    thread_spin_unlock (&handler->lock);
    worker_wakeup (handler);
}
Exemplo n.º 13
0
void client_add_worker (client_t *client)
{
    worker_t *handler;

    thread_rwlock_rlock (&workers_lock);
    /* add client to the handler with the least number of clients */
    handler = worker_selected();
    thread_spin_lock (&handler->lock);
    thread_rwlock_unlock (&workers_lock);

    worker_add_client (handler, client);
    thread_spin_unlock (&handler->lock);
    worker_wakeup (handler);
}
Exemplo n.º 14
0
int auth_get_userlist(source_t *source, xmlNodePtr srcnode)
{
    int ret = 0;
    htpasswd_auth_state *state;

    if (source->authenticator) {
        if (!strcmp(source->authenticator->type, "htpasswd")) {
            state = source->authenticator->state;
            thread_rwlock_rlock(&state->file_rwlock);
            ret = auth_get_htpasswd_userlist(source->authenticator, srcnode);
            thread_rwlock_unlock(&state->file_rwlock);
        }
    }
    return ret;
}
Exemplo n.º 15
0
/* Mark an existing entry in the YP list as to be marked for deletion */
void yp_remove (const char *mount)
{
    struct yp_server *server = (struct yp_server *)active_yps;

    thread_rwlock_rlock (&yp_lock);
    while (server)
    {
        ypdata_t *yp = find_yp_mount (server->mounts, mount);
        if (yp)
        {
            DEBUG2 ("release %s on YP %s", mount, server->url);
            yp->release = 1;
            yp->next_update = 0;
        }
        server = server->next;
    }
    thread_rwlock_unlock (&yp_lock);
}
Exemplo n.º 16
0
static void *yp_update_thread(void *arg)
{
    struct yp_server *server;

    yp_thread = thread_self();
    /* DEBUG0("YP thread started"); */

    /* do the YP communication */
    thread_rwlock_rlock (&yp_lock);
    ypclient.counter = -1;
    server = (struct yp_server *)active_yps;
    while (server)
    {
        /* DEBUG1 ("trying %s", server->url); */
        yp_process_server (server);
        server = server->next;
    }
    thread_rwlock_unlock (&yp_lock);

    /* update the local YP structure */
    if (yp_update)
    {
        thread_rwlock_wlock (&yp_lock);
        check_servers ();
        server = (struct yp_server *)active_yps;
        while (server)
        {
            /* DEBUG1 ("Checking yps %s", server->url); */
            add_pending_yp (server);
            delete_marked_yp (server);
            server = server->next;
        }
        yp_update = 0;
        thread_rwlock_unlock (&yp_lock);
    }
    yp_thread = NULL;
    /* DEBUG0("YP thread shutdown"); */

    ypclient.flags |= CLIENT_ACTIVE;
    worker_wakeup (ypclient.worker);

    return NULL;
}
Exemplo n.º 17
0
/* The auth thread main loop. */
static void *auth_run_thread (void *arg)
{
    auth_thread_t *handler = arg;
    auth_t *auth = handler->auth;

    DEBUG2 ("Authentication thread %d started for %s", handler->id, auth->mount);
    thread_rwlock_rlock (&auth_lock);

    while (1)
    {
        thread_mutex_lock (&auth->lock);
        if (auth->head)
        {
            auth_client *auth_user = auth->head;

            DEBUG2 ("%d client(s) pending on %s", auth->pending_count, auth->mount);
            auth->head = auth_user->next;
            if (auth->head == NULL)
                auth->tailp = &auth->head;
            auth->pending_count--;
            thread_mutex_unlock (&auth->lock);
            auth_user->next = NULL;

            /* associate per-thread data with auth_user here */
            auth_user->thread_data = handler->data;
            auth_user->handler = handler->id;

            if (auth_user->process)
                auth_user->process (auth_user);

            auth_client_free (auth_user);

            continue;
        }
        handler->thread = NULL;
        break;
    }
    DEBUG1 ("Authenication thread %d shutting down", handler->id);
    auth_release (auth);
    thread_rwlock_unlock (&auth_lock);
    return NULL;
}
Exemplo n.º 18
0
// We pick a worker (consequetive) and set a max number of clients to move if needed
void worker_balance_trigger (time_t now)
{
    int log_counts = (now % 10) == 0 ? 1 : 0;

    if (worker_count == 1)
        return; // no balance required, leave quickly
    thread_rwlock_rlock (&workers_lock);

    // lets only search for this once a second, not many times
    worker_least_used = find_least_busy_handler (log_counts);
    if (worker_balance_to_check)
    {
        worker_balance_to_check->move_allocations = 50;
        worker_balance_to_check = worker_balance_to_check->next;
    }
    if (worker_balance_to_check == NULL)
        worker_balance_to_check = workers;

    thread_rwlock_unlock (&workers_lock);
}
Exemplo n.º 19
0
static int command_show_image (client_t *client, const char *mount)
{
    source_t *source;

    avl_tree_rlock (global.source_tree);
    source = source_find_mount_raw (mount);
    if (source && source->format && source->format->get_image)
    {
        thread_rwlock_rlock (&source->lock);
        avl_tree_unlock (global.source_tree);
        if (source->format->get_image (client, source->format) == 0)
        {
            thread_rwlock_unlock (&source->lock);
            return fserve_setup_client (client);
        }
        thread_rwlock_unlock (&source->lock);
    }
    else
        avl_tree_unlock (global.source_tree);
    return client_send_404 (client, "No image available");
}
Exemplo n.º 20
0
// We pick a worker (consequetive) and set a max number of clients to move if needed
void worker_balance_trigger (time_t now)
{

    thread_rwlock_rlock (&workers_lock);
    if (worker_count > 1)
    {
        int log_counts = (now & 15) == 0 ? 1 : 0;

        worker_least_used = find_least_busy_handler (log_counts);
        if (worker_balance_to_check)
        {
            worker_balance_to_check->move_allocations = 50;
            worker_balance_to_check = worker_balance_to_check->next;
        }
        if (worker_balance_to_check == NULL)
            worker_balance_to_check = workers;
    }
    if (worker_incoming)
        worker_incoming->move_allocations = 2000000; // enforce a move away from this thread if possible

    thread_rwlock_unlock (&workers_lock);
}
Exemplo n.º 21
0
/* Add YP entries to active servers */
void yp_add (const char *mount)
{
    struct yp_server *server;

    /* make sure YP thread is not modifying the lists */
    thread_rwlock_rlock (&yp_lock);

    /* make sure we don't race against another yp_add */
    thread_mutex_lock (&yp_pending_lock);
    server = (struct yp_server *)active_yps;
    while (server)
    {
        ypdata_t *yp;

        /* on-demand relays may already have a YP entry */
        yp = find_yp_mount (server->mounts, mount);
        if (yp == NULL)
        {
            /* add new ypdata to each servers pending yp */
            yp = create_yp_entry (mount);
            if (yp)
            {
                DEBUG2 ("Adding %s to %s", mount, server->url);
                yp->server = server;
                yp->touch_interval = server->touch_interval;
                yp->next = server->pending_mounts;
                yp->next_update = time(NULL) + 5;
                server->pending_mounts = yp;
                yp_update = 1;
            }
        }
        else
            DEBUG1 ("YP entry %s already exists", mount);
        server = server->next;
    }
    thread_mutex_unlock (&yp_pending_lock);
    thread_rwlock_unlock (&yp_lock);
}
Exemplo n.º 22
0
static int fserve_change_worker (client_t *client)
{
    worker_t *this_worker = client->worker, *worker;
    int ret = 0;

    if (this_worker->move_allocations == 0 || worker_count < 2)
        return 0;
    thread_rwlock_rlock (&workers_lock);
    worker = worker_selected ();
    if (worker && worker != client->worker)
    {
        long diff = this_worker->count - worker->count;
        if (diff > 15)
        {
            this_worker->move_allocations--;
            ret = client_change_worker (client, worker);
            if (ret)
                DEBUG2 ("moving listener from %p to %p", this_worker, worker);
        }
    }
    thread_rwlock_unlock (&workers_lock);
    return ret;
}
Exemplo n.º 23
0
static auth_result htpasswd_userlist(auth_t *auth, xmlNodePtr srcnode)
{
    htpasswd_auth_state *state;
    xmlNodePtr newnode;
    avl_node *node;

    state = auth->state;

    htpasswd_recheckfile (state);

    thread_rwlock_rlock (&state->file_rwlock);
    node = avl_get_first (state->users);
    while (node)
    {
        htpasswd_user *user = (htpasswd_user *)node->key;
        newnode = xmlNewChild (srcnode, NULL, "User", NULL);
        xmlNewChild(newnode, NULL, "username", user->name);
        xmlNewChild(newnode, NULL, "password", user->pass);
        node = avl_get_next (node);
    }
    thread_rwlock_unlock (&state->file_rwlock);

    return AUTH_OK;
}
Exemplo n.º 24
0
int xslt_transform (xmlDocPtr doc, const char *xslfilename, client_t *client)
{
    xmlDocPtr    res;
    xsltStylesheetPtr cur;
    int len, i;
    char **params = NULL;
    refbuf_t *content = NULL;

    client->shared_data = doc;
    thread_rwlock_rlock (&xslt_lock);
    i = xslt_cached (xslfilename, client);
    if (i < 0)
    {
        thread_rwlock_unlock (&xslt_lock);
        if (i == -2)
        {
            xmlFreeDoc (doc);
            client->shared_data = NULL;
            return client_send_404 (client, "Could not parse XSLT file");
        }
        return 0;
    }
    cur = cache[i].stylesheet;
    client->shared_data = NULL;
    if (client->parser->queryvars)
    {
        // annoying but we need to surround the args with ' when passing them in
        int i, arg_count = client->parser->queryvars->length * 2;
        avl_node *node = avl_get_first (client->parser->queryvars);

        params = calloc (arg_count+1, sizeof (char *));
        for (i = 0; node && i < arg_count; node = avl_get_next (node))
        {
            http_var_t *param = (http_var_t *)node->key;
            char *tmp = util_url_escape (param->value);
            params[i++] = param->name;
            // use alloca for now, should really url esc into a supplied buffer
            params[i] = (char*)alloca (strlen (tmp) + 3);
            sprintf (params[i++], "\'%s\'", tmp);
            free (tmp);
        }
        params[i] = NULL;
    }

    res = xsltApplyStylesheet (cur, doc, (const char **)params);
    free (params);

    if (res == NULL || xslt_SaveResultToBuf (&content, &len, res, cur) < 0)
    {
        thread_rwlock_unlock (&xslt_lock);
        xmlFreeDoc (res);
        xmlFreeDoc (doc);
        WARN1 ("problem applying stylesheet \"%s\"", xslfilename);
        return client_send_404 (client, "XSLT problem");
    }
    else
    {
        /* the 100 is to allow for the hardcoded headers */
        refbuf_t *refbuf = refbuf_new (200);
        const char *mediatype = NULL;

        /* lets find out the content type to use */
        if (cur->mediaType)
            mediatype = (char *)cur->mediaType;
        else
        {
            /* check method for the default, a missing method assumes xml */
            if (cur->method && xmlStrcmp (cur->method, XMLSTR("html")) == 0)
                mediatype = "text/html";
            else
                if (cur->method && xmlStrcmp (cur->method, XMLSTR("text")) == 0)
                    mediatype = "text/plain";
                else
                    mediatype = "text/xml";
        }
        snprintf (refbuf->data, 200,
                "HTTP/1.0 200 OK\r\nContent-Type: %s\r\nContent-Length: %d\r\n"
                "Expires: Thu, 19 Nov 1981 08:52:00 GMT\r\n"
                "Cache-Control: no-store, no-cache, must-revalidate\r\n"
                "Pragma: no-cache\r\n"
                "\r\n",
                mediatype, len);

        thread_rwlock_unlock (&xslt_lock);
        client->respcode = 200;
        client_set_queue (client, NULL);
        client->refbuf = refbuf;
        refbuf->len = strlen (refbuf->data);
        refbuf->next = content;
    }
    xmlFreeDoc(res);
    xmlFreeDoc(doc);
    return fserve_setup_client (client);
}
Exemplo n.º 25
0
ice_config_t *config_get_config(void)
{
    thread_rwlock_rlock(&(_locks.config_lock));
    return &_current_configuration;
}
Exemplo n.º 26
0
Arquivo: avl.c Projeto: gleriston/idjc
void avl_tree_rlock(avl_tree *tree)
{
    thread_rwlock_rlock(&tree->rwlock);
}
Exemplo n.º 27
0
int redirect_client (const char *mountpoint, client_t *client)
{
    int ret = 0, which;
    redirect_host *checking, **trail;

    thread_rwlock_rlock (&slaves_lock);
    /* select slave entry */
    if (global.redirect_count == 0)
    {
        thread_rwlock_unlock (&slaves_lock);
        return 0;
    }
    which=(int) (((float)global.redirect_count)*rand()/(RAND_MAX+1.0)) + 1;
    checking = redirectors;
    trail = &redirectors;

    DEBUG2 ("random selection %d (out of %d)", which, global.redirect_count);
    while (checking)
    {
        DEBUG2 ("...%s:%d", checking->server, checking->port);
        if (checking->next_update && checking->next_update+10 < time(NULL))
        {
            /* no streamist request, expire slave for now */
            *trail = checking->next;
            global.redirect_count--;
            /* free slave details */
            INFO2 ("dropping redirector for %s:%d", checking->server, checking->port);
            free (checking->server);
            free (checking);
            checking = *trail;
            if (which > 0)
                which--; /* we are 1 less now */
            continue;
        }
        if (--which == 0)
        {
            char *location;
            /* add enough for "http://" the port ':' and nul */
            int len = strlen (mountpoint) + strlen (checking->server) + 15;
            const char *user = client->username;
            const char *pass = client->password;
            const char *args = httpp_getvar (client->parser, HTTPP_VAR_QUERYARGS);
            const char *colon = ":", *at_sign = "@";

            if (args)
                len += strlen (args);
            else
                args = "";
            if (user && pass)
                len += strlen (user) + strlen (pass);
            else
                colon = at_sign = user = pass = "";
            INFO2 ("redirecting listener to slave server at %s:%d", checking->server, checking->port);
            location = alloca (len);
            snprintf (location, len, "http://%s%s%s%s%s:%d%s%s",
                    user, colon, pass, at_sign,
                    checking->server, checking->port, mountpoint, args);
            client_send_302 (client, location);
            ret = 1;
        }
        trail = &checking->next;
        checking = checking->next;
    }
    thread_rwlock_unlock (&slaves_lock);
    return ret;
}
Exemplo n.º 28
0
void avl_node_rlock(avl_node *node)
{
    thread_rwlock_rlock(&node->rwlock);
}
Exemplo n.º 29
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, int show_listeners)
{
    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_rwlock_rlock (&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));
                if (show_listeners)
                    admin_source_listeners (source, srcnode);
            }
        }
        thread_rwlock_unlock (&source->lock);
        node = avl_get_next(node);
    }
    return(doc);
}
Exemplo n.º 30
0
/* Perform any initialisation just before the stream data is processed, the header
 * info is processed by now and the format details are setup
 */
static void source_init (source_t *source)
{
    ice_config_t *config = config_get_config();
    char *listenurl;
    const char *str;
    int listen_url_size;
    mount_proxy *mountinfo;

    /* 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%s",
            config->hostname, source->mount);
    config_release_config();

    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);

    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, "source_total_connections");
    stats_event (source->mount, "slow_listeners", "0");
    stats_event_args (source->mount, "listeners", "%lu", source->listeners);
    stats_event_args (source->mount, "listener_peak", "%lu", source->peak_listeners);
    stats_event_time (source->mount, "stream_start");

    DEBUG0("Source creation complete");
    source->last_read = time (NULL);
    source->prev_listeners = -1;
    source->running = 1;

    mountinfo = config_find_mount (config_get_config(), source->mount);
    if (mountinfo)
    {
        if (mountinfo->on_connect)
            source_run_script (mountinfo->on_connect, source->mount);
        auth_stream_start (mountinfo, source->mount);
    }
    config_release_config();

    /*
    ** 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);
    }
}