int admin_mount_request (client_t *client, const char *uri) { source_t *source; const char *mount = httpp_get_query_param (client->parser, "mount"); struct admin_command *cmd = find_admin_command (admin_mount, uri); if (cmd == NULL) return command_stats (client, uri); if (cmd == NULL || cmd->handle.source == NULL) { INFO0("mount request not recognised"); return client_send_400 (client, "unknown request"); } avl_tree_rlock(global.source_tree); source = source_find_mount_raw(mount); if (source == NULL) { avl_tree_unlock(global.source_tree); if (strncmp (cmd->request, "stats", 5) == 0) return command_stats (client, uri); if (strncmp (cmd->request, "listclients", 11) == 0) return fserve_list_clients (client, mount, cmd->response, 1); if (strncmp (cmd->request, "killclient", 10) == 0) return fserve_kill_client (client, mount, cmd->response); WARN1("Admin command on non-existent source %s", mount); return client_send_400 (client, "Source does not exist"); } else { int ret = 0; thread_mutex_lock (&source->lock); if (source_available (source) == 0) { thread_mutex_unlock (&source->lock); avl_tree_unlock (global.source_tree); INFO1("Received admin command on unavailable mount \"%s\"", mount); return client_send_400 (client, "Source is not available"); } ret = cmd->handle.source (client, source, cmd->response); avl_tree_unlock(global.source_tree); return ret; } }
int move_listener (client_t *client, struct _fbinfo *finfo) { source_t *source; mount_proxy *minfo; int rate = finfo->limit, loop = 20, ret = -1; ice_config_t *config = config_get_config(); struct _fbinfo where; unsigned int len = 4096; char buffer [len]; memcpy (&where, finfo, sizeof (where)); if (finfo->fallback) where.fallback = strdup (finfo->fallback); avl_tree_rlock (global.source_tree); do { len = sizeof buffer; util_expand_pattern (where.fallback, where.mount, buffer, &len); where.mount = buffer; minfo = config_find_mount (config, where.mount); if (rate == 0 && minfo && minfo->limit_rate) rate = minfo->limit_rate; source = source_find_mount_raw (where.mount); if (source == NULL && minfo == NULL) break; if (source) { thread_rwlock_wlock (&source->lock); if (source_available (source)) { // an unused on-demand relay will still have an unitialised type if (source->format->type == finfo->type || source->format->type == FORMAT_TYPE_UNDEFINED) { config_release_config(); avl_tree_unlock (global.source_tree); source_setup_listener (source, client); source->listeners++; client->flags |= CLIENT_HAS_MOVED; thread_rwlock_unlock (&source->lock); free (where.fallback); return 0; } } thread_rwlock_unlock (&source->lock); } if (minfo && minfo->fallback_mount) { free (where.fallback); where.fallback = strdup (where.mount); where.mount = minfo->fallback_mount; } else break; } while (loop--); avl_tree_unlock (global.source_tree); config_release_config(); if (where.mount && ((client->flags & CLIENT_IS_SLAVE) == 0)) { if (where.limit == 0) { if (rate == 0) if (sscanf (where.mount, "%*[^[][%d]", &rate) == 1) rate = rate * 1000/8; where.limit = rate; } client->intro_offset = 0; ret = fserve_setup_client_fb (client, &where); } free (where.fallback); return ret; }
/* build an XML doc containing information about currently running sources. * If a mountpoint is passed then that source will not be added to the XML * doc even if the source is running */ xmlDocPtr admin_build_sourcelist (const char *mount) { avl_node *node; source_t *source; xmlNodePtr xmlnode, srcnode; xmlDocPtr doc; char buf[22]; time_t now = time(NULL); doc = xmlNewDoc(XMLSTR("1.0")); xmlnode = xmlNewDocNode(doc, NULL, XMLSTR("icestats"), NULL); xmlDocSetRootElement(doc, xmlnode); if (mount) { xmlNewChild(xmlnode, NULL, XMLSTR("current_source"), XMLSTR(mount)); } node = avl_get_first(global.source_tree); while(node) { source = (source_t *)node->key; if (mount && strcmp (mount, source->mount) == 0) { node = avl_get_next (node); continue; } thread_mutex_lock (&source->lock); if (source_available (source)) { ice_config_t *config; mount_proxy *mountinfo; srcnode = xmlNewChild (xmlnode, NULL, XMLSTR("source"), NULL); xmlSetProp (srcnode, XMLSTR("mount"), XMLSTR(source->mount)); snprintf (buf, sizeof(buf), "%lu", source->listeners); xmlNewChild (srcnode, NULL, XMLSTR("listeners"), XMLSTR(buf)); config = config_get_config(); mountinfo = config_find_mount (config, source->mount); if (mountinfo) { if (mountinfo->auth) { xmlNewChild (srcnode, NULL, XMLSTR("authenticator"), XMLSTR(mountinfo->auth->type)); } if (mountinfo->fallback_mount) xmlNewChild (srcnode, NULL, XMLSTR("fallback"), XMLSTR(mountinfo->fallback_mount)); } config_release_config(); if (source_running (source)) { if (source->client) { snprintf (buf, sizeof(buf), "%lu", (unsigned long)(now - source->client->connection.con_time)); xmlNewChild (srcnode, NULL, XMLSTR("Connected"), XMLSTR(buf)); } xmlNewChild (srcnode, NULL, XMLSTR("content-type"), XMLSTR(source->format->contenttype)); } } thread_mutex_unlock (&source->lock); node = avl_get_next(node); } return(doc); }