From 83f365029a2776379b13122cb05d3f90996ceb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Tue, 19 Jan 2010 20:19:20 +0000 Subject: [PATCH] Initial stab at a statedump feature via the HTTP server. Access via http://host:9981/state --- Makefile | 1 + src/trap.c | 4 + src/webui/statedump.c | 187 ++++++++++++++++++++++++++++++++++++++++++ src/webui/webui.c | 5 +- 4 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 src/webui/statedump.c diff --git a/Makefile b/Makefile index d4f41566..549b0235 100644 --- a/Makefile +++ b/Makefile @@ -111,6 +111,7 @@ SRCS += src/webui/webui.c \ src/webui/comet.c \ src/webui/extjs.c \ src/webui/simpleui.c \ + src/webui/statedump.c \ # # Extra modules diff --git a/src/trap.c b/src/trap.c index fb651569..5c1d2654 100644 --- a/src/trap.c +++ b/src/trap.c @@ -18,6 +18,8 @@ #include "trap.h" +char tvh_binshasum[20]; + #if defined(__i386__) || defined(__x86_64__) // Only do this on x86 for now @@ -176,6 +178,8 @@ trap_init(const char *ver) digest[18], digest[19]); + memcpy(tvh_binshasum, digest, 20); + free(binsum); } diff --git a/src/webui/statedump.c b/src/webui/statedump.c new file mode 100644 index 00000000..947a278f --- /dev/null +++ b/src/webui/statedump.c @@ -0,0 +1,187 @@ +/* + * Tvheadend, Statedump + * Copyright (C) 2010 Andreas Ă–man + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "tvhead.h" +#include "http.h" +#include "webui.h" +#include "access.h" +#include "epg.h" +#include "dvr/dvr.h" +#include "xmltv.h" +#include "dvb/dvb.h" +#include "dvb/dvb_support.h" +#include "transports.h" + +extern char tvh_binshasum[20]; +extern char *htsversion_full; + +int page_statedump(http_connection_t *hc, const char *remain, void *opaque); + +static void +outputtitle(htsbuf_queue_t *hq, int indent, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + + htsbuf_qprintf(hq, "\n%*.s", indent, ""); + + htsbuf_vqprintf(hq, fmt, ap); + va_end(ap); + htsbuf_qprintf(hq, "\n%*.s----------------------------------------------\n", + indent, ""); +} + + +static void +dumpchannels(htsbuf_queue_t *hq) +{ + channel_t *ch; + outputtitle(hq, 0, "Channels"); + + RB_FOREACH(ch, &channel_name_tree, ch_name_link) { + + htsbuf_qprintf(hq, "%s (%d)\n", ch->ch_name, ch->ch_id); + htsbuf_qprintf(hq, + " refcount = %d\n" + " zombie = %d\n" + " number = %d\n" + " xmltv source = %s\n" + " icon = %s\n\n", + ch->ch_refcount, + ch->ch_zombie, + ch->ch_number, + ch->ch_xc ? ch->ch_xc->xc_displayname : "", + ch->ch_icon ?: ""); + } +} + +static void +dumptransports(htsbuf_queue_t *hq, struct th_transport_list *l, int indent) +{ + th_transport_t *t; + th_stream_t *st; + + outputtitle(hq, indent, "Transports (or services)"); + LIST_FOREACH(t, l, tht_group_link) { + + htsbuf_qprintf(hq, "%*.s%s (%s)\n", indent + 2, "", + transport_nicename(t), t->tht_identifier); + + + htsbuf_qprintf(hq, "%*.s%-16s %-5s %-5s %-5s %-5s %-10s\n", indent + 4, "", + "Type", + "Index", + "Pid", + "Lang", + "CAID", + "ProviderID"); + + htsbuf_qprintf(hq, "%*.s-------------------------------------------\n", + indent + 4, ""); + + LIST_FOREACH(st, &t->tht_components, st_link) { + htsbuf_qprintf(hq, "%*.s%-16s %-5d %-5d %-5s %04x %08x\n", indent + 4, "", + streaming_component_type2txt(st->st_type), + st->st_index, + st->st_pid, + st->st_lang[0] ? st->st_lang : "", + st->st_caid, + st->st_providerid); + } + + htsbuf_qprintf(hq, "\n"); + + } +} + + + +static void +dumpdvbadapters(htsbuf_queue_t *hq) +{ + th_dvb_adapter_t *tda; + th_dvb_mux_instance_t *tdmi; + + outputtitle(hq, 0, "DVB Adapters"); + + TAILQ_FOREACH(tda, &dvb_adapters, tda_global_link) { + htsbuf_qprintf(hq, "%s (%s)\n", tda->tda_displayname, tda->tda_identifier); + + outputtitle(hq, 4, "Multiplexes"); + LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) { + char tdminame[64]; + dvb_mux_nicename(tdminame, sizeof(tdminame), tdmi); + htsbuf_qprintf(hq, " %s (%s)\n", + tdminame, tdmi->tdmi_identifier); + + htsbuf_qprintf(hq, "\n"); + dumptransports(hq, &tdmi->tdmi_transports, 8); + } + } +} + + +int +page_statedump(http_connection_t *hc, const char *remain, void *opaque) +{ + htsbuf_queue_t *hq = &hc->hc_reply; + + scopedgloballock(); + + + htsbuf_qprintf(hq, "Tvheadend %s Binary SHA1: " + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + htsversion_full, + tvh_binshasum[0], + tvh_binshasum[1], + tvh_binshasum[2], + tvh_binshasum[3], + tvh_binshasum[4], + tvh_binshasum[5], + tvh_binshasum[6], + tvh_binshasum[7], + tvh_binshasum[8], + tvh_binshasum[9], + tvh_binshasum[10], + tvh_binshasum[11], + tvh_binshasum[12], + tvh_binshasum[13], + tvh_binshasum[14], + tvh_binshasum[15], + tvh_binshasum[16], + tvh_binshasum[17], + tvh_binshasum[18], + tvh_binshasum[19]); + + dumpchannels(hq); + + dumpdvbadapters(hq); + + + http_output_content(hc, "text/plain; charset=UTF-8"); + return 0; +} + diff --git a/src/webui/webui.c b/src/webui/webui.c index 572d94fb..4458a489 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -297,7 +297,7 @@ favicon(http_connection_t *hc, const char *remain, void *opaque) return 0; } - +int page_statedump(http_connection_t *hc, const char *remain, void *opaque); /** * WEB user interface @@ -311,6 +311,9 @@ webui_init(const char *contentpath) http_path_add("/favicon.ico", NULL, favicon, ACCESS_WEB_INTERFACE); http_path_add("/channels.pls", NULL, page_rtsp_playlist, ACCESS_WEB_INTERFACE); + http_path_add("/state", NULL, page_statedump, ACCESS_ADMIN); + + webui_static_content(contentpath, "/static", "src/webui/static"); webui_static_content(contentpath, "/docs", "docs/html"); webui_static_content(contentpath, "/docresources", "docs/docresources");