aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Oberritter <obi@opendreambox.org>2010-11-01 14:36:06 +0100
committerAndreas Oberritter <obi@opendreambox.org>2010-11-16 17:15:38 +0100
commit728f5f70f2ece1e2ac1e70cf5a3512b6cfd8cd83 (patch)
tree3f748f049a81b2a8983762b5c28f9fc56963de93
parent96857065b23a18ed81c3165b9c503d7563e30351 (diff)
downloadenigma2-728f5f70f2ece1e2ac1e70cf5a3512b6cfd8cd83.tar.gz
enigma2-728f5f70f2ece1e2ac1e70cf5a3512b6cfd8cd83.zip
bsod: use simple XML generator
-rw-r--r--configure.ac3
-rw-r--r--main/Makefile.am42
-rw-r--r--[-rwxr-xr-x]main/bsod.cpp469
-rw-r--r--main/enigma.cpp17
-rw-r--r--main/version_info.cpp18
-rw-r--r--main/version_info.h8
-rw-r--r--main/xmlgenerator.cpp188
-rw-r--r--main/xmlgenerator.h43
8 files changed, 446 insertions, 342 deletions
diff --git a/configure.ac b/configure.ac
index 25589c2c..c2d8d915 100644
--- a/configure.ac
+++ b/configure.ac
@@ -34,6 +34,9 @@ AX_PTHREAD
TUXBOX_APPS_DVB
+AM_CONDITIONAL(HAVE_GIT_DIR, test -d "$srcdir/.git")
+AM_CONDITIONAL(HAVE_FAKE_GIT_DIR, test -f "$srcdir/.git/last_commit_info")
+
PKG_CHECK_MODULES(BASE, [freetype2 fribidi gstreamer-0.10 gstreamer-pbutils-0.10 libdvbsi++ libpng libxml-2.0 sigc++-1.2])
PKG_CHECK_MODULES(LIBDDVD, libdreamdvd, HAVE_LIBDDVD="yes", HAVE_LIBDDVD="no")
AM_CONDITIONAL(HAVE_LIBDDVD, test "$HAVE_LIBDDVD" = "yes")
diff --git a/main/Makefile.am b/main/Makefile.am
index c96f9066..782138e8 100644
--- a/main/Makefile.am
+++ b/main/Makefile.am
@@ -13,6 +13,10 @@ enigma2_SOURCES = \
bsod.cpp \
bsod.h \
enigma.cpp \
+ xmlgenerator.cpp \
+ xmlgenerator.h \
+ version_info.cpp \
+ version_info.h
version.h
EXTRA_DIST = \
@@ -48,27 +52,29 @@ enigma2_LDADD = \
enigma2_LDFLAGS = -Wl,--export-dynamic
-BUILT_SOURCES = version.h
-
+if HAVE_GIT_DIR
GIT_DIR = $(top_srcdir)/.git
+GIT = git --git-dir=$(GIT_DIR)
-version.h:
- if [ -d $(GIT_DIR) ]; then \
- if [ -f $(GIT_DIR)/last_commit_info ]; then \
- echo "#define ENIGMA2_LAST_CHANGE_DATE \"`cat $(GIT_DIR)/last_commit_info | grep 'Date:' | cut -d' ' -f4`\"" > $@; \
- echo "#define ENIGMA2_BRANCH \"`cat $(GIT_DIR)/branch`\"" >> $@; \
- else \
- echo "#define ENIGMA2_LAST_CHANGE_DATE \"`git --git-dir=$(top_srcdir)/.git log --no-color -n 1 --format=format:%cd --date=short`\"" > $@; \
- echo "#define ENIGMA2_BRANCH \"`git --git-dir=$(top_srcdir)/.git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`\"" >> $@; \
- fi; \
- elif [ ! -f $@ ]; then \
- echo "#define ENIGMA2_LAST_CHANGE_DATE \"`date --rfc-3339=date`\"" > $@; \
- echo "#define ENIGMA2_BRANCH \"$(PACKAGE_VERSION)\"" >> $@; \
- fi;
+if HAVE_FAKE_GIT_DIR
+ENIGMA2_DATE = `cat $(GIT_DIR)/last_commit_info | grep 'Date:' | cut -d' ' -f4`
+ENIGMA2_BRANCH = `cat $(GIT_DIR)/branch`
+else
+ENIGMA2_DATE = `$(GIT) log --no-color -n 1 --format=format:%cd --date=short`
+ENIGMA2_BRANCH = `$(GIT) branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'`
+ENIGMA2_REV = `$(GIT) describe --abbrev=7 --always --dirty --long --tags`
+endif
-dist-hook:
- echo "#define ENIGMA2_LAST_CHANGE_DATE \"`date --rfc-3339=date`\"" > version.h;
- echo "#define ENIGMA2_BRANCH \"$(PACKAGE_VERSION)\"" >> version.h;
+BUILT_SOURCES = version-intermediate.h
+CLEANFILES = version-intermediate.h
+version-intermediate.h:
+ $(AM_V_GEN)touch $@
+ $(AM_V_at)[ -n "$(ENIGMA2_DATE)" ] && echo "#define ENIGMA2_LAST_CHANGE_DATE \"$(ENIGMA2_DATE)\"" >> $@
+ $(AM_V_at)[ -n "$(ENIGMA2_BRANCH)" ] && echo "#define ENIGMA2_BRANCH \"$(ENIGMA2_BRANCH)\"" >> $@
+ $(AM_V_at)[ -n "$(ENIGMA2_REV)" ] && echo "#define ENIGMA2_REV \"$(ENIGMA2_REV)\"" >> $@
+ $(AM_V_at)([ -f version.h ] && diff -q version.h $@ >/dev/null) || $(INSTALL_HEADER) $@ version.h
+ $(AM_V_at)$(RM) $@
+endif
enigma2$(EXEEXT): $(enigma2_OBJECTS) $(enigma2_DEPENDENCIES) $(enigma2_LDADD_WHOLE)
$(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ $(enigma2_LDFLAGS) $(enigma2_OBJECTS) \
diff --git a/main/bsod.cpp b/main/bsod.cpp
index 40252c0f..7256d20a 100755..100644
--- a/main/bsod.cpp
+++ b/main/bsod.cpp
@@ -1,45 +1,51 @@
-#include <string.h>
-#include <signal.h>
-#include <asm/ptrace.h>
-
+#include <fstream>
+#include <sstream>
#include <lib/base/eenv.h>
#include <lib/base/eerror.h>
-#include <lib/base/smartptr.h>
#include <lib/base/nconfig.h>
-#include <lib/gdi/grc.h>
#include <lib/gdi/gmaindc.h>
-#include "version.h"
+#if defined(__MIPSEL__)
+#include <asm/ptrace.h>
+#else
+#warning "no oops support!"
+#define NO_OOPS_SUPPORT
+#endif
+
+#include "xmlgenerator.h"
+#include "version_info.h"
/************************************************/
#define CRASH_EMAILADDR "crashlog@dream-multimedia-tv.de"
-#define STDBUFFER_SIZE 512
+#define INFOFILE "/maintainer.info"
+
#define RINGBUFFER_SIZE 16384
static char ringbuffer[RINGBUFFER_SIZE];
-static int ringbuffer_head;
+static unsigned int ringbuffer_head;
-static void addToLogbuffer(const char *data, int len)
+static void addToLogbuffer(const char *data, unsigned int len)
{
while (len)
{
- int remaining = RINGBUFFER_SIZE - ringbuffer_head;
-
+ unsigned int remaining = RINGBUFFER_SIZE - ringbuffer_head;
+
if (remaining > len)
remaining = len;
-
+
memcpy(ringbuffer + ringbuffer_head, data, remaining);
len -= remaining;
data += remaining;
ringbuffer_head += remaining;
- if (ringbuffer_head >= RINGBUFFER_SIZE)
+ ASSERT(ringbuffer_head <= RINGBUFFER_SIZE);
+ if (ringbuffer_head == RINGBUFFER_SIZE)
ringbuffer_head = 0;
}
}
-static std::string getLogBuffer()
+static const std::string getLogBuffer()
{
- int begin = ringbuffer_head;
+ unsigned int begin = ringbuffer_head;
while (ringbuffer[begin] == 0)
{
++begin;
@@ -48,12 +54,11 @@ static std::string getLogBuffer()
if (begin == ringbuffer_head)
return "";
}
+
if (begin < ringbuffer_head)
return std::string(ringbuffer + begin, ringbuffer_head - begin);
else
- {
return std::string(ringbuffer + begin, RINGBUFFER_SIZE - begin) + std::string(ringbuffer, ringbuffer_head);
- }
}
static void addToLogbuffer(int level, const std::string &log)
@@ -61,117 +66,67 @@ static void addToLogbuffer(int level, const std::string &log)
addToLogbuffer(log.c_str(), log.size());
}
-static std::string getConfigFileValue(const char *entry)
+static const std::string getConfigString(const std::string &key, const std::string &defaultValue)
{
- std::string configfile = eEnv::resolve("${sysconfdir}/enigma2/settings");
- std::string configvalue;
- if (entry)
- {
- ePythonConfigQuery::getConfigValue(entry, configvalue);
- if (configvalue != "") //we get at least the default value if python is still alive
- {
- return configvalue;
- }
- else // get value from enigma2 settings file
- {
- FILE *f = fopen(configfile.c_str(), "r");
- if (!f)
- {
- return "Error";
- }
- while (1)
- {
- char line[1024];
- if (!fgets(line, 1024, f))
- break;
- if (!strncmp(line, entry, strlen(entry) ))
- {
- if (strlen(line) && line[strlen(line)-1] == '\r')
- line[strlen(line)-1] = 0;
- if (strlen(line) && line[strlen(line)-1] == '\n')
- line[strlen(line)-1] = 0;
- std::string tmp = line;
- int posEqual = tmp.find("=", 0);
- configvalue = tmp.substr(posEqual+1);
- }
- }
- fclose(f);
- return configvalue;
- }
- }
-}
+ std::string value;
-static std::string getFileContent(const char *file)
-{
- std::string filecontent;
+ ePythonConfigQuery::getConfigValue(key.c_str(), value);
+ //we get at least the default value if python is still alive
+ if (!value.empty())
+ return value;
- if (file)
- {
- FILE *f = fopen(file, "r");
- if (!f)
- {
- return "Error";
- }
- while (1)
- {
- char line[1024];
- if (!fgets(line, 1024, f))
+ value = defaultValue;
+
+ // get value from enigma2 settings file
+ std::ifstream in(eEnv::resolve("${sysconfdir}/enigma2/settings").c_str());
+ if (in.good()) {
+ do {
+ std::string line;
+ std::getline(in, line);
+ size_t size = key.size();
+ if (!key.compare(0, size, line) && line[size] == '=') {
+ value = line.substr(size + 1);
break;
- std::string tmp = line;
- std::string password;
- int pwdpos = tmp.find(".password=", 0);
- if( pwdpos != std::string::npos)
- {
- filecontent += tmp.substr(0,pwdpos +10);
- for ( int pos = pwdpos +10; pos < tmp.length()-1; ++pos )
- {
- filecontent += "X";
- }
- filecontent += "\n";
- }
- else {
- filecontent += line;
}
- }
- fclose(f);
+ } while (in.good());
+ in.close();
}
- return filecontent;
-}
-static std::string execCommand(std::string cmd) {
- FILE* pipe = popen(cmd.c_str(), "r");
- if (!pipe)
- return "Error";
- char buffer[STDBUFFER_SIZE];
- std::string result = "";
- while(!feof(pipe))
- {
- if(!fgets(buffer,STDBUFFER_SIZE, pipe))
- break;
- result += buffer;
- }
- pclose(pipe);
- return result;
+ return value;
}
-#define INFOFILE "/maintainer.info"
+static bool getConfigBool(const std::string &key, bool defaultValue)
+{
+ std::string value = getConfigString(key, defaultValue ? "true" : "false");
+ const char *cvalue = value.c_str();
+
+ if (!strcasecmp(cvalue, "true"))
+ return true;
+ if (!strcasecmp(cvalue, "false"))
+ return false;
+
+ return defaultValue;
+}
void bsodFatal(const char *component)
{
- char logfile[128];
- sprintf(logfile, "/media/hdd/enigma2_crash_%u.log", (unsigned int)time(0));
- FILE *f = fopen(logfile, "wb");
+ std::ostringstream os;
+ os << time(0);
+
+ std::string logfile("/media/hdd/enigma2_crash_" + os.str() + ".log");
+
+ FILE *f = fopen(logfile.c_str(), "wb");
std::string lines = getLogBuffer();
/* find python-tracebacks, and extract " File "-strings */
size_t start = 0;
- char crash_emailaddr[256] = CRASH_EMAILADDR;
- char crash_component[256] = "enigma2";
+ std::string crash_emailaddr = CRASH_EMAILADDR;
+ std::string crash_component = "enigma2";
if (component)
- snprintf(crash_component, 256, component);
+ crash_component = component;
else
{
while ((start = lines.find("\n File \"", start)) != std::string::npos)
@@ -188,21 +143,12 @@ void bsodFatal(const char *component)
if (end == std::string::npos)
break;
- if (end - start >= (256 - strlen(INFOFILE)))
- continue;
- char filename[256];
- snprintf(filename, 256, "%s%s", lines.substr(start, end - start).c_str(), INFOFILE);
- FILE *cf = fopen(filename, "r");
- if (cf)
- {
- fgets(crash_emailaddr, sizeof crash_emailaddr, cf);
- if (*crash_emailaddr && crash_emailaddr[strlen(crash_emailaddr)-1] == '\n')
- crash_emailaddr[strlen(crash_emailaddr)-1] = 0;
-
- fgets(crash_component, sizeof crash_component, cf);
- if (*crash_component && crash_component[strlen(crash_component)-1] == '\n')
- crash_component[strlen(crash_component)-1] = 0;
- fclose(cf);
+
+ std::string filename(lines.substr(start, end - start) + INFOFILE);
+ std::ifstream in(filename.c_str());
+ if (in.good()) {
+ std::getline(in, crash_emailaddr) && std::getline(in, crash_component);
+ in.close();
}
}
}
@@ -210,202 +156,108 @@ void bsodFatal(const char *component)
if (f)
{
time_t t = time(0);
- char crashtime[STDBUFFER_SIZE];
- sprintf(crashtime, "%s",ctime(&t));
- if (strlen(crashtime) && crashtime[strlen(crashtime)-1] == '\n')
- crashtime[strlen(crashtime)-1] = 0;
- fprintf(f, "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>\n<opendreambox>\n");
- fprintf(f, "\t<enigma2>\n");
- fprintf(f, "\t\t<crashdate>%s</crashdate>\n", crashtime);
-#ifdef ENIGMA2_CHECKOUT_TAG
- fprintf(f, "\t\t<checkouttag>" ENIGMA2_CHECKOUT_TAG "</checkouttag>\n");
-#else
- fprintf(f, "\t\t<compiledate>" __DATE__ "</compiledate>\n");
-#endif
-#ifdef ENIGMA2_CHECKOUT_ROOT
- fprintf(f, "\t\t<checkoutroot>" ENIGMA2_CHECKOUT_ROOT "</checkoutroot>\n");
-#endif
- fprintf(f, "\t\t<contactemail>%s</contactemail>\n", crash_emailaddr);
- fprintf(f, "\t\t<!-- Please email this crashlog to above address -->\n");
- std::string activeSkin = getConfigFileValue("config.skin.primary_skin");
- if (activeSkin != "Error")
- {
- if (activeSkin == "")
- activeSkin = "Default Skin";
- fprintf(f, "\t\t<skin>%s</skin>\n", activeSkin.c_str());
- }
- fprintf(f, "\t</enigma2>\n");
+ struct tm tm;
+ char tm_str[32];
- fprintf(f, "\t<image>\n");
- std::string model = getFileContent("/proc/stb/info/model");
- if (model != "Error")
- {
- char modelname[STDBUFFER_SIZE];
- sprintf(modelname, "%s",model.c_str());
- if (strlen(modelname) && modelname[strlen(modelname)-1] == '\n')
- modelname[strlen(modelname)-1] = 0;
- fprintf(f, "\t\t<dreamboxmodel>%s</dreamboxmodel>\n", modelname);
- }
- std::string kernel = getFileContent("/proc/cmdline");
- if (kernel != "Error")
- {
- char kernelcmd[STDBUFFER_SIZE];
- sprintf(kernelcmd, "%s",kernel.c_str());
- if (strlen(kernelcmd) && kernelcmd[strlen(kernelcmd)-1] == '\n')
- kernelcmd[strlen(kernelcmd)-1] = 0;
- fprintf(f, "\t\t<kernelcmdline>%s</kernelcmdline>\n", kernelcmd);
- }
- std::string sendAnonCrashlog = getConfigFileValue("config.plugins.crashlogautosubmit.sendAnonCrashlog");
- if (sendAnonCrashlog == "False" || sendAnonCrashlog == "false") // defaults to true... default anonymized crashlogs
- {
- std::string ca = getFileContent("/proc/stb/info/ca");
- if (ca != "Error")
- {
- char dreamboxca[STDBUFFER_SIZE];
- sprintf(dreamboxca, "%s",ca.c_str());
- if (strlen(dreamboxca) && dreamboxca[strlen(dreamboxca)-1] == '\n')
- dreamboxca[strlen(dreamboxca)-1] = 0;
- fprintf(f, "\t\t<dreamboxca>\n\t\t<![CDATA[\n%s\n\t\t]]>\n\t\t</dreamboxca>\n", dreamboxca);
- }
- std::string settings = getFileContent(eEnv::resolve("${sysconfdir}/enigma2/settings").c_str());
- if (settings != "Error")
- {
- fprintf(f, "\t\t<enigma2settings>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</enigma2settings>\n", settings.c_str());
- }
- }
- std::string addNetwork = getConfigFileValue("config.plugins.crashlogautosubmit.addNetwork");
- if (addNetwork == "True" || addNetwork == "true")
- {
- std::string nwinterfaces = getFileContent("/etc/network/interfaces");
- if (nwinterfaces != "Error")
- {
- fprintf(f, "\t\t<networkinterfaces>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</networkinterfaces>\n", nwinterfaces.c_str());
- }
- std::string dns = getFileContent("/etc/resolv.conf");
- if (dns != "Error")
- {
- fprintf(f, "\t\t<dns>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</dns>\n", dns.c_str());
- }
- std::string defaultgw = getFileContent("/etc/default_gw");
- if (defaultgw != "Error")
- {
- char gateway[STDBUFFER_SIZE];
- sprintf(gateway, "%s",defaultgw.c_str());
- if (strlen(gateway) && gateway[strlen(gateway)-1] == '\n')
- gateway[strlen(gateway)-1] = 0;
- fprintf(f, "\t\t<defaultgateway>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</defaultgateway>\n", gateway);
- }
- }
- std::string addWlan = getConfigFileValue("config.plugins.crashlogautosubmit.addWlan");
- if (addWlan == "True" || addWlan == "true")
- {
- std::string wpasupplicant = getFileContent("/etc/wpa_supplicant.conf");
- if (wpasupplicant != "Error")
- {
- fprintf(f, "\t\t<wpasupplicant>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</wpasupplicant>\n", wpasupplicant.c_str());
- }
- }
- std::string imageversion = getFileContent("/etc/image-version");
- if (imageversion != "Error")
- {
- fprintf(f, "\t\t<imageversion>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</imageversion>\n", imageversion.c_str());
+ localtime_r(&t, &tm);
+ strftime(tm_str, sizeof(tm_str), "%a %b %_d %T %Y", &tm);
+
+ XmlGenerator xml(f);
+
+ xml.open("opendreambox");
+
+ xml.open("enigma2");
+ xml.string("crashdate", tm_str);
+ xml.string("compiledate", __DATE__);
+ xml.string("contactemail", crash_emailaddr);
+ xml.comment("Please email this crashlog to above address");
+
+ xml.string("skin", getConfigString("config.skin.primary_skin", "Default Skin"));
+ xml.string("sourcedate", enigma2_date);
+ xml.string("branch", enigma2_branch);
+ xml.string("rev", enigma2_rev);
+ xml.string("version", PACKAGE_VERSION);
+ xml.close();
+
+ xml.open("image");
+ xml.stringFromFile("dreamboxmodel", "/proc/stb/info/model");
+ xml.stringFromFile("kernelcmdline", "/proc/cmdline");
+ if (!getConfigBool("config.plugins.crashlogautosubmit.sendAnonCrashlog", true)) {
+ xml.cDataFromFile("dreamboxca", "/proc/stb/info/ca");
+ xml.cDataFromFile("enigma2settings", eEnv::resolve("${sysconfdir}/enigma2/settings"), ".password=");
}
- std::string imageissue = getFileContent("/etc/issue.net");
- if (imageissue != "Error")
- {
- fprintf(f, "\t\t<imageissue>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</imageissue>\n", imageissue.c_str());
+ if (getConfigBool("config.plugins.crashlogautosubmit.addNetwork", false)) {
+ xml.cDataFromFile("networkinterfaces", "/etc/network/interfaces");
+ xml.cDataFromFile("dns", "/etc/resolv.conf");
+ xml.cDataFromFile("defaultgateway", "/etc/default_gw");
}
- fprintf(f, "\t</image>\n");
-
- fprintf(f, "\t<software>\n");
- std::string installedplugins = execCommand("ipkg list_installed | grep enigma2");
- fprintf(f, "\t\t<enigma2software>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</enigma2software>\n", installedplugins.c_str());
- std::string dreambox = execCommand("ipkg list_installed | grep dream");
- fprintf(f, "\t\t<dreamboxsoftware>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</dreamboxsoftware>\n", dreambox.c_str());
- std::string gstreamer = execCommand("ipkg list_installed | grep gst");
- fprintf(f, "\t\t<gstreamersoftware>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</gstreamersoftware>\n", gstreamer.c_str());
- fprintf(f, "\t</software>\n");
-
- fprintf(f, "\t<crashlogs>\n");
- std::string buffer = getLogBuffer();
- fprintf(f, "\t\t<enigma2crashlog>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</enigma2crashlog>\n", buffer.c_str());
- std::string pythonmd5 = execCommand("find " + eEnv::resolve("${libdir}/enigma2/python/") + " -name \"*.py\" | xargs md5sum");
- fprintf(f, "\t\t<pythonMD5sum>\n\t\t<![CDATA[\n%s\t\t]]>\n\t\t</pythonMD5sum>\n", pythonmd5.c_str());
- fprintf(f, "\t</crashlogs>\n");
-
- fprintf(f, "\n</opendreambox>\n");
+ if (getConfigBool("config.plugins.crashlogautosubmit.addWlan", false))
+ xml.cDataFromFile("wpasupplicant", "/etc/wpa_supplicant.conf");
+ xml.cDataFromFile("imageversion", "/etc/image-version");
+ xml.cDataFromFile("imageissue", "/etc/issue.net");
+ xml.close();
+
+ xml.open("software");
+ xml.cDataFromCmd("enigma2software", "ipkg list_installed | grep enigma2");
+ xml.cDataFromCmd("dreamboxsoftware", "ipkg list_installed | grep dream");
+ xml.cDataFromCmd("gstreamersoftware", "ipkg list_installed | grep gst");
+ xml.close();
+
+ xml.open("crashlogs");
+ xml.cDataFromString("enigma2crashlog", getLogBuffer());
+ xml.cDataFromCmd("pythonMD5sum", "find " + eEnv::resolve("${libdir}/enigma2/python/") + " -name \"*.py\" | xargs md5sum");
+ xml.close();
+
+ xml.close();
+
fclose(f);
-
}
-
+
ePtr<gMainDC> my_dc;
gMainDC::getInstance(my_dc);
- {
- gPainter p(my_dc);
- p.resetOffset();
- p.resetClip(eRect(ePoint(0, 0), my_dc->size()));
-#ifdef ENIGMA2_CHECKOUT_TAG
- if (ENIGMA2_CHECKOUT_TAG[0] == 'T') /* tagged checkout (release) */
- p.setBackgroundColor(gRGB(0x0000C0));
- else if (ENIGMA2_CHECKOUT_TAG[0] == 'D') /* dated checkout (daily experimental build) */
- {
- srand(time(0));
- int r = rand();
- unsigned int col = 0;
- if (r & 1)
- col |= 0x800000;
- if (r & 2)
- col |= 0x008000;
- if (r & 4)
- col |= 0x0000c0;
- p.setBackgroundColor(gRGB(col));
- }
-#else
- p.setBackgroundColor(gRGB(0x008000));
-#endif
+ gPainter p(my_dc);
+ p.resetOffset();
+ p.resetClip(eRect(ePoint(0, 0), my_dc->size()));
+ p.setBackgroundColor(gRGB(0x008000));
+ p.setForegroundColor(gRGB(0xFFFFFF));
- p.setForegroundColor(gRGB(0xFFFFFF));
-
- ePtr<gFont> font = new gFont("Regular", 20);
- p.setFont(font);
- p.clear();
-
- eRect usable_area = eRect(100, 70, my_dc->size().width() - 150, 100);
-
- char text[512];
- snprintf(text, 512, "We are really sorry. Your Dreambox encountered "
- "a software problem, and needs to be restarted. "
- "Please send the logfile created in /hdd/ to %s.\n"
- "Your Dreambox restarts in 10 seconds!\n"
- "Component: %s",
- crash_emailaddr, crash_component);
-
- p.renderText(usable_area, text, gPainter::RT_WRAP|gPainter::RT_HALIGN_LEFT);
-
- usable_area = eRect(100, 170, my_dc->size().width() - 180, my_dc->size().height() - 20);
-
- int i;
+ ePtr<gFont> font = new gFont("Regular", 20);
+ p.setFont(font);
+ p.clear();
+
+ eRect usable_area = eRect(100, 70, my_dc->size().width() - 150, 100);
- size_t start = std::string::npos + 1;
- for (i=0; i<20; ++i)
+ std::string text("We are really sorry. Your Dreambox encountered "
+ "a software problem, and needs to be restarted. "
+ "Please send the logfile created in /hdd/ to " + crash_emailaddr + ".\n"
+ "Your Dreambox restarts in 10 seconds!\n"
+ "Component: " + crash_component);
+
+ p.renderText(usable_area, text.c_str(), gPainter::RT_WRAP|gPainter::RT_HALIGN_LEFT);
+
+ usable_area = eRect(100, 170, my_dc->size().width() - 180, my_dc->size().height() - 20);
+
+ int i;
+
+ start = std::string::npos + 1;
+ for (i=0; i<20; ++i)
+ {
+ start = lines.rfind('\n', start - 1);
+ if (start == std::string::npos)
{
- start = lines.rfind('\n', start - 1);
- if (start == std::string::npos)
- {
- start = 0;
- break;
- }
+ start = 0;
+ break;
}
-
- font = new gFont("Regular", 14);
- p.setFont(font);
-
- p.renderText(usable_area,
- lines.substr(start), gPainter::RT_HALIGN_LEFT);
- sleep(10);
}
+ font = new gFont("Regular", 14);
+ p.setFont(font);
+
+ p.renderText(usable_area,
+ lines.substr(start), gPainter::RT_HALIGN_LEFT);
+ sleep(10);
+
raise(SIGKILL);
}
@@ -432,16 +284,13 @@ void oops(const mcontext_t &context, int dumpcode)
eDebug(" (end)");
}
}
-#else
-#warning "no oops support!"
-#define NO_OOPS_SUPPORT
#endif
void handleFatalSignal(int signum, siginfo_t *si, void *ctx)
{
+#ifndef NO_OOPS_SUPPORT
ucontext_t *uc = (ucontext_t*)ctx;
-#ifndef NO_OOPS_SUPPORT
oops(uc->uc_mcontext, signum == SIGSEGV || signum == SIGABRT);
#endif
eDebug("-------");
diff --git a/main/enigma.cpp b/main/enigma.cpp
index 3ea4afb7..6bc35714 100644
--- a/main/enigma.cpp
+++ b/main/enigma.cpp
@@ -28,6 +28,7 @@
#include <lib/python/python.h>
#include "bsod.h"
+#include "version_info.h"
#include <gst/gst.h>
@@ -296,22 +297,10 @@ void quitMainloop(int exitCode)
eApp->quit(0);
}
-#include "version.h"
-
const char *getEnigmaVersionString()
{
- std::string date =
-#ifdef ENIGMA2_LAST_CHANGE_DATE
- ENIGMA2_LAST_CHANGE_DATE;
-#else
- __DATE__;
-#endif
- std::string branch =
-#ifdef ENIGMA2_BRANCH
- ENIGMA2_BRANCH;
-#else
- "HEAD";
-#endif
+ std::string date = enigma2_date;
+ std::string branch = enigma2_branch;
return std::string(date + '-' + branch).c_str();
}
diff --git a/main/version_info.cpp b/main/version_info.cpp
new file mode 100644
index 00000000..372101d9
--- /dev/null
+++ b/main/version_info.cpp
@@ -0,0 +1,18 @@
+#include "version_info.h"
+#include "version.h"
+
+#ifndef ENIGMA2_LAST_CHANGE_DATE
+#define ENIGMA2_LAST_CHANGE_DATE __DATE__
+#endif
+const char *enigma2_date = ENIGMA2_LAST_CHANGE_DATE;
+
+#ifndef ENIGMA2_BRANCH
+#define ENIGMA2_BRANCH "HEAD"
+#endif
+const char *enigma2_branch = ENIGMA2_BRANCH;
+
+#ifndef ENIGMA2_REV
+#define ENIGMA2_REV NULL
+#endif
+const char *enigma2_rev = ENIGMA2_REV;
+
diff --git a/main/version_info.h b/main/version_info.h
new file mode 100644
index 00000000..f93cf01a
--- /dev/null
+++ b/main/version_info.h
@@ -0,0 +1,8 @@
+#ifndef __main_version_info_h__
+#define __main_version_info_h__
+
+extern const char *enigma2_date;
+extern const char *enigma2_branch;
+extern const char *enigma2_rev;
+
+#endif
diff --git a/main/xmlgenerator.cpp b/main/xmlgenerator.cpp
new file mode 100644
index 00000000..eb4f1577
--- /dev/null
+++ b/main/xmlgenerator.cpp
@@ -0,0 +1,188 @@
+#include <fstream>
+#include <lib/base/eerror.h>
+#include "xmlgenerator.h"
+
+XmlGenerator::XmlGenerator(FILE *f) : m_file(f), m_indent(true), m_level(0)
+{
+ ::fprintf(m_file, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
+}
+
+XmlGenerator::~XmlGenerator()
+{
+}
+
+void XmlGenerator::vprint(const char *fmt, va_list ap, bool newline)
+{
+ unsigned int i;
+
+ if (m_indent)
+ for (i = 0; i < m_level; i++)
+ ::fprintf(m_file, "\t");
+
+ ::vfprintf(m_file, fmt, ap);
+
+ if (newline)
+ ::fprintf(m_file, "\n");
+}
+
+void XmlGenerator::print(const char *fmt, ...)
+{
+ va_list ap;
+
+ ::va_start(ap, fmt);
+ vprint(fmt, ap, false);
+ ::va_end(ap);
+}
+
+void XmlGenerator::printLn(const char *fmt, ...)
+{
+ va_list ap;
+
+ ::va_start(ap, fmt);
+ vprint(fmt, ap, true);
+ ::va_end(ap);
+}
+
+void XmlGenerator::open(const std::string &tag, bool newline)
+{
+ if (newline) {
+ printLn("<%s>", tag.c_str());
+ } else {
+ print("<%s>", tag.c_str());
+ m_indent = false;
+ }
+
+ m_tags.push(tag);
+ m_level++;
+}
+
+void XmlGenerator::open(const std::string &tag)
+{
+ open(tag, true);
+}
+
+void XmlGenerator::close()
+{
+ ASSERT(!m_tags.empty());
+ ASSERT(m_level > 0);
+ m_level--;
+
+ printLn("</%s>", m_tags.top().c_str());
+ m_indent = true;
+
+ m_tags.pop();
+}
+
+void XmlGenerator::comment(const std::string &str)
+{
+ printLn("<!-- %s -->", str.c_str());
+}
+
+void XmlGenerator::commentFromErrno(const std::string &tag)
+{
+ open(tag);
+ comment(strerror(errno));
+ close();
+}
+
+std::string XmlGenerator::cDataEscape(const std::string &str)
+{
+ const std::string search = "]]>";
+ const std::string replace = "]]]]><![CDATA[>";
+ std::string ret;
+ size_t pos = 0, opos;
+
+ for (;;) {
+ opos = pos;
+ pos = str.find(search, opos);
+ if (pos == std::string::npos)
+ break;
+ ret.append(str, opos, pos - opos);
+ ret.append(replace);
+ pos += search.size();
+ }
+
+ ret.append(str, opos, std::string::npos);
+ return ret;
+}
+
+void XmlGenerator::cDataFromCmd(const std::string &tag, const std::string &cmd)
+{
+ FILE *pipe = ::popen(cmd.c_str(), "re");
+
+ if (pipe == 0) {
+ commentFromErrno(tag);
+ return;
+ }
+
+ std::string result;
+ char *lineptr = NULL;
+ size_t n = 0;
+
+ for (;;) {
+ ssize_t ret = ::getline(&lineptr, &n, pipe);
+ if (ret < 0)
+ break;
+ result.append(lineptr, ret);
+ }
+
+ if (lineptr)
+ ::free(lineptr);
+
+ ::pclose(pipe);
+ cDataFromString(tag, result);
+}
+
+void XmlGenerator::cDataFromFile(const std::string &tag, const std::string &filename, const char *filter)
+{
+ std::ifstream in(filename.c_str());
+ std::string line;
+ std::string content;
+
+ if (!in.good()) {
+ commentFromErrno(tag);
+ return;
+ }
+
+ while (std::getline(in, line))
+ if (!filter || !line.find(filter))
+ content += line + '\n';
+
+ in.close();
+ cDataFromString(tag, content);
+}
+
+void XmlGenerator::cDataFromString(const std::string &tag, const std::string &str)
+{
+ bool indent = false;
+
+ open(tag);
+ printLn("<![CDATA[");
+ std::swap(m_indent, indent);
+ print("%s", cDataEscape(str).c_str());
+ printLn("]]>");
+ std::swap(m_indent, indent);
+ close();
+}
+
+void XmlGenerator::string(const std::string &tag, const std::string &str)
+{
+ open(tag, false);
+ print("%s", str.c_str());
+ close();
+}
+
+void XmlGenerator::stringFromFile(const std::string &tag, const std::string &filename)
+{
+ std::ifstream in(filename.c_str());
+ std::string line;
+
+ if (!in.good()) {
+ commentFromErrno(tag);
+ return;
+ }
+
+ std::getline(in, line);
+ in.close();
+ string(tag, line);
+}
diff --git a/main/xmlgenerator.h b/main/xmlgenerator.h
new file mode 100644
index 00000000..0dbb2628
--- /dev/null
+++ b/main/xmlgenerator.h
@@ -0,0 +1,43 @@
+#ifndef _main_xmlgenerator_h__
+#define _main_xmlgenerator_h__
+
+#include <cstdarg>
+#include <cstdio>
+#include <stack>
+#include <string>
+
+class XmlGenerator
+{
+private:
+ FILE *m_file;
+ bool m_indent;
+ unsigned int m_level;
+ std::stack<std::string> m_tags;
+
+ void vprint(const char *fmt, va_list ap, bool newline);
+ void __attribute__ ((__format__(__printf__, 2, 3))) print(const char *fmt, ...);
+ void __attribute__ ((__format__(__printf__, 2, 3))) printLn(const char *fmt, ...);
+
+ void open(const std::string &tag, bool newline);
+ void commentFromErrno(const std::string &tag);
+
+ std::string cDataEscape(const std::string &str);
+
+public:
+ XmlGenerator(FILE *f);
+ ~XmlGenerator();
+
+ void open(const std::string &tag);
+ void close();
+
+ void comment(const std::string &str);
+
+ void cDataFromCmd(const std::string &tag, const std::string &cmd);
+ void cDataFromFile(const std::string &tag, const std::string &filename, const char *filter = 0);
+ void cDataFromString(const std::string &tag, const std::string &str);
+
+ void string(const std::string &tag, const std::string &str);
+ void stringFromFile(const std::string &tag, const std::string &filename);
+};
+
+#endif