Exemple #1
0
static void worker_start (void)
{
    worker_t *handler = calloc (1, sizeof(worker_t));

    worker_control_create (&handler->wakeup_fd[0]);

    handler->pending_clients_tail = &handler->pending_clients;
    thread_spin_create (&handler->lock);
    handler->last_p = &handler->clients;

    thread_rwlock_wlock (&workers_lock);
    if (worker_incoming == NULL)
    {
        worker_incoming = handler;
        handler->thread = thread_create ("worker", worker, handler, THREAD_ATTACHED);
        thread_rwlock_unlock (&workers_lock);
        INFO0 ("starting incoming worker thread");
        worker_start();  // single level recursion, just get a special worker thread set up
        return;
    }
    handler->next = workers;
    workers = handler;
    worker_count++;
    worker_least_used = worker_balance_to_check = workers;
    thread_rwlock_unlock (&workers_lock);

    handler->thread = thread_create ("worker", worker, handler, THREAD_ATTACHED);
}
Exemple #2
0
static int command_move_clients (client_t *client, source_t *source, int response)
{
    const char *dest_source;
    xmlDocPtr doc;
    xmlNodePtr node;
    int parameters_passed = 0;
    char buf[255];

    if((COMMAND_OPTIONAL(client, "destination", dest_source))) {
        parameters_passed = 1;
    }
    if (!parameters_passed) {
        doc = admin_build_sourcelist(source->mount, 0);
        thread_rwlock_unlock (&source->lock);
        return admin_send_response(doc, client, response, "moveclients.xsl");
    }
    INFO2 ("source is \"%s\", destination is \"%s\"", source->mount, dest_source);

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

    source_set_fallback (source, dest_source);
    source->termination_count = source->listeners;
    source->flags |= SOURCE_LISTENERS_SYNC;

    snprintf (buf, sizeof(buf), "Clients moved from %s to %s",
            source->mount, dest_source);
    thread_rwlock_unlock (&source->lock);
    xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
    xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));

    return admin_send_response (doc, client, response, "response.xsl");
}
Exemple #3
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;
}
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;
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
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);
}
Exemple #8
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;
}
Exemple #9
0
static void worker_stop (void)
{
    worker_t *handler;

    if (workers == NULL)
        return;
    thread_rwlock_wlock (&workers_lock);
    handler = workers;
    workers = handler->next;
    worker_least_used = worker_balance_to_check = workers;
    if (workers)
        workers->move_allocations = 100;
    worker_count--;
    thread_rwlock_unlock (&workers_lock);

    handler->running = 0;
    worker_wakeup (handler);

    thread_join (handler->thread);
    thread_spin_destroy (&handler->lock);

    sock_close (handler->wakeup_fd[1]);
    sock_close (handler->wakeup_fd[0]);
    free (handler);
}
Exemple #10
0
void connection_accept_loop(void)
{
    connection_t *con;

    _build_pool();

    while (global.running == ICE_RUNNING)
    {
        if (global . schedule_config_reread)
        {
            /* reread config file */
            INFO0("Scheduling config reread ...");

            connection_inject_event(EVENT_CONFIG_READ, NULL);
            global . schedule_config_reread = 0;
        }

        con = _accept_connection();

        if (con) {
            _add_connection(con);
        }
    }

    /* Give all the other threads notification to shut down */
    thread_cond_broadcast(&global.shutdown_cond);

    _destroy_pool();

    /* wait for all the sources to shutdown */
    thread_rwlock_wlock(&_source_shutdown_rwlock);
    thread_rwlock_unlock(&_source_shutdown_rwlock);
}
Exemple #11
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);
}
Exemple #12
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);
}
Exemple #13
0
static int command_fallback (client_t *client, source_t *source, int response)
{
    char *mount = strdup (source->mount);
    mount_proxy *mountinfo;
    ice_config_t *config;

    thread_rwlock_unlock (&source->lock);
    DEBUG0("Got fallback request");
    config = config_grab_config();
    mountinfo = config_find_mount (config, mount);
    free (mount);
    if (mountinfo)
    {
        const char *fallback;
        char buffer[200];
        if (COMMAND_REQUIRE(client, "fallback", fallback) < 0)
            return client_send_400 (client, "missing arg, fallback");

        xmlFree (mountinfo->fallback_mount);
        mountinfo->fallback_mount = (char *)xmlCharStrdup (fallback);
        snprintf (buffer, sizeof (buffer), "Fallback for \"%s\" configured", mountinfo->mountname);
        config_release_config ();
        return html_success (client, buffer);
    }
    config_release_config ();
    return client_send_400 (client, "no mount details available");
}
Exemple #14
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);
}
Exemple #15
0
static int command_show_listeners (client_t *client, source_t *source, int response)
{
    xmlDocPtr doc;
    xmlNodePtr node, srcnode;
    uint64_t id = -1;
    const char *ID_str = NULL;
    char buf[22];

    doc = xmlNewDoc(XMLSTR("1.0"));
    node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
    srcnode = xmlNewChild(node, NULL, XMLSTR("source"), NULL);

    xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
    xmlDocSetRootElement(doc, node);

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

    COMMAND_OPTIONAL(client, "id", ID_str);
    if (ID_str)
        sscanf (ID_str, "%" SCNu64, &id);

    if (id == -1)
        admin_source_listeners (source, srcnode);
    else
    {
        client_t *listener = source_find_client (source, id);

        if (listener)
            stats_listener_to_xml (listener, srcnode);
    }
    thread_rwlock_unlock (&source->lock);

    return admin_send_response (doc, client, response, "listclients.xsl");
}
Exemple #16
0
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;
}
Exemple #17
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;
}
Exemple #18
0
void auth_shutdown (void)
{
    if (allow_auth == 0)
        return;
    allow_auth = 0;
    thread_rwlock_wlock (&auth_lock);
    thread_rwlock_unlock (&auth_lock);
    thread_rwlock_destroy (&auth_lock);
    INFO0 ("Auth shutdown complete");
}
Exemple #19
0
int main(void)
{
	int rv;
	thread_rwlock_t *thread_rwlock = NULL;
	rv = thread_rwlock_create(&thread_rwlock);
	rv = thread_rwlock_wrlock(thread_rwlock);
	rv = thread_rwlock_unlock(thread_rwlock);
	thread_rwlock_destroy(thread_rwlock);
	return 0;
}
Exemple #20
0
static int command_kill_client (client_t *client, source_t *source, int response)
{
    const char *idtext;
    uint64_t id;
    client_t *listener;
    xmlDocPtr doc;
    xmlNodePtr node;
    char buf[50] = "";

    if (COMMAND_REQUIRE(client, "id", idtext) < 0)
    {
        thread_rwlock_unlock (&source->lock);
        return client_send_400 (client, "missing arg, id");
    }

    sscanf (idtext, "%" SCNu64, &id);

    listener = source_find_client(source, id);

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

    if(listener != NULL) {
        INFO1("Admin request: client %d removed", id);

        /* This tags it for removal on the next iteration of the main source
         * loop
         */
        listener->connection.error = 1;
        snprintf(buf, sizeof(buf), "Client %" PRIu64 " removed", id);
        xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
        xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("1"));
    }
    else {
        snprintf(buf, sizeof(buf), "Client %" PRIu64 " not found", id);
        xmlNewChild(node, NULL, XMLSTR("message"), XMLSTR(buf));
        xmlNewChild(node, NULL, XMLSTR("return"), XMLSTR("0"));
    }
    thread_rwlock_unlock (&source->lock);
    return admin_send_response (doc, client, response, "response.xsl");
}
Exemple #21
0
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
{
    if (rwlock == NULL)
        return_errno(EINVAL, EINVAL);
    if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
        if (pthread_rwlock_init(rwlock, NULL) != OK)
            return errno;
    if (!thread_rwlock_unlock((rwlock_t *)(*rwlock)))
        return errno;
    return OK;
}
Exemple #22
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);
    }
}
Exemple #23
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");
}
Exemple #24
0
static int command_shoutcast_metadata (client_t *client, source_t *source)
{
    const char *action;
    const char *value;
    int same_ip = 1;

    if (COMMAND_REQUIRE(client, "mode", action) < 0)
    {
        thread_rwlock_unlock (&source->lock);
        return client_send_400 (client, "missing arg, mode");
    }

    if ((source->flags & SOURCE_SHOUTCAST_COMPAT) == 0)
    {
        thread_rwlock_unlock (&source->lock);
        ERROR0 ("illegal request on non-shoutcast compatible stream");
        return client_send_400 (client, "Not a shoutcast compatible stream");
    }

    if (strcmp (action, "updinfo") == 0)
    {
        DEBUG0("Got shoutcast metadata update request");
        if (COMMAND_REQUIRE (client, "song", value) < 0)
        {
            thread_rwlock_unlock (&source->lock);
            return client_send_400 (client, "missing arg, song");
        }
        if (source->client && strcmp (client->connection.ip, source->client->connection.ip) != 0)
            if (connection_check_admin_pass (client->parser) == 0)
                same_ip = 0;

        if (same_ip && source->format && source->format->set_tag)
        {
            httpp_set_query_param (client->parser, "mount", client->server_conn->shoutcast_mount);
            source->format->set_tag (source->format, "title", value, NULL);
            source->format->set_tag (source->format, NULL, NULL, NULL);

            DEBUG2("Metadata on mountpoint %s changed to \"%s\"", source->mount, value);
            thread_rwlock_unlock (&source->lock);
            return html_success(client, "Metadata update successful");
        }
        thread_rwlock_unlock (&source->lock);
        return client_send_400 (client, "mountpoint will not accept URL updates");
    }
    if (strcmp (action, "viewxml") == 0)
    {
        xmlDocPtr doc;
        DEBUG0("Got shoutcast viewxml request");
        thread_rwlock_unlock (&source->lock);
        doc = stats_get_xml (STATS_ALL, source->mount);
        return admin_send_response (doc, client, XSLT, "viewxml.xsl");
    }
    thread_rwlock_unlock (&source->lock);
    return client_send_400 (client, "No such action");
}
static auth_result htpasswd_adduser (auth_t *auth, const char *username, const char *password)
{
    FILE *passwdfile;
    char *hashed_password = NULL;
    htpasswd_auth_state *state = auth->state;
    htpasswd_user entry;
    void *result;

    htpasswd_recheckfile (state);

    thread_rwlock_wlock (&state->file_rwlock);

    entry.name = (char*)username;
    if (avl_get_by_key (state->users, &entry, &result) == 0)
    {
        thread_rwlock_unlock (&state->file_rwlock);
        return AUTH_USEREXISTS;
    }

    passwdfile = fopen(state->filename, "ab");

    if (passwdfile == NULL)
    {
        thread_rwlock_unlock (&state->file_rwlock);
        WARN2("Failed to open authentication database \"%s\": %s", 
                state->filename, strerror(errno));
        return AUTH_FAILED;
    }

    hashed_password = get_hash(password, strlen(password));
    if (hashed_password) {
        fprintf(passwdfile, "%s:%s\n", username, hashed_password);
        free(hashed_password);
    }

    fclose(passwdfile);
    thread_rwlock_unlock (&state->file_rwlock);

    return AUTH_USERADDED;
}
Exemple #26
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);
}
Exemple #27
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);
}
Exemple #28
0
static int command_updatemetadata(client_t *client, source_t *source, int response)
{
    xmlDocPtr doc;
    xmlNodePtr node, srcnode;

    thread_rwlock_unlock (&source->lock);
    doc = xmlNewDoc(XMLSTR("1.0"));
    node = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL);
    srcnode = xmlNewChild(node, NULL, XMLSTR("source"), NULL);
    xmlSetProp(srcnode, XMLSTR("mount"), XMLSTR(source->mount));
    xmlDocSetRootElement(doc, node);

    return admin_send_response (doc, client, response, "updatemetadata.xsl");
}
Exemple #29
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;
}
Exemple #30
0
int auth_deleteuser(source_t *source, char *username)
{
    htpasswd_auth_state *state;

    int ret = 0;
    if (source->authenticator) {
        if (!strcmp(source->authenticator->type, "htpasswd")) {
            state = source->authenticator->state;
            thread_rwlock_wlock(&state->file_rwlock);
            ret = auth_htpasswd_deleteuser(source->authenticator, username);
            thread_rwlock_unlock(&state->file_rwlock);
        }
    }
    return ret;
}