diff --git a/configure.in b/configure.in index b13bc36c..1d1763ad 100644 --- a/configure.in +++ b/configure.in @@ -39,6 +39,8 @@ AC_CHECK_FUNCS([setuid]) AC_CHECK_FUNCS([chroot]) AC_CHECK_FUNCS([chown]) AC_CHECK_FUNCS([strcasestr]) +AC_CHECK_FUNCS([gethostname]) +AC_CHECK_FUNCS([uname]) dnl Checks for typedefs, structures, and compiler characteristics. XIPH_C__FUNC__ diff --git a/src/cfgfile.c b/src/cfgfile.c index be8b2f7f..a7f0bb92 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -31,6 +31,7 @@ #include "refbuf.h" #include "client.h" #include "logging.h" +#include "util.h" #define CATMODULE "CONFIG" #define CONFIG_DEFAULT_LOCATION "Earth" @@ -450,6 +451,44 @@ static void _set_defaults(ice_config_t *configuration) configuration->burst_size = CONFIG_DEFAULT_BURST_SIZE; } +static inline void __check_hostname(ice_config_t *configuration) { + char *p; + + // ensure we have a non-NULL buffer: + if (!configuration->hostname) + configuration->hostname = (char *)xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME); + + // convert to lower case: + for (p = configuration->hostname; *p; p++) + if ( *p >= 'A' && *p <= 'Z' ) + *p += 'a' - 'A'; + + configuration->sane_hostname = 0; + switch (util_hostcheck(configuration->hostname)) { + case HOSTCHECK_SANE: + configuration->sane_hostname = 1; + break; + case HOSTCHECK_ERROR: + ICECAST_LOG_ERROR("Can not check hostname \"%s\".", configuration->hostname); + break; + case HOSTCHECK_NOT_FQDN: + ICECAST_LOG_WARN("Warning, seems not to be set to a fully qualified fomain name (FQDN). This may cause problems, e.g. with YP directory listings."); + break; + case HOSTCHECK_IS_LOCALHOST: + ICECAST_LOG_WARN("Warning, not configured, using default value \"%s\". This will cause problems, e.g. with YP directory listings.", CONFIG_DEFAULT_HOSTNAME); + break; + case HOSTCHECK_IS_IPV4: + ICECAST_LOG_WARN("Warning, seems to be set to an IPv4 address. This may cause problems, e.g. with YP directory listings."); + break; + case HOSTCHECK_IS_IPV6: + ICECAST_LOG_WARN("Warning, seems to be set to an IPv6 address. This may cause problems, e.g. with YP directory listings."); + break; + case HOSTCHECK_BADCHAR: + ICECAST_LOG_WARN("Warning, configured to unusual characters. This may cause problems, e.g. with YP directory listings."); + break; + } +} + static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ice_config_t *configuration) { @@ -566,11 +605,7 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node, if (!configuration->fileserve) ICECAST_LOG_WARN("Warning, serving of static files has been disabled in the config, this will also affect files used by the web interface (stylesheets, images)."); - if (!configuration->hostname || strcmp(configuration->hostname, CONFIG_DEFAULT_HOSTNAME) == 0) { - ICECAST_LOG_WARN("Warning, not configured, using default value \"%s\". This will cause problems, e.g. with YP directory listings.", CONFIG_DEFAULT_HOSTNAME); - if (!configuration->hostname) - configuration->hostname = (char *)xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME); - } + __check_hostname(configuration); if (!configuration->location || strcmp(configuration->location, CONFIG_DEFAULT_LOCATION) == 0) { ICECAST_LOG_WARN("Warning, not configured, using default value \"%s\".", CONFIG_DEFAULT_LOCATION); diff --git a/src/cfgfile.h b/src/cfgfile.h index 26366c72..845685aa 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -167,6 +167,7 @@ typedef struct ice_config_tag { ice_config_dir_t *dir_list; char *hostname; + int sane_hostname; int port; char *mimetypes_fn; diff --git a/src/main.c b/src/main.c index b86e2294..3c016190 100644 --- a/src/main.c +++ b/src/main.c @@ -37,6 +37,10 @@ #include #endif +#ifdef HAVE_UNAME +#include +#endif + #include "thread/thread.h" #include "avl/avl.h" #include "net/sock.h" @@ -54,6 +58,7 @@ #endif #include "cfgfile.h" +#include "util.h" #include "sighandler.h" #include "global.h" @@ -425,6 +430,46 @@ static void _ch_root_uid_setup(void) } #endif +static inline void __log_system_name(void) { + char hostname[80] = "(unknown)"; + char system[128] = "(unknown)"; + int have_hostname = 0; +#ifdef HAVE_UNAME + struct utsname utsname; +#endif + ice_config_t *config; + +#ifdef HAVE_GETHOSTNAME + if (gethostname(hostname, sizeof(hostname)) != 0) { + strncpy(hostname, "(unknown)", sizeof(hostname)); + } else { + have_hostname = 1; + } +#endif +#ifdef HAVE_UNAME + if(uname(&utsname) == 0) { + snprintf(system, sizeof(system), "%s %s, %s, %s, %s", + utsname.sysname, utsname.release, utsname.nodename, utsname.version, utsname.machine); + if (!have_hostname) { + strncpy(hostname, utsname.nodename, sizeof(hostname)); + have_hostname = 1; + } + } +#elif defined(WIN32) + strncpy(system, "MS Windows", sizeof(system)); +#endif + + ICECAST_LOG_INFO("Running on %s; OS: %s; Address Bits: %i", hostname, system, sizeof(void*)*8); + + if (have_hostname) { + config = config_get_config(); + if (!config->sane_hostname && util_hostcheck(hostname) == HOSTCHECK_SANE) { + ICECAST_LOG_WARN("Hostname is not set to anything useful in , Consider setting it to the system's name \"%s\".", hostname); + } + config_release_config(); + } +} + #ifdef WIN32_SERVICE int mainService(int argc, char **argv) #else @@ -521,6 +566,7 @@ int main(int argc, char **argv) } ICECAST_LOG_INFO("%s server started", ICECAST_VERSION_STRING); + __log_system_name(); /* REM 3D Graphics */ diff --git a/src/util.c b/src/util.c index 4e58e9dd..55e08981 100644 --- a/src/util.c +++ b/src/util.c @@ -487,6 +487,47 @@ char *util_base64_decode(const char *data) return result; } +util_hostcheck_type util_hostcheck(const char *hostname) { + const char * p; + size_t colon_count; + + if (!hostname) + return HOSTCHECK_ERROR; + + if (strcmp(hostname, "localhost") == 0 || + strcmp(hostname, "localhost.localdomain") == 0 || + strcmp(hostname, "localhost.localnet") == 0) + return HOSTCHECK_IS_LOCALHOST; + + for (p = hostname; *p; p++) + if (!( (*p >= '0' && *p <= '9') || *p == '.')) + break; + if (!*p) + return HOSTCHECK_IS_IPV4; + + for (p = hostname, colon_count = 0; *p; p++) { + if (*p == ':') { + colon_count++; + continue; + } + if (!((*p >= 'a' && *p <= 'f') || (*p >= '0' && *p <= '9') || *p == ':')) + break; + } + if (!*p && colon_count) + return HOSTCHECK_IS_IPV6; + + for (p = hostname; *p; p++) + if (!( (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') || *p == '.' || *p == '-' )) + return HOSTCHECK_BADCHAR; + + for (p = hostname, colon_count = 0; *p && *p != '.'; p++); + if (!*p) + return HOSTCHECK_NOT_FQDN; + + return HOSTCHECK_SANE; +} + + /* TODO, FIXME: handle memory allocation errors better. */ static inline void _build_headers_loop(char **ret, size_t *len, ice_config_http_header_t *header, int status) { size_t headerlen; diff --git a/src/util.h b/src/util.h index c7b09f51..f2d14dc5 100644 --- a/src/util.h +++ b/src/util.h @@ -33,6 +33,18 @@ char *util_base64_encode(const char *data); char *util_base64_decode(const char *input); char *util_bin_to_hex(unsigned char *data, int len); +typedef enum _util_hostcheck_tag { + HOSTCHECK_ERROR = -1, + HOSTCHECK_SANE = 0, + HOSTCHECK_NOT_FQDN, + HOSTCHECK_IS_LOCALHOST, + HOSTCHECK_IS_IPV4, + HOSTCHECK_IS_IPV6, + HOSTCHECK_BADCHAR +} util_hostcheck_type; + +util_hostcheck_type util_hostcheck(const char *hostname); + char *util_url_unescape(const char *src); char *util_url_escape(const char *src);