|
23 | 23 | #include <libxml/xmlmemory.h> |
24 | 24 | #include <libxml/parser.h> |
25 | 25 | #include <libxml/tree.h> |
| 26 | +#include <libxml/xmlversion.h> |
| 27 | + |
| 28 | +#ifdef HAVE_UNISTD_H |
| 29 | +# include <unistd.h> |
| 30 | +#endif |
26 | 31 |
|
27 | 32 | #if HAVE_GETRLIMIT && HAVE_SYS_RESOURCE_H |
28 | 33 | #include <sys/resource.h> |
29 | 34 | #endif |
30 | 35 |
|
| 36 | +#ifdef HAVE_OPENSSL |
| 37 | +#include <openssl/opensslv.h> |
| 38 | +#endif |
| 39 | + |
| 40 | +#include <vorbis/codec.h> |
| 41 | + |
| 42 | +#ifdef HAVE_THEORA |
| 43 | +#include <theora/theora.h> |
| 44 | +#endif |
| 45 | + |
| 46 | +#ifdef HAVE_SPEEX |
| 47 | +#include <speex/speex.h> |
| 48 | +#endif |
| 49 | + |
| 50 | +#ifdef HAVE_CURL |
| 51 | +#include <curl/curlver.h> |
| 52 | +#include <curl/curl.h> |
| 53 | +#endif |
| 54 | + |
| 55 | +#ifdef HAVE_UNAME |
| 56 | +#include <sys/utsname.h> |
| 57 | +#endif |
| 58 | + |
31 | 59 | #include "common/net/sock.h" |
32 | 60 |
|
33 | 61 | #include "admin.h" |
|
125 | 153 | #define DASHBOARD_RAW_REQUEST "dashboard" |
126 | 154 | #define DASHBOARD_HTML_REQUEST "dashboard.xsl" |
127 | 155 | #define DASHBOARD_JSON_REQUEST "dashboard.json" |
| 156 | +#define VERSION_RAW_REQUEST "version" |
| 157 | +#define VERSION_HTML_REQUEST "version.xsl" |
128 | 158 | #define DEFAULT_RAW_REQUEST "" |
129 | 159 | #define DEFAULT_HTML_REQUEST "" |
130 | 160 | #define BUILDM3U_RAW_REQUEST "buildm3u" |
@@ -160,6 +190,7 @@ static void command_buildm3u (client_t *client, source_t *source, adm |
160 | 190 | static void command_show_log (client_t *client, source_t *source, admin_format_t response); |
161 | 191 | static void command_mark_log (client_t *client, source_t *source, admin_format_t response); |
162 | 192 | static void command_dashboard (client_t *client, source_t *source, admin_format_t response); |
| 193 | +static void command_version (client_t *client, source_t *source, admin_format_t response); |
163 | 194 |
|
164 | 195 | static const admin_command_handler_t handlers[] = { |
165 | 196 | { "*", ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_UNSAFE, NULL, NULL}, /* for ACL framework */ |
@@ -216,6 +247,8 @@ static const admin_command_handler_t handlers[] = { |
216 | 247 | { DASHBOARD_RAW_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_RAW, ADMINSAFE_SAFE, command_dashboard, NULL}, |
217 | 248 | { DASHBOARD_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_dashboard, NULL}, |
218 | 249 | { DASHBOARD_JSON_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_JSON, ADMINSAFE_SAFE, command_dashboard, NULL}, |
| 250 | + { VERSION_RAW_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_RAW, ADMINSAFE_SAFE, command_version, NULL}, |
| 251 | + { VERSION_HTML_REQUEST, ADMINTYPE_GENERAL, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_version, NULL}, |
219 | 252 | { DEFAULT_HTML_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_default_selector, NULL}, |
220 | 253 | { DEFAULT_RAW_REQUEST, ADMINTYPE_HYBRID, ADMIN_FORMAT_HTML, ADMINSAFE_SAFE, command_default_selector, NULL} |
221 | 254 | }; |
@@ -1726,6 +1759,174 @@ static void command_dashboard (client_t *client, source_t *source, adm |
1726 | 1759 | refobject_unref(report); |
1727 | 1760 | } |
1728 | 1761 |
|
| 1762 | +#ifdef HAVE_SPEEX |
| 1763 | +static inline const char *get_speex_version(void) |
| 1764 | +{ |
| 1765 | + const char *version; |
| 1766 | + if (speex_lib_ctl(SPEEX_LIB_GET_VERSION_STRING, &version) != 0) |
| 1767 | + return NULL; |
| 1768 | + return version; |
| 1769 | +} |
| 1770 | +#endif |
| 1771 | + |
| 1772 | +static void command_version (client_t *client, source_t *source, admin_format_t response) |
| 1773 | +{ |
| 1774 | + reportxml_t *report = client_get_reportxml("8cdfc150-094d-42f7-9c61-f9fb9a6e07e7", NULL, NULL); |
| 1775 | + reportxml_node_t *incident = reportxml_get_node_by_type(report, REPORTXML_NODE_TYPE_INCIDENT, 0); |
| 1776 | + reportxml_node_t *resource = reportxml_node_new(REPORTXML_NODE_TYPE_RESOURCE, NULL, NULL, NULL); |
| 1777 | + reportxml_node_t *config = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL); |
| 1778 | + reportxml_node_t *dependencies = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL); |
| 1779 | + reportxml_node_t *flags = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL); |
| 1780 | + reportxml_node_t *cflags = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL); |
| 1781 | + reportxml_node_t *rflags = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL); |
| 1782 | + ice_config_t *icecast_config; |
| 1783 | +#ifdef HAVE_CURL |
| 1784 | + const curl_version_info_data * curl_runtime_version = curl_version_info(CURLVERSION_NOW); |
| 1785 | +#endif |
| 1786 | + struct { |
| 1787 | + const char *name; |
| 1788 | + const char *compiletime; |
| 1789 | + const char *runtime; |
| 1790 | + } dependency_versions[] = { |
| 1791 | + {"libxml2", LIBXML_DOTTED_VERSION, NULL}, |
| 1792 | +#if defined(HAVE_OPENSSL) && defined(OPENSSL_VERSION_TEXT) |
| 1793 | + {"OpenSSL", OPENSSL_VERSION_TEXT, NULL}, |
| 1794 | +#endif |
| 1795 | + {"libvorbis", NULL, vorbis_version_string()}, |
| 1796 | +#ifdef HAVE_THEORA |
| 1797 | + {"libtheora", NULL, theora_version_string()}, |
| 1798 | +#endif |
| 1799 | +#ifdef HAVE_SPEEX |
| 1800 | + {"libspeex", NULL, get_speex_version()}, |
| 1801 | +#endif |
| 1802 | +#ifdef HAVE_CURL |
| 1803 | + {"libcurl", LIBCURL_VERSION, curl_runtime_version->version}, |
| 1804 | +#endif |
| 1805 | + {NULL, NULL, NULL} |
| 1806 | + }; |
| 1807 | + const char *compiletime_flags[] = { |
| 1808 | +#ifdef HAVE_POLL |
| 1809 | + "poll", |
| 1810 | +#endif |
| 1811 | +#ifdef HAVE_SYS_SELECT_H |
| 1812 | + "select", |
| 1813 | +#endif |
| 1814 | +#ifdef HAVE_UNAME |
| 1815 | + "uname", |
| 1816 | +#endif |
| 1817 | +#ifdef HAVE_GETHOSTNAME |
| 1818 | + "gethostname", |
| 1819 | +#endif |
| 1820 | +#ifdef WIN32 |
| 1821 | + "win32", |
| 1822 | +#endif |
| 1823 | +#ifdef DEVEL_LOGGING |
| 1824 | + "developer-logging", |
| 1825 | +#endif |
| 1826 | + NULL, |
| 1827 | + }; |
| 1828 | + size_t i; |
| 1829 | + |
| 1830 | + reportxml_node_set_attribute(resource, "type", "result"); |
| 1831 | + reportxml_node_add_child(incident, resource); |
| 1832 | + |
| 1833 | + reportxml_helper_add_value_string(resource, "version", ICECAST_VERSION_STRING); |
| 1834 | + reportxml_helper_add_value_int(resource, "address-bits", sizeof(void*)*8); |
| 1835 | + |
| 1836 | +#ifdef HAVE_GETHOSTNAME |
| 1837 | + if (true) { |
| 1838 | + char hostname[80]; |
| 1839 | + if (gethostname(hostname, sizeof(hostname)) == 0) { |
| 1840 | + reportxml_helper_add_value_string(resource, "gethostname", hostname); |
| 1841 | + } else { |
| 1842 | + reportxml_helper_add_value_string(resource, "gethostname", NULL); |
| 1843 | + } |
| 1844 | + } |
| 1845 | +#endif |
| 1846 | + |
| 1847 | +#ifdef HAVE_UNAME |
| 1848 | + if (true) { |
| 1849 | + reportxml_node_t *res = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL); |
| 1850 | + struct utsname utsname; |
| 1851 | + |
| 1852 | + reportxml_node_set_attribute(res, "type", "structure"); |
| 1853 | + reportxml_node_set_attribute(res, "member", "uname"); |
| 1854 | + reportxml_node_add_child(resource, res); |
| 1855 | + |
| 1856 | + if(uname(&utsname) == 0) { |
| 1857 | + reportxml_helper_add_value_string(res, "sysname", utsname.sysname); |
| 1858 | + reportxml_helper_add_value_string(res, "release", utsname.release); |
| 1859 | + reportxml_helper_add_value_string(res, "nodename", utsname.nodename); |
| 1860 | + reportxml_helper_add_value_string(res, "version", utsname.version); |
| 1861 | + reportxml_helper_add_value_string(res, "machine", utsname.machine); |
| 1862 | + } else { |
| 1863 | + reportxml_node_set_attribute(res, "state", "unset"); |
| 1864 | + } |
| 1865 | + |
| 1866 | + refobject_unref(res); |
| 1867 | + } |
| 1868 | +#endif |
| 1869 | + |
| 1870 | + reportxml_node_set_attribute(config, "type", "structure"); |
| 1871 | + reportxml_node_set_attribute(config, "member", "config"); |
| 1872 | + reportxml_node_add_child(resource, config); |
| 1873 | + |
| 1874 | + icecast_config = config_get_config(); |
| 1875 | + reportxml_helper_add_value_string(config, "hostname", icecast_config->hostname); |
| 1876 | + reportxml_helper_add_value_string(config, "location", icecast_config->location); |
| 1877 | + reportxml_helper_add_value_string(config, "admin", icecast_config->admin); |
| 1878 | + reportxml_helper_add_value_string(config, "server-id", icecast_config->server_id); |
| 1879 | + |
| 1880 | + reportxml_helper_add_value_flag(rflags, "requested-chroot", icecast_config->chroot); |
| 1881 | + reportxml_helper_add_value_flag(rflags, "requested-chuid", icecast_config->chuid); |
| 1882 | + config_release_config(); |
| 1883 | + |
| 1884 | + reportxml_node_set_attribute(dependencies, "type", "structure"); |
| 1885 | + reportxml_node_set_attribute(dependencies, "member", "dependencies"); |
| 1886 | + reportxml_node_add_child(resource, dependencies); |
| 1887 | + |
| 1888 | + for (i = 0; dependency_versions[i].name; i++) { |
| 1889 | + reportxml_node_t *dependency = reportxml_node_new(REPORTXML_NODE_TYPE_VALUE, NULL, NULL, NULL); |
| 1890 | + reportxml_node_set_attribute(dependency, "type", "structure"); |
| 1891 | + reportxml_node_set_attribute(dependency, "member", dependency_versions[i].name); |
| 1892 | + reportxml_helper_add_value_string(dependency, "compiletime", dependency_versions[i].compiletime); |
| 1893 | + reportxml_helper_add_value_string(dependency, "runtime", dependency_versions[i].runtime); |
| 1894 | + reportxml_node_add_child(dependencies, dependency); |
| 1895 | + refobject_unref(dependency); |
| 1896 | + } |
| 1897 | + |
| 1898 | + reportxml_node_set_attribute(flags, "type", "structure"); |
| 1899 | + reportxml_node_set_attribute(flags, "member", "flags"); |
| 1900 | + reportxml_node_add_child(resource, flags); |
| 1901 | + |
| 1902 | + reportxml_node_set_attribute(cflags, "type", "unordered-list"); |
| 1903 | + reportxml_node_set_attribute(cflags, "member", "compiletime"); |
| 1904 | + reportxml_node_add_child(flags, cflags); |
| 1905 | + for (i = 0; compiletime_flags[i]; i++) { |
| 1906 | + reportxml_helper_add_value_flag(cflags, compiletime_flags[i], true); |
| 1907 | + } |
| 1908 | + |
| 1909 | + reportxml_node_set_attribute(rflags, "type", "unordered-list"); |
| 1910 | + reportxml_node_set_attribute(rflags, "member", "runtime"); |
| 1911 | + reportxml_node_add_child(flags, rflags); |
| 1912 | + reportxml_helper_add_value_flag(rflags, "ipv4-mapped", sock_is_ipv4_mapped_supported()); |
| 1913 | + |
| 1914 | + global_lock(); |
| 1915 | + reportxml_helper_add_value_flag(rflags, "bound-unix", listensocket_container_is_family_included(global.listensockets, SOCK_FAMILY_UNIX)); |
| 1916 | + reportxml_helper_add_value_flag(rflags, "bound-inet4", listensocket_container_is_family_included(global.listensockets, SOCK_FAMILY_INET4)); |
| 1917 | + reportxml_helper_add_value_flag(rflags, "bound-inet6", listensocket_container_is_family_included(global.listensockets, SOCK_FAMILY_INET6)); |
| 1918 | + global_unlock(); |
| 1919 | + |
| 1920 | + refobject_unref(config); |
| 1921 | + refobject_unref(dependencies); |
| 1922 | + refobject_unref(cflags); |
| 1923 | + refobject_unref(rflags); |
| 1924 | + refobject_unref(flags); |
| 1925 | + refobject_unref(resource); |
| 1926 | + refobject_unref(incident); |
| 1927 | + client_send_reportxml(client, report, DOCUMENT_DOMAIN_ADMIN, VERSION_HTML_REQUEST, response, 200, NULL); |
| 1928 | + refobject_unref(report); |
| 1929 | +} |
1729 | 1930 |
|
1730 | 1931 | static void ui_command(client_t * client, source_t * source, admin_format_t format, resourcematch_extract_t *parameters) |
1731 | 1932 | { |
|
0 commit comments