From 1eb652688a7ff2e1b09f465b8bb94b5402bc5596 Mon Sep 17 00:00:00 2001 From: svenhoefer Date: Mon, 9 Feb 2015 08:51:33 +0100 Subject: [PATCH 01/26] - osdlang_setup.cpp: change user-dir for locales, to match the ... ... given path in system/localize.cpp --- src/gui/osdlang_setup.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/osdlang_setup.cpp b/src/gui/osdlang_setup.cpp index a03536ca1..d00b6d922 100644 --- a/src/gui/osdlang_setup.cpp +++ b/src/gui/osdlang_setup.cpp @@ -177,8 +177,7 @@ void COsdLangSetup::showLanguageSetup(CMenuWidget *osdl_setup) { struct dirent **namelist; int n; - // printf("scanning locale dir now....(perhaps)\n"); - char *pfad[] = {(char *) DATADIR "/neutrino/locale",(char *) CONFIGDIR "/locale"}; + char *pfad[] = {(char *) DATADIR "/neutrino/locale",(char *) "/var/tuxbox/locale"}; osdl_setup->addIntroItems(); From a85878db2fb59558b15aca9362b114aeae1a0d28 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 1 Feb 2015 19:59:15 +0100 Subject: [PATCH 02/26] CTextBox: fix text position calculation --- src/gui/widget/textbox.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/widget/textbox.cpp b/src/gui/widget/textbox.cpp index 0b91eee42..2b56027db 100644 --- a/src/gui/widget/textbox.cpp +++ b/src/gui/widget/textbox.cpp @@ -613,17 +613,19 @@ void CTextBox::refreshText(void) int i; int x_center = 0; + int lines = std::min(m_nLinesPerPage, m_nNrOfLines); + // set text y position if (m_nMode & TOP) // move to top of frame y += m_nFontTextHeight + ((m_cFrameTextRel.iHeight - m_nFontTextHeight * m_nLinesPerPage) >> 1); else if (m_nMode & BOTTOM) // move to bottom of frame - y += m_cFrameTextRel.iHeight - (m_nNrOfLines > 1 ? (m_nNrOfLines-1)*m_nFontTextHeight : 0) - text_Vborder_width; + y += m_cFrameTextRel.iHeight - (lines > 1 ? (lines - 1)*m_nFontTextHeight : 0) - text_Vborder_width; //m_nFontTextHeight + text_Vborder_width /*- ((m_cFrameTextRel.iHeight + m_nFontTextHeight*/ * m_nLinesPerPage/*) >> 1)*/; else // fit into mid of frame space - y += m_nFontTextHeight + ((m_cFrameTextRel.iHeight - m_nFontTextHeight * std::min(m_nLinesPerPage, m_nNrOfLines)) >> 1); + y += m_nFontTextHeight + ((m_cFrameTextRel.iHeight - m_nFontTextHeight * lines) >> 1); for(i = m_nCurrentLine; i < m_nNrOfLines && i < m_nCurrentLine + m_nLinesPerPage; i++) { From e02972c81ca902fe17e2b3cd2e06eb7c76a501af Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 1 Feb 2015 20:01:09 +0100 Subject: [PATCH 03/26] CShellWindow: use my_popen() to avoid leaking fds etc. --- src/gui/widget/shellwindow.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index a3208c7d3..4fab27253 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -7,6 +7,7 @@ Implementation: Copyright (C) 2013 martii gitorious.org/neutrino-mp/martiis-neutrino-mp + Copyright (C) 2015 Stefan Seyfried License: GPL @@ -33,13 +34,18 @@ #include #include +#include +#include #include #include #include #include #include +#include +#include CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res) { + pid_t pid; textBox = NULL; std::string cmd; mode = _mode; @@ -56,7 +62,7 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res } cmd = command + " 2>&1"; - FILE *f = popen(cmd.c_str(), "r"); + FILE *f = my_popen(pid, cmd.c_str(), "r"); if (!f) { if (res) *res = -1; @@ -163,13 +169,16 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res } } while(ok); - int r = pclose(f); + fclose(f); + int s; + errno = 0; + int r = waitpid(pid, &s, 0); if (res) { if (r == -1) - *res = r; + *res = errno; else - *res = WEXITSTATUS(r); + *res = WEXITSTATUS(s); } } From 27124e72e11f01ca3483fa2e4c7f11004c74eb9f Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 1 Feb 2015 20:11:02 +0100 Subject: [PATCH 04/26] shellwindow: fix line reading code In case of partially read lines, the last complete line before was discarded. Fix this, simplify the code and make it code work at all for lines longer than 1023 bytes (went into endless loop before). --- src/gui/widget/shellwindow.cpp | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 4fab27253..4d555d6ff 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -82,27 +82,26 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res struct timeval tv; gettimeofday(&tv,NULL); uint64_t lastPaint = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); - bool ok = true, nlseen = false, dirty = false, pushed = false; + bool ok = true, nlseen = false, dirty = false, incomplete = false; char output[1024]; - int off = 0; std::string txt = ""; + std::string line = ""; do { uint64_t now; fds.revents = 0; int r = poll(&fds, 1, 300); - if (r > 0) { if (!feof(f)) { gettimeofday(&tv,NULL); now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); unsigned int lines_read = 0; - while (fgets(output + off, sizeof(output) - off, f)) { - char *outputp = output + off; + while (fgets(output, sizeof(output), f)) { + char *outputp = output; dirty = true; - for (int i = off; output[i] && !nlseen; i++) + for (int i = 0; output[i] && !nlseen; i++) switch (output[i]) { case '\b': if (outputp > output) @@ -124,26 +123,26 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res if (outputp < output + sizeof(output)) *outputp = 0; + line += std::string(output); + if (incomplete) + lines.pop_back(); if (nlseen) { - pushed = false; + lines.push_back(line); + line.clear(); nlseen = false; - off = 0; + incomplete = false; } else { - off = strlen(output); - if (pushed) - lines.pop_back(); + lines.push_back(line); + incomplete = true; } - lines.push_back(std::string((output))); - pushed = true; if (lines.size() > lines_max) lines.pop_front(); txt = ""; bool first = true; for (std::list::const_iterator it = lines.begin(), end = lines.end(); it != end; ++it) { - if (first) - first = false; - else + if (!first) txt += '\n'; + first = false; txt += *it; } if (((lines_read == lines_max) && (lastPaint + 100000 < now)) || (lastPaint + 250000 < now)) { From 701cb24f458f9e2e1af51ca1df8e2cbc4e6d190b Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 1 Feb 2015 20:13:40 +0100 Subject: [PATCH 05/26] shellwindow: don't update screen if not necessary --- src/gui/widget/shellwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index 4d555d6ff..07302b0ed 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -160,7 +160,7 @@ CShellWindow::CShellWindow(const std::string &command, const int _mode, int *res gettimeofday(&tv,NULL); now = (uint64_t) tv.tv_usec + (uint64_t)((uint64_t) tv.tv_sec * (uint64_t) 1000000); - if (r < 1 || dirty || lastPaint + 250000 < now) { + if (!ok || (r < 1 && dirty && lastPaint + 250000 < now)) { textBox->setText(&txt); textBox->paint(); lastPaint = now; From 4e1678c2a3b6d9cf1f518b78e392aa5db8ca577f Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Fri, 6 Feb 2015 17:26:20 +0100 Subject: [PATCH 06/26] filebrowser, moviebrowser, pictureviewer: clarify error message --- src/gui/filebrowser.cpp | 2 +- src/gui/moviebrowser.cpp | 2 +- src/gui/pictureviewer.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/filebrowser.cpp b/src/gui/filebrowser.cpp index 3c892e21a..95de54101 100644 --- a/src/gui/filebrowser.cpp +++ b/src/gui/filebrowser.cpp @@ -562,7 +562,7 @@ bool CFileBrowser::readDir_std(const std::string & dirname, CFileList* flist) // printf("file.Name: '%s', getFileName: '%s' getPath: '%s'\n",file.Name.c_str(),file.getFileName().c_str(),file.getPath().c_str()); if(stat64((file.Name).c_str(),&statbuf) != 0) - perror("stat error"); + fprintf(stderr, "stat '%s' error: %m\n", file.Name.c_str()); else { file.Mode = statbuf.st_mode; diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 71f739c75..fab0174cd 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -2432,7 +2432,7 @@ bool CMovieBrowser::readDir(const std::string & dirname, CFileList* flist) // printf("file.Name: '%s', getFileName: '%s' getPath: '%s'\n",file.Name.c_str(),file.getFileName().c_str(),file.getPath().c_str()); if (my_stat((file.Name).c_str(),&statbuf) != 0) - perror("stat error"); + fprintf(stderr, "stat '%s' error: %m\n", file.Name.c_str()); else { file.Mode = statbuf.st_mode; diff --git a/src/gui/pictureviewer.cpp b/src/gui/pictureviewer.cpp index 366bfafb2..f948f7285 100644 --- a/src/gui/pictureviewer.cpp +++ b/src/gui/pictureviewer.cpp @@ -450,7 +450,7 @@ int CPictureViewerGui::show() pic.Type = tmp.substr(tmp.rfind('.')+1); struct stat statbuf; if (stat(pic.Filename.c_str(),&statbuf) != 0) - printf("stat error"); + fprintf(stderr, "stat '%s' error: %m\n", pic.Filename.c_str()); pic.Date = statbuf.st_mtime; playlist.push_back(pic); } From 6b787d8d3186c7cde67a42fa875cea4268f2b053 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Fri, 6 Feb 2015 21:58:48 +0100 Subject: [PATCH 07/26] pictureviewer/gif: fix build with giflib-5.1+ --- src/driver/pictureviewer/gif.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/driver/pictureviewer/gif.cpp b/src/driver/pictureviewer/gif.cpp index 4b0a3b23e..0e082b902 100644 --- a/src/driver/pictureviewer/gif.cpp +++ b/src/driver/pictureviewer/gif.cpp @@ -14,14 +14,20 @@ extern "C" { #include } +#if GIFLIB_MAJOR >= 5 && GIFLIB_MINOR >= 1 +#define DGIFCLOSEFILE(x) { int _error; DGifCloseFile(x, &_error); } +#else +#define DGIFCLOSEFILE(x) DGifCloseFile(x) +#endif #include #define min(a,b) ((a) < (b) ? (a) : (b)) #define gflush return(FH_ERROR_FILE); - #define grflush { DGifCloseFile(gft); return(FH_ERROR_FORMAT); } - #define mgrflush { free(lb); free(slb); DGifCloseFile(gft); return(FH_ERROR_FORMAT); } + #define grflush { DGIFCLOSEFILE(gft); return(FH_ERROR_FORMAT); } + #define mgrflush { free(lb); free(slb); DGIFCLOSEFILE(gft); return(FH_ERROR_FORMAT); } +#if 0 #define agflush return(FH_ERROR_FORMAT); #define agrflush { DGifCloseFile(gft); return(FH_ERROR_FORMAT); } - +#endif int fh_gif_id(const char *name) { @@ -123,7 +129,7 @@ int fh_gif_load(const char *name,unsigned char **buffer,int* /*xp*/,int* /*yp*/) } } while( rt!= TERMINATE_RECORD_TYPE ); - DGifCloseFile(gft); + DGIFCLOSEFILE(gft); return(FH_ERROR_OK); } int fh_gif_getsize(const char *name,int *x,int *y, int /*wanted_width*/, int /*wanted_height*/) @@ -152,7 +158,7 @@ int fh_gif_getsize(const char *name,int *x,int *y, int /*wanted_width*/, int /*w px=gft->Image.Width; py=gft->Image.Height; *x=px; *y=py; - DGifCloseFile(gft); + DGIFCLOSEFILE(gft); return(FH_ERROR_OK); break; case EXTENSION_RECORD_TYPE: @@ -165,7 +171,7 @@ int fh_gif_getsize(const char *name,int *x,int *y, int /*wanted_width*/, int /*w } } while( rt!= TERMINATE_RECORD_TYPE ); - DGifCloseFile(gft); + DGIFCLOSEFILE(gft); return(FH_ERROR_FORMAT); } #endif From c7dd4260d6d586578c9fdc2bcd69558033d2194d Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Fri, 6 Feb 2015 22:13:13 +0100 Subject: [PATCH 08/26] intall warning icon --- data/icons/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am index 43eceae09..e1166af54 100644 --- a/data/icons/Makefile.am +++ b/data/icons/Makefile.am @@ -265,6 +265,7 @@ install_DATA += \ volumeslider2red.png \ vtxt.png \ vtxt_gray.png \ + warning.png \ x_green.png \ x_white.png \ x_yellow.png \ From d04f7406a7b85ae6bc5fe7326f23983503f54ad2 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 7 Feb 2015 21:38:33 +0100 Subject: [PATCH 09/26] mdev_helper/hdd_menu: add udev support busybox/mdev fills the MDEV variable without /dev/ prefix, udev fills DEVNAME with /dev/ prefix. Handle both variants. --- src/gui/hdd_menu.cpp | 17 ++++++++++++----- src/mdev_helper.cpp | 6 +++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/gui/hdd_menu.cpp b/src/gui/hdd_menu.cpp index 5af3bf20c..2062a004a 100644 --- a/src/gui/hdd_menu.cpp +++ b/src/gui/hdd_menu.cpp @@ -2,7 +2,7 @@ Neutrino-GUI - DBoxII-Project Copyright (C) 2001 Steffen Hehn 'McClean' - Copyright (C) 2010-2014 Stefan Seyfried + Copyright (C) 2010-2015 Stefan Seyfried Copyright (C) 2013-2014 martii Copyright (C) 2009-2014 CoolStream International Ltd @@ -389,11 +389,18 @@ int CHDDMenuHandler::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t dat if (!split_config_string(str, smap)) return messages_return::handled; + std::string dev; std::map::iterator it = smap.find("MDEV"); - if (it == smap.end()) - return messages_return::handled; - - std::string dev = it->second; + if (it != smap.end()) + dev = it->second; + else { + it = smap.find("DEVNAME"); + if (it == smap.end()) + return messages_return::handled; + dev = it->second; + if (dev.length() > 5) + dev = dev.substr(5); /* strip off /dev/ */ + } printf("CHDDMenuHandler::handleMsg: MDEV=%s\n", dev.c_str()); if (!filterDevName(dev.c_str())) return messages_return::handled; diff --git a/src/mdev_helper.cpp b/src/mdev_helper.cpp index 26d35d781..7fd3659d4 100644 --- a/src/mdev_helper.cpp +++ b/src/mdev_helper.cpp @@ -37,10 +37,10 @@ const char *mdev_env[] = "MDEV" , "DEVPATH" , "INTERFACE", + "DEVNAME", + NULL /* terminating entry */ }; -#define ENV_SIZE (sizeof(mdev_env)/sizeof(char *)) - int main (int /*argc*/, char **argv) { struct sockaddr_un servaddr; @@ -64,7 +64,7 @@ int main (int /*argc*/, char **argv) goto _error; } - for (unsigned i = 0; i < ENV_SIZE; i++) { + for (unsigned i = 0; mdev_env[i]; i++) { char * s = getenv(mdev_env[i]); if (s) data += std::string(mdev_env[i]) + "=" + s + " "; From f75ed81dd1f3ec914a0a0400d00834954e780159 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 00:22:33 +0100 Subject: [PATCH 10/26] opkg_manager: remove the dependency on opkg-key opkg-key does not work at all in standard installs (without gpg) and is not needed for package management. Slightly change the definition of opkg commands to not initialize with find_executable function at startup which seems bogus. --- src/gui/opkg_manager.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index d4773c456..80f1cb38f 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -11,6 +11,7 @@ Adaptions: Copyright (C) 2013 martii gitorious.org/neutrino-mp/martiis-neutrino-mp + Copyright (C) 2015 Stefan Seyfried License: GPL @@ -51,8 +52,8 @@ #include #include -#define OPKG_CL find_executable("opkg-cl") -#define OPKG_KEY find_executable("opkg-key") +/* later this can be changed to just "opkg" */ +#define OPKG_CL "opkg-cl" enum { @@ -69,14 +70,14 @@ enum static const std::string pkg_types[OM_MAX] = { - OPKG_CL + " list", - OPKG_CL + " list-installed", - OPKG_CL + " list-upgradable", - OPKG_CL + " update", - OPKG_CL + " upgrade ", - OPKG_CL + " remove ", - OPKG_CL + " info ", - OPKG_CL + " install " + OPKG_CL " list", + OPKG_CL " list-installed", + OPKG_CL " list-upgradable", + OPKG_CL " update", + OPKG_CL " upgrade ", + OPKG_CL " remove ", + OPKG_CL " info ", + OPKG_CL " install " }; COPKGManager::COPKGManager() @@ -268,9 +269,13 @@ int COPKGManager::showMenu() bool COPKGManager::hasOpkgSupport() { - string deps[] = {OPKG_CL, OPKG_KEY, "/etc/opkg/opkg.conf", "/var/lib/opkg"}; + string deps[] = {"/etc/opkg/opkg.conf", "/var/lib/opkg", ""}; - for(size_t i=0; i Date: Sun, 8 Feb 2015 00:25:46 +0100 Subject: [PATCH 11/26] opkg_manager: use my_system to avoid filedescriptor leaks --- src/gui/opkg_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/opkg_manager.cpp b/src/gui/opkg_manager.cpp index 80f1cb38f..959dca1c0 100644 --- a/src/gui/opkg_manager.cpp +++ b/src/gui/opkg_manager.cpp @@ -372,7 +372,7 @@ fprintf(stderr, "execCmd(%s)\n", cmdstr); return res; } else { cmd += " 2>/dev/null >&2"; - int r = system(cmd.c_str()); + int r = my_system(3, "/bin/sh", "-c", cmd.c_str()); if (r == -1) return r; return WEXITSTATUS(r); From 141872565e5740e01e935066aa2e4c7f5097874b Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 12:27:03 +0100 Subject: [PATCH 12/26] hdd_menu: only offer filesystems with kernel support --- src/gui/hdd_menu.cpp | 28 ++++++++++++++++++++++++++++ src/gui/hdd_menu.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/src/gui/hdd_menu.cpp b/src/gui/hdd_menu.cpp index 2062a004a..16837dc46 100644 --- a/src/gui/hdd_menu.cpp +++ b/src/gui/hdd_menu.cpp @@ -215,9 +215,36 @@ std::string CHDDMenuHandler::getFmtType(std::string name, std::string part) return ret; } +void CHDDMenuHandler::check_kernel_fs() +{ + char line[128]; /* /proc/filesystems lines are shorter */ + kernel_fs_list.clear(); + FILE *f = fopen("/proc/filesystems", "r"); + if (! f) { + fprintf(stderr, "CHDDMenuHandler::%s: opening /proc/filesystems failed: %m\n", __func__); + return; + } + while (fgets(line, sizeof(line), f)) { + size_t l = strlen(line); + if (l > 0) + line[l - 1] = 0; /* remove \n */ + char *tab = strchr(line, '\t'); + if (! tab) /* should not happen in any kernel I have seen */ + continue; + tab++; + kernel_fs_list.insert(string(tab)); + } + fclose(f); +} + void CHDDMenuHandler::check_dev_tools() { for (unsigned i = 0; i < FS_MAX; i++) { + if (kernel_fs_list.find(devtools[i].fmt) == kernel_fs_list.end()) { + printf("%s: filesystem '%s' not supported by kernel\n", + __func__, devtools[i].fmt.c_str()); + continue; + } if (!access(devtools[i].fsck.c_str(), X_OK)) devtools[i].fsck_supported = true; if (!access(devtools[i].mkfs.c_str(), X_OK)) @@ -682,6 +709,7 @@ int CHDDMenuHandler::doMenu() show_menu = false; in_menu = true; + check_kernel_fs(); check_dev_tools(); _show_menu: diff --git a/src/gui/hdd_menu.h b/src/gui/hdd_menu.h index 899d0f6e5..2273dc209 100644 --- a/src/gui/hdd_menu.h +++ b/src/gui/hdd_menu.h @@ -64,6 +64,7 @@ class CHDDMenuHandler : public CMenuTarget bool mounted; }; std::vector hdd_list; + std::set kernel_fs_list; struct cmp_hdd_by_name: public binary_function { bool operator() (const struct hdd_s c1, const struct hdd_s c2) @@ -84,6 +85,7 @@ class CHDDMenuHandler : public CMenuTarget bool add_dev(std::string dev, std::string part); bool waitfordev(std::string dev, int maxwait); void check_dev_tools(); + void check_kernel_fs(); devtool_s * get_dev_tool(std::string fmt); int showDeviceMenu(std::string dev); From f607fe5fbef8b1b54e4ee2fcfbc4bc301f090a70 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 13:05:53 +0100 Subject: [PATCH 13/26] helpers: add "backtick" function for shell-like `command` --- src/system/helpers.cpp | 17 +++++++++++++++++ src/system/helpers.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/src/system/helpers.cpp b/src/system/helpers.cpp index d2bf3dc88..4280c0913 100644 --- a/src/system/helpers.cpp +++ b/src/system/helpers.cpp @@ -361,6 +361,23 @@ std::string find_executable(const char *name) return ""; } +std::string backtick(std::string command) +{ + char *buf = NULL; + size_t n = 0; + pid_t pid; + FILE *p = my_popen(pid, command.c_str(), "r"); + if (! p) + return ""; + std::string out = ""; + while (getline(&buf, &n, p) >= 0) + out.append(std::string(buf)); + free(buf); + fclose(p); + waitpid(pid, NULL, 0); + return out; +} + std::string _getPathName(std::string &path, std::string sep) { size_t pos = path.find_last_of(sep); diff --git a/src/system/helpers.h b/src/system/helpers.h index 6726e941a..afa14d132 100644 --- a/src/system/helpers.h +++ b/src/system/helpers.h @@ -55,6 +55,8 @@ bool get_mem_usage(unsigned long &total, unsigned long &free); void mySleep(int sec); std::string find_executable(const char *name); +/* basically what "foo=`command`" does in the shell */ +std::string backtick(std::string command); bool hdd_get_standby(const char * fname); void hdd_flush(const char * fname); From 17395a7fed2cc12a20fe239726fcd417aa8a301a Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 13:07:51 +0100 Subject: [PATCH 14/26] hdd_menu: also recognize recordingdir if it is a symlink ...like "/media/by-label/foo/movies", no need to reset configuration in that case --- src/gui/hdd_menu.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/gui/hdd_menu.cpp b/src/gui/hdd_menu.cpp index 16837dc46..9c9bbb1bc 100644 --- a/src/gui/hdd_menu.cpp +++ b/src/gui/hdd_menu.cpp @@ -390,6 +390,14 @@ void CHDDMenuHandler::setRecordPath(std::string &dev) printf("CHDDMenuHandler::setRecordPath: recordingdir already set to %s\n", newpath.c_str()); return; } + /* don't annoy if the recordingdir is a symlink pointing to the 'right' location */ + string readl = backtick("readlink -f " + g_settings.network_nfs_recordingdir); + readl = trim(readl); + if (newpath.compare(readl) == 0) { + printf("CHDDMenuHandler::%s: recordingdir is a symlink to %s\n", + __func__, newpath.c_str()); + return; + } bool old_menu = in_menu; in_menu = false; int res = ShowMsg(LOCALE_RECORDINGMENU_DEFDIR, LOCALE_HDD_SET_RECDIR, CMessageBox::mbrNo, CMessageBox::mbYes | CMessageBox::mbNo); From 415e7351e104bcec9367ba6f64b4aff66b957275 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 15:11:37 +0100 Subject: [PATCH 15/26] hdd_menu: fix is_mounted for device links It is possible to mount e.g. '/dev/disk/by-label/ext_drive', but is_mounted did not handle this case. Fix that. --- src/gui/hdd_menu.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/gui/hdd_menu.cpp b/src/gui/hdd_menu.cpp index 9c9bbb1bc..6437e1238 100644 --- a/src/gui/hdd_menu.cpp +++ b/src/gui/hdd_menu.cpp @@ -138,14 +138,25 @@ bool CHDDMenuHandler::is_mounted(const char *dev) else snprintf(devpath, sizeof(devpath), "/dev/%s", dev); - int devpathlen = strlen(devpath); char buffer[255]; + string realdev = backtick("readlink -f " + string(devpath)); + realdev = trim(realdev); FILE *f = fopen("/proc/mounts", "r"); if(f) { - while (!res && fgets(buffer, sizeof(buffer), f)) - if (!strncmp(buffer, devpath, devpathlen) - && (buffer[devpathlen] == ' ' || buffer[devpathlen] == '\t')) + while (!res && fgets(buffer, sizeof(buffer), f)) { + if (buffer[0] != '/') + continue; /* only "real" devices are interesting */ + char *p = strchr(buffer, ' '); + if (p) + *p = 0; /* terminate at first space, kernel-user ABI is fixed */ + if (!strcmp(buffer, devpath)) /* default '/dev/sda1' mount */ res = true; + else { /* now the case of '/dev/disk/by-label/myharddrive' mounts */ + string realmount = backtick("readlink -f " + string(buffer)); + if (realdev == trim(realmount)) + res = true; + } + } fclose(f); } printf("CHDDMenuHandler::is_mounted: dev [%s] is %s\n", devpath, res ? "mounted" : "not mounted"); From f7bb7a70cbe6c096fc45fed9a8936c39d7e8e30e Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 15:22:15 +0100 Subject: [PATCH 16/26] hdd_menu: do not handle the rootfs or fs without kernel support --- src/gui/hdd_menu.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/gui/hdd_menu.cpp b/src/gui/hdd_menu.cpp index 6437e1238..3a600da77 100644 --- a/src/gui/hdd_menu.cpp +++ b/src/gui/hdd_menu.cpp @@ -776,9 +776,11 @@ _show_menu: } if (!hdd_list.empty()) { - struct stat rec_st; + struct stat rec_st, root_st, dev_st; memset(&rec_st, 0, sizeof(rec_st)); + memset(&root_st, 0, sizeof(root_st)); stat(g_settings.network_nfs_recordingdir.c_str(), &rec_st); + stat("/", &root_st); sort(hdd_list.begin(), hdd_list.end(), cmp_hdd_by_name()); mount = g_Locale->getText(LOCALE_HDD_MOUNT); @@ -794,6 +796,13 @@ _show_menu: } std::string key = "m" + it->devname; bool enabled = !rec_icon || !CNeutrinoApp::getInstance()->recordingstatus; + /* do not allow to unmount the rootfs, and skip filesystems without kernel support */ + memset(&dev_st, 0, sizeof(dev_st)); + if (stat(("/dev/" + it->devname).c_str(), &dev_st) != -1 + && dev_st.st_rdev == root_st.st_dev) + enabled = false; + else if (kernel_fs_list.find(it->fmt) == kernel_fs_list.end()) + enabled = false; it->cmf = new CMenuForwarder(it->desc, enabled, it->mounted ? umount : mount , this, key.c_str(), CRCInput::convertDigitToKey(shortcut++), NULL, rec_icon); hddmenu->addItem(it->cmf); From 6e9496b18f9bf348730639c8639b79fc933abcf0 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 17:33:25 +0100 Subject: [PATCH 17/26] fix parentallock for "bouquets default locked" case in case of "default locked" bouquets, the "whole bouquet unlock" did not work, because of the inverted logic in this case --- src/gui/channellist.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index 2451af450..fb454cc61 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -2,7 +2,7 @@ Neutrino-GUI - DBoxII-Project Copyright (C) 2001 Steffen Hehn 'McClean' - Copyright (C) 2007-2012 Stefan Seyfried + Copyright (C) 2007-2015 Stefan Seyfried Kommentar: @@ -1048,7 +1048,8 @@ int CChannelList::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data, (*chanlist)[selected]->last_unlocked_time = time_monotonic(); int bnum = bouquetList->getActiveBouquetNumber(); /* unlock only real locked bouquet, not whole satellite or all channels! */ - if (bnum >= 0 && bouquetList->Bouquets[bnum]->zapitBouquet && bouquetList->Bouquets[bnum]->zapitBouquet->bLocked) + if (bnum >= 0 && bouquetList->Bouquets[bnum]->zapitBouquet && + bouquetList->Bouquets[bnum]->zapitBouquet->bLocked != g_settings.parentallock_defaultlocked) { /* unlock the whole bouquet */ int i; From dc637ca68ea586564df5c8b5c1b617531bbd4477 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 17:35:01 +0100 Subject: [PATCH 18/26] channellist: fix 2 forgotten cases of fixed plock_zaptime --- src/gui/channellist.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/channellist.cpp b/src/gui/channellist.cpp index fb454cc61..0e867b3c2 100644 --- a/src/gui/channellist.cpp +++ b/src/gui/channellist.cpp @@ -343,16 +343,17 @@ int CChannelList::doChannelMenu(void) switch(select) { case 0: // edit mode if (g_settings.parentallock_prompt == PARENTALLOCK_PROMPT_CHANGETOLOCKED) { + int pl_z = g_settings.parentallock_zaptime * 60; if (g_settings.personalize[SNeutrinoSettings::P_MSER_BOUQUET_EDIT] == CPersonalizeGui::PERSONALIZE_MODE_PIN) { unlocked = false; } else if (bouquet && bouquet->zapitBouquet && bouquet->zapitBouquet->bLocked) { /* on locked bouquet, enough to check any channel */ - unlocked = ((*chanlist)[selected]->last_unlocked_time + 3600 > time_monotonic()); + unlocked = ((*chanlist)[selected]->last_unlocked_time + pl_z > time_monotonic()); } else { /* check all locked channels for last_unlocked_time, overwrite only if already unlocked */ for (unsigned int j = 0 ; j < (*chanlist).size(); j++) { if ((*chanlist)[j]->bLocked) - unlocked = unlocked && ((*chanlist)[j]->last_unlocked_time + 3600 > time_monotonic()); + unlocked = unlocked && ((*chanlist)[j]->last_unlocked_time + pl_z > time_monotonic()); } } if (!unlocked) { From d411f6d996dfaf39263361c1aefd4ff0f0252551 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 8 Feb 2015 00:55:44 +0100 Subject: [PATCH 19/26] hdd_menu: my_popen() needs waitpid to avoid zombies --- src/gui/hdd_menu.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/hdd_menu.cpp b/src/gui/hdd_menu.cpp index 3a600da77..2b6a21c83 100644 --- a/src/gui/hdd_menu.cpp +++ b/src/gui/hdd_menu.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -202,6 +203,7 @@ void CHDDMenuHandler::getBlkIds() hdd_list.push_back(hdd); } fclose(f); + waitpid(pid, NULL, 0); /* beware of the zombie apocalypse! */ } std::string CHDDMenuHandler::getDefaultPart(std::string dev) From c00befb0e63b9064fb06be6f6e16627991459a99 Mon Sep 17 00:00:00 2001 From: "[CST] Focus" Date: Fri, 6 Feb 2015 14:00:07 +0300 Subject: [PATCH 20/26] rcsim.c: use event dev on cst, too --- src/rcsim.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/rcsim.c b/src/rcsim.c index c274f6c4b..2ae56a39c 100644 --- a/src/rcsim.c +++ b/src/rcsim.c @@ -39,8 +39,10 @@ /* if you want use HAVE_XX_HARDWARE, better include config.h :-) */ #include "config.h" -#ifdef HAVE_DBOX_HARDWARE +#if defined(HAVE_DBOX_HARDWARE) #define EVENTDEV "/dev/input/event0" +#elif defined (HAVE_COOL_HARDWARE) +#define EVENTDEV "/dev/input/input0" #else /* dreambox and tripledragon do not use a "normal" input device, so we cannot (ab-)use the event repeating function of it. use the neutrino socket instead. */ @@ -73,7 +75,7 @@ enum initiators void usage(char *n){ unsigned int keynum = sizeof(keyname)/sizeof(struct key); unsigned int i; -#ifdef HAVE_DBOX_HARDWARE +#if defined (EVENTDEV) printf ("rcsim v1.1\nUsage: %s [