diff --git a/configure.ac b/configure.ac
index eb5e2f2a9..eacab6cba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -228,8 +228,10 @@ fi
# hack to define a short filename also for out-of-tree build
if test `dirname $0` = `pwd`; then
HWLIB_CFLAGS="$HWLIB_CFLAGS "'-D__file__=__FILE__'
+ HWLIB_CFLAGS="$HWLIB_CFLAGS "'-D__path_file__=__FILE__'
else
HWLIB_CFLAGS="$HWLIB_CFLAGS "'-D__file__="\"$(subst $(srcdir)/,,$(abspath $<))\""'
+ HWLIB_CFLAGS="$HWLIB_CFLAGS "'-D__path_file__="\"$(subst $(top_srcdir)/,,$(abspath $<))\""'
fi
#
# Check for libtdservicedb - the new one - for testing only
diff --git a/src/gui/lua/Makefile.am b/src/gui/lua/Makefile.am
index e3861cb76..05a3b91a8 100644
--- a/src/gui/lua/Makefile.am
+++ b/src/gui/lua/Makefile.am
@@ -32,10 +32,12 @@ libneutrino_gui_lua_a_SOURCES = \
lua_cc_window.cpp \
lua_configfile.cpp \
lua_curl.cpp \
+ lua_filehelpers.cpp \
lua_hintbox.cpp \
lua_menue.cpp \
lua_messagebox.cpp \
lua_misc.cpp \
+ lua_stringinput.cpp \
lua_threads.cpp \
lua_threads_copy.cpp \
lua_threads_functions.cpp \
diff --git a/src/gui/lua/lua_api_version.h b/src/gui/lua/lua_api_version.h
index dd5ac6fa7..b5e974561 100644
--- a/src/gui/lua/lua_api_version.h
+++ b/src/gui/lua/lua_api_version.h
@@ -4,4 +4,4 @@
* to luainstance.h changes
*/
#define LUA_API_VERSION_MAJOR 1
-#define LUA_API_VERSION_MINOR 47
+#define LUA_API_VERSION_MINOR 56
diff --git a/src/gui/lua/lua_filehelpers.cpp b/src/gui/lua/lua_filehelpers.cpp
new file mode 100644
index 000000000..c8d1cd252
--- /dev/null
+++ b/src/gui/lua/lua_filehelpers.cpp
@@ -0,0 +1,474 @@
+/*
+ * lua file helpers functions
+ *
+ * (C) 2016 M. Liebmann (micha-bbg)
+ *
+ * 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 2
+ * 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
+#include
+
+#include
+#include
+#include
+#include
+
+#include "luainstance.h"
+#include "lua_filehelpers.h"
+
+CLuaInstFileHelpers* CLuaInstFileHelpers::getInstance()
+{
+ static CLuaInstFileHelpers* LuaInstFileHelpers = NULL;
+
+ if (!LuaInstFileHelpers)
+ LuaInstFileHelpers = new CLuaInstFileHelpers();
+ return LuaInstFileHelpers;
+}
+
+CLuaFileHelpers *CLuaInstFileHelpers::FileHelpersCheckData(lua_State *L, int n)
+{
+ return *(CLuaFileHelpers **) luaL_checkudata(L, n, LUA_FILEHELPER_CLASSNAME);
+}
+
+void CLuaInstFileHelpers::LuaFileHelpersRegister(lua_State *L)
+{
+ luaL_Reg meth[] = {
+ { "new", CLuaInstFileHelpers::FileHelpersNew },
+ { "cp", CLuaInstFileHelpers::FileHelpersCp },
+ { "chmod", CLuaInstFileHelpers::FileHelpersChmod },
+ { "touch", CLuaInstFileHelpers::FileHelpersTouch },
+ { "rmdir", CLuaInstFileHelpers::FileHelpersRmdir },
+ { "mkdir", CLuaInstFileHelpers::FileHelpersMkdir },
+ { "readlink", CLuaInstFileHelpers::FileHelpersReadlink },
+ { "ln", CLuaInstFileHelpers::FileHelpersLn },
+ { "exist", CLuaInstFileHelpers::FileHelpersExist },
+ { "__gc", CLuaInstFileHelpers::FileHelpersDelete },
+ { NULL, NULL }
+ };
+
+ luaL_newmetatable(L, LUA_FILEHELPER_CLASSNAME);
+ luaL_setfuncs(L, meth, 0);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -1, "__index");
+ lua_setglobal(L, LUA_FILEHELPER_CLASSNAME);
+}
+
+int CLuaInstFileHelpers::FileHelpersNew(lua_State *L)
+{
+ CLuaFileHelpers **udata = (CLuaFileHelpers **) lua_newuserdata(L, sizeof(CLuaFileHelpers *));
+ *udata = new CLuaFileHelpers();
+ luaL_getmetatable(L, LUA_FILEHELPER_CLASSNAME);
+ lua_setmetatable(L, -2);
+ return 1;
+}
+
+int CLuaInstFileHelpers::FileHelpersCp(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+
+ int numargs = lua_gettop(L) - 1;
+ int min_numargs = 2;
+ if (numargs < min_numargs) {
+ printf("luascript cp: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ if (!lua_isstring(L, 2)) {
+ printf("luascript cp: argument 1 is not a string.\n");
+ lua_pushboolean(L, false);
+ return 1;
+ }
+ const char *from = "";
+ from = luaL_checkstring(L, 2);
+
+ if (!lua_isstring(L, 3)) {
+ printf("luascript cp: argument 2 is not a string.\n");
+ lua_pushboolean(L, false);
+ return 1;
+ }
+ const char *to = "";
+ to = luaL_checkstring(L, 3);
+
+ const char *flags = "";
+ if (numargs > min_numargs)
+ flags = luaL_checkstring(L, 4);
+
+ bool ret = false;
+ CFileHelpers fh;
+ fh.setConsoleQuiet(true);
+ ret = fh.cp(from, to, flags);
+ if (ret == false) {
+ helpersDebugInfo di;
+ fh.readDebugInfo(&di);
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, di.msg.c_str(), di.file.c_str(), di.line);
+ }
+
+ lua_pushboolean(L, ret);
+ return 1;
+}
+
+int CLuaInstFileHelpers::FileHelpersChmod(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+
+ int numargs = lua_gettop(L) - 1;
+ int min_numargs = 2;
+ if (numargs < min_numargs) {
+ printf("luascript chmod: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ const char *file = "";
+ file = luaL_checkstring(L, 2);
+
+ int mode_i = luaL_checkint(L, 3);
+ /* Hack for convert lua number to octal */
+ std::string mode_s = itoa(mode_i, 10);
+ mode_t mode = (mode_t)(strtol(mode_s.c_str(), (char **)NULL, 8) & 0x0FFF);
+ //printf("\n##### [%s:%d] str: %s, okt: %o \n \n", __func__, __LINE__, mode_s.c_str(), (int)mode);
+
+ bool ret = true;
+ if (chmod(file, mode) != 0) {
+ ret = false;
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ const char* s = strerror(errno);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, s, __path_file__, __LINE__);
+ }
+
+ lua_pushboolean(L, ret);
+ return 1;
+}
+
+int CLuaInstFileHelpers::FileHelpersTouch(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+
+ int numargs = lua_gettop(L) - 1;
+ int min_numargs = 1;
+ if (numargs < min_numargs) {
+ printf("luascript touch: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ const char *file = "";
+ file = luaL_checkstring(L, 2);
+
+ bool ret = true;
+ lua_Debug ar;
+
+ if (!file_exists(file)) {
+ FILE *f = fopen(file, "w");
+ if (f == NULL) {
+ ret = false;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ const char* s = strerror(errno);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, s, __path_file__, __LINE__);
+ lua_pushboolean(L, ret);
+ return 1;
+ }
+ fclose(f);
+ if (numargs == min_numargs) {
+ lua_pushboolean(L, ret);
+ return 1;
+ }
+ }
+
+ time_t modTime;
+ if (numargs == min_numargs)
+ /* current time */
+ modTime = time(NULL);
+ else
+ /* new time */
+ modTime = (time_t)luaL_checkint(L, 3);
+
+ utimbuf utb;
+ utb.actime = modTime;
+ utb.modtime = modTime;
+ if (utime(file, &utb) != 0) {
+ ret = false;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ const char* s = strerror(errno);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, s, __path_file__, __LINE__);
+ }
+
+ lua_pushboolean(L, ret);
+ return 1;
+}
+
+int CLuaInstFileHelpers::FileHelpersRmdir(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+
+ int numargs = lua_gettop(L) - 1;
+ int min_numargs = 1;
+ if (numargs < min_numargs) {
+ printf("luascript rmdir: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ const char *dir = "";
+ dir = luaL_checkstring(L, 2);
+
+ bool ret = false;
+ CFileHelpers* fh = CFileHelpers::getInstance();
+ fh->setConsoleQuiet(true);
+ ret = fh->removeDir(dir);
+ if (ret == false) {
+ helpersDebugInfo di;
+ fh->readDebugInfo(&di);
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, di.msg.c_str(), di.file.c_str(), di.line);
+ }
+
+ lua_pushboolean(L, ret);
+ return 1;
+}
+
+int CLuaInstFileHelpers::FileHelpersMkdir(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+
+ int numargs = lua_gettop(L) - 1;
+ int min_numargs = 1;
+ if (numargs < min_numargs) {
+ printf("luascript mkdir: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ const char *dir = "";
+ dir = luaL_checkstring(L, 2);
+
+ mode_t mode = 0755;
+ if (numargs > min_numargs) {
+ int mode_i = luaL_checkint(L, 3);
+ /* Hack for convert lua number to octal */
+ std::string mode_s = itoa(mode_i, 10);
+ mode = (mode_t)(strtol(mode_s.c_str(), (char **)NULL, 8) & 0x0FFF);
+ //printf("\n##### [%s:%d] str: %s, okt: %o \n \n", __func__, __LINE__, mode_s.c_str(), (int)mode);
+ }
+
+ bool ret = false;
+ CFileHelpers* fh = CFileHelpers::getInstance();
+ fh->setConsoleQuiet(true);
+ ret = fh->createDir(dir, mode);
+ if (ret == false) {
+ helpersDebugInfo di;
+ fh->readDebugInfo(&di);
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, di.msg.c_str(), di.file.c_str(), di.line);
+ }
+
+ lua_pushboolean(L, ret);
+ return 1;
+}
+
+int CLuaInstFileHelpers::FileHelpersReadlink(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+
+ int numargs = lua_gettop(L) - 1;
+ int min_numargs = 1;
+ if (numargs < min_numargs) {
+ printf("luascript readlink: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
+ lua_pushnil(L);
+ return 1;
+ }
+
+ const char *link = "";
+ link = luaL_checkstring(L, 2);
+
+ char buf[PATH_MAX];
+ memset(buf, '\0', sizeof(buf));
+ if (readlink(link, buf, sizeof(buf)-1) == -1) {
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ const char* s = strerror(errno);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, s, __path_file__, __LINE__);
+
+ lua_pushnil(L);
+ return 1;
+ }
+
+ lua_pushstring(L, buf);
+ return 1;
+}
+
+int CLuaInstFileHelpers::FileHelpersLn(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+
+ int numargs = lua_gettop(L) - 1;
+ int min_numargs = 2;
+ if (numargs < min_numargs) {
+ printf("luascript ln: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ const char *src = "";
+ src = luaL_checkstring(L, 2);
+ const char *link = "";
+ link = luaL_checkstring(L, 3);
+
+ const char *flags = "";
+ if (numargs > min_numargs)
+ flags = luaL_checkstring(L, 4);
+
+ bool symlnk = (strchr(flags, 's') != NULL);
+ bool force = (strchr(flags, 'f') != NULL);
+ lua_Debug ar;
+
+ if (!symlnk) {
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ const char* s = "Currently only supports symlinks.";
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, s, __path_file__, __LINE__);
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
+ bool ret = true;
+ if (symlink(src, link) != 0) {
+ if (force && (errno == EEXIST)) {
+ if (unlink(link) == 0) {
+ if (symlink(src, link) == 0) {
+ lua_pushboolean(L, ret);
+ return 1;
+ }
+ }
+ }
+ ret = false;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ const char* s = strerror(errno);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, s, __path_file__, __LINE__);
+
+ }
+
+ lua_pushboolean(L, ret);
+ return 1;
+}
+
+int CLuaInstFileHelpers::FileHelpersExist(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+
+ int numargs = lua_gettop(L) - 1;
+ int min_numargs = 2;
+ if (numargs < min_numargs) {
+ printf("luascript exist: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
+ lua_pushnil(L);
+ return 1;
+ }
+
+ bool ret = false;
+ bool err = false;
+ int errLine = 0;
+ std::string errMsg = "";
+
+ const char *file = "";
+ file = luaL_checkstring(L, 2);
+ const char *flag = "";
+ flag = luaL_checkstring(L, 3);
+
+ if (file_exists(file)) {
+ struct stat FileInfo;
+ if (lstat(file, &FileInfo) == -1) {
+ err = true;
+ errLine = __LINE__;
+ errMsg = (std::string)strerror(errno);
+ }
+ else if (strchr(flag, 'f') != NULL) {
+ if (S_ISREG(FileInfo.st_mode))
+ ret = true;
+ }
+ else if (strchr(flag, 'l') != NULL) {
+ if (S_ISLNK(FileInfo.st_mode))
+ ret = true;
+ }
+ else if (strchr(flag, 'd') != NULL) {
+ if (S_ISDIR(FileInfo.st_mode))
+ ret = true;
+ }
+ else {
+ err = true;
+ errLine = __LINE__;
+ errMsg = (strlen(flag) == 0) ? "no" : "unknown";
+ errMsg += " flag given.";
+ }
+ }
+
+ if (err) {
+ lua_Debug ar;
+ lua_getstack(L, 1, &ar);
+ lua_getinfo(L, "Sl", &ar);
+ printf(">>> Lua script error [%s:%d] %s\n (error from neutrino: [%s:%d])\n",
+ ar.short_src, ar.currentline, errMsg.c_str(), __path_file__, errLine);
+ lua_pushnil(L);
+ return 1;
+ }
+
+ lua_pushboolean(L, ret);
+ return 1;
+}
+
+
+int CLuaInstFileHelpers::FileHelpersDelete(lua_State *L)
+{
+ CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
+ if (!D) return 0;
+ delete D;
+ return 0;
+}
diff --git a/src/gui/lua/lua_filehelpers.h b/src/gui/lua/lua_filehelpers.h
new file mode 100644
index 000000000..853f9768e
--- /dev/null
+++ b/src/gui/lua/lua_filehelpers.h
@@ -0,0 +1,53 @@
+/*
+ * lua file helpers functions
+ *
+ * (C) 2016 M. Liebmann (micha-bbg)
+ *
+ * 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 2
+ * 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 .
+ */
+
+#ifndef _LUAFILEHELPERS_H
+#define _LUAFILEHELPERS_H
+
+class CLuaFileHelpers
+{
+ public:
+ CLuaFileHelpers() {};
+ ~CLuaFileHelpers() {};
+};
+
+class CLuaInstFileHelpers
+{
+ public:
+
+ CLuaInstFileHelpers() {};
+ ~CLuaInstFileHelpers() {};
+ static CLuaInstFileHelpers* getInstance();
+ static void LuaFileHelpersRegister(lua_State *L);
+
+ private:
+ static CLuaFileHelpers *FileHelpersCheckData(lua_State *L, int n);
+ static int FileHelpersNew(lua_State *L);
+ static int FileHelpersCp(lua_State *L);
+ static int FileHelpersChmod(lua_State *L);
+ static int FileHelpersTouch(lua_State *L);
+ static int FileHelpersRmdir(lua_State *L);
+ static int FileHelpersMkdir(lua_State *L);
+ static int FileHelpersReadlink(lua_State *L);
+ static int FileHelpersLn(lua_State *L);
+ static int FileHelpersExist(lua_State *L);
+ static int FileHelpersDelete(lua_State *L);
+};
+
+#endif //_LUAFILEHELPERS_H
diff --git a/src/gui/lua/lua_stringinput.cpp b/src/gui/lua/lua_stringinput.cpp
new file mode 100644
index 000000000..e61264b50
--- /dev/null
+++ b/src/gui/lua/lua_stringinput.cpp
@@ -0,0 +1,106 @@
+/*
+ * lua stringinput
+ *
+ * (C) 2016 Sven Hoefer (svenhoefer)
+ * (C) 2016 M. Liebmann (micha-bbg)
+ *
+ * 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 2
+ * 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
+#include
+#include
+
+#include "luainstance.h"
+#include "lua_stringinput.h"
+
+CLuaInstStringInput* CLuaInstStringInput::getInstance()
+{
+ static CLuaInstStringInput* LuaInstStringInput = NULL;
+
+ if (!LuaInstStringInput)
+ LuaInstStringInput = new CLuaInstStringInput();
+ return LuaInstStringInput;
+}
+
+void CLuaInstStringInput::StringInputRegister(lua_State *L)
+{
+ luaL_Reg meth[] = {
+ { "exec", CLuaInstStringInput::StringInputExec },
+ { NULL, NULL }
+ };
+
+ luaL_newmetatable(L, "stringinput");
+ luaL_setfuncs(L, meth, 0);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -1, "__index");
+ lua_setglobal(L, "stringinput");
+}
+
+/*
+ local return_value = stringinput.exec{
+ caption="Title",
+ value="value",
+ icon="settings",
+ valid_chars="0123456789",
+ size=4
+ }
+*/
+int CLuaInstStringInput::StringInputExec(lua_State *L)
+{
+ lua_assert(lua_istable(L,1));
+
+ std::string name;
+ tableLookup(L, "name", name) || tableLookup(L, "title", name) || tableLookup(L, "caption", name);
+
+ std::string value;
+ tableLookup(L, "value", value);
+
+ lua_Integer size = 30;
+ tableLookup(L, "size", size);
+
+ // TODO: Locales?
+
+ std::string valid_chars = "abcdefghijklmnopqrstuvwxyz0123456789!\"§$%&/()=?-.@,_: ";
+ tableLookup(L, "valid_chars", valid_chars);
+
+ // TODO: CChangeObserver?
+
+ std::string icon = std::string(NEUTRINO_ICON_INFO);
+ tableLookup(L, "icon", icon);
+
+ lua_Integer sms = 0;
+ tableLookup(L, "sms", sms);
+
+ CStringInput *i;
+ if (sms)
+ i = new CStringInputSMS(name, &value, size,
+ NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, valid_chars.c_str(), NULL, icon.c_str());
+ else
+ i = new CStringInput(name, &value, size,
+ NONEXISTANT_LOCALE, NONEXISTANT_LOCALE, valid_chars.c_str(), NULL, icon.c_str());
+ i->exec(NULL, "");
+ delete i;
+
+ lua_pushstring(L, value.c_str());
+
+ return 1;
+}
diff --git a/src/gui/lua/lua_stringinput.h b/src/gui/lua/lua_stringinput.h
new file mode 100644
index 000000000..c49ad7dc0
--- /dev/null
+++ b/src/gui/lua/lua_stringinput.h
@@ -0,0 +1,44 @@
+/*
+ * lua stringinput
+ *
+ * (C) 2016 Sven Hoefer (svenhoefer)
+ * (C) 2016 M. Liebmann (micha-bbg)
+ *
+ * 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 2
+ * 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 .
+ */
+
+#ifndef _LUASTRINGINPUT_H
+#define _LUASTRINGINPUT_H
+
+class CLuaStringInput
+{
+ public:
+ CStringInput *b;
+ CLuaStringInput();
+ ~CLuaStringInput();
+};
+
+class CLuaInstStringInput
+{
+ public:
+ CLuaInstStringInput() {};
+ ~CLuaInstStringInput() {};
+ static CLuaInstStringInput* getInstance();
+ static void StringInputRegister(lua_State *L);
+
+ private:
+ static int StringInputExec(lua_State *L);
+};
+
+#endif //_LUASTRINGINPUT_H
diff --git a/src/gui/lua/luainstance.cpp b/src/gui/lua/luainstance.cpp
index d5de296b6..a21cac683 100644
--- a/src/gui/lua/luainstance.cpp
+++ b/src/gui/lua/luainstance.cpp
@@ -44,10 +44,12 @@
#include "lua_cc_window.h"
#include "lua_configfile.h"
#include "lua_curl.h"
+#include "lua_filehelpers.h"
#include "lua_hintbox.h"
#include "lua_menue.h"
#include "lua_messagebox.h"
#include "lua_misc.h"
+#include "lua_stringinput.h"
#include "lua_threads.h"
#include "lua_video.h"
@@ -621,9 +623,11 @@ void LuaInstRegisterFunctions(lua_State *L, bool fromThreads/*=false*/)
CLuaInstCCWindow::getInstance()->CCWindowRegister(L);
CLuaInstConfigFile::getInstance()->LuaConfigFileRegister(L);
CLuaInstCurl::getInstance()->LuaCurlRegister(L);
+ CLuaInstFileHelpers::getInstance()->LuaFileHelpersRegister(L);
CLuaInstHintbox::getInstance()->HintboxRegister(L);
CLuaInstMenu::getInstance()->MenuRegister(L);
CLuaInstMessagebox::getInstance()->MessageboxRegister(L);
+ CLuaInstStringInput::getInstance()->StringInputRegister(L);
CLuaInstMisc::getInstance()->LuaMiscRegister(L);
CLuaInstVideo::getInstance()->LuaVideoRegister(L);
if (!fromThreads)
diff --git a/src/gui/lua/luainstance_helpers.h b/src/gui/lua/luainstance_helpers.h
index cf6b9ba30..fa54bb690 100644
--- a/src/gui/lua/luainstance_helpers.h
+++ b/src/gui/lua/luainstance_helpers.h
@@ -2,7 +2,7 @@
* lua instance helper functions
*
* (C) 2013 Stefan Seyfried (seife)
- * (C) 2014-2015 M. Liebmann (micha-bbg)
+ * (C) 2014-2016 M. Liebmann (micha-bbg)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,6 +30,7 @@
#define LUA_MISC_CLASSNAME "misc"
#define LUA_CURL_CLASSNAME "curl"
#define LUA_HEADER_CLASSNAME "header"
+#define LUA_FILEHELPER_CLASSNAME "filehelpers"
#define LUA_WIKI "https://wiki.neutrino-hd.de/wiki"
//#define LUA_WIKI "https://wiki.slknet.de/wiki"
diff --git a/src/system/helpers.cpp b/src/system/helpers.cpp
index 266ffbf14..c9d736c85 100644
--- a/src/system/helpers.cpp
+++ b/src/system/helpers.cpp
@@ -667,6 +667,8 @@ CFileHelpers::CFileHelpers()
FileBufSize = 0xFFFF;
FileBuf = new char[FileBufSize];
doCopyFlag = true;
+ ConsoleQuiet = false;
+ clearDebugInfo();
}
CFileHelpers::~CFileHelpers()
@@ -683,12 +685,188 @@ CFileHelpers* CFileHelpers::getInstance()
return FileHelpers;
}
-bool CFileHelpers::copyFile(const char *Src, const char *Dst, mode_t mode)
+void CFileHelpers::clearDebugInfo()
+{
+ DebugInfo.msg.clear();
+ DebugInfo.file.clear();
+ DebugInfo.func.clear();
+ DebugInfo.line = 0;
+}
+
+void CFileHelpers::setDebugInfo(const char* msg, const char* file, const char* func, int line)
+{
+ DebugInfo.msg = msg;
+ DebugInfo.file = file;
+ DebugInfo.func = func;
+ DebugInfo.line = line;
+}
+
+void CFileHelpers::readDebugInfo(helpersDebugInfo* di)
+{
+ di->msg = DebugInfo.msg;
+ di->file = DebugInfo.file;
+ di->func = DebugInfo.func;
+ di->line = DebugInfo.line;
+}
+
+void CFileHelpers::printDebugInfo()
+{
+ if (!ConsoleQuiet)
+ printf(">>>> [%s:%d] %s\n", DebugInfo.func.c_str(), DebugInfo.line, DebugInfo.msg.c_str());
+}
+
+bool CFileHelpers::cp(const char *Src, const char *Dst, const char *Flags/*=""*/)
+{
+ clearDebugInfo();
+ if ((Src == NULL) || (Dst == NULL)) {
+ setDebugInfo("One or more parameters are NULL", __path_file__, __func__, __LINE__);
+ printDebugInfo();
+ return false;
+ }
+
+ std::string src = Src;
+ src = trim(src);
+ if (src.find_first_of("/") != 0)
+ src = "./" + src;
+ size_t pos = src.find_last_of("/");
+ if (pos == src.length()-1)
+ src = src.substr(0, pos);
+
+ std::string dst = Dst;
+ dst = trim(dst);
+ if (dst.find_first_of("/") != 0)
+ dst = "./" + dst;
+ pos = dst.find_last_of("/");
+ if (pos == dst.length()-1)
+ dst = dst.substr(0, pos);
+
+ bool wildcards = (src.find("*") != std::string::npos);
+ bool recursive = ((strchr(Flags, 'r') != NULL) || (strchr(Flags, 'a') != NULL));
+ bool no_dereference = ((strchr(Flags, 'd') != NULL) || (strchr(Flags, 'a') != NULL));
+
+ static struct stat FileInfo;
+ char buf[PATH_MAX];
+ if (wildcards == false) {
+ if (!file_exists(src.c_str())) {
+ setDebugInfo("Source file not exist", __path_file__, __func__, __LINE__);
+ printDebugInfo();
+ return false;
+ }
+ if (lstat(src.c_str(), &FileInfo) == -1) {
+ setDebugInfo("lstat error", __path_file__, __func__, __LINE__);
+ printDebugInfo();
+ return false;
+ }
+
+ pos = src.find_last_of("/");
+ std::string fname = src.substr(pos);
+
+ static struct stat FileInfo2;
+ // is symlink
+ if (S_ISLNK(FileInfo.st_mode)) {
+ int len = readlink(src.c_str(), buf, sizeof(buf)-1);
+ if (len != -1) {
+ buf[len] = '\0';
+ if (!no_dereference) { /* copy */
+ std::string buf_ = (std::string)buf;
+ char buf2[PATH_MAX + 1];
+ if (buf[0] != '/')
+ buf_ = getPathName(src) + "/" + buf_;
+ buf_ = (std::string)realpath(buf_.c_str(), buf2);
+ //printf("\n>>>> RealPath: %s\n \n", buf_.c_str());
+ if (file_exists(dst.c_str()) && (lstat(dst.c_str(), &FileInfo2) != -1)){
+ if (S_ISDIR(FileInfo2.st_mode))
+ copyFile(buf_.c_str(), (dst + fname).c_str());
+ else {
+ unlink(dst.c_str());
+ copyFile(buf_.c_str(), dst.c_str());
+ }
+ }
+ else
+ copyFile(buf_.c_str(), dst.c_str());
+ }
+ else { /* link */
+ if (file_exists(dst.c_str()) && (lstat(dst.c_str(), &FileInfo2) != -1)){
+ if (S_ISDIR(FileInfo2.st_mode))
+ symlink(buf, (dst + fname).c_str());
+ else {
+ unlink(dst.c_str());
+ symlink(buf, dst.c_str());
+ }
+ }
+ else
+ symlink(buf, dst.c_str());
+ }
+ }
+ }
+ // is directory
+ else if (S_ISDIR(FileInfo.st_mode)) {
+ if (recursive)
+ copyDir(src.c_str(), dst.c_str());
+ else {
+ setDebugInfo("'recursive flag' must be set to copy dir.", __path_file__, __func__, __LINE__);
+ printDebugInfo();
+ return false;
+ }
+ }
+ // is file
+ else if (S_ISREG(FileInfo.st_mode)) {
+ if (file_exists(dst.c_str()) && (lstat(dst.c_str(), &FileInfo2) != -1)){
+ if (S_ISDIR(FileInfo2.st_mode))
+ copyFile(src.c_str(), (dst + fname).c_str());
+ else {
+ unlink(dst.c_str());
+ copyFile(src.c_str(), dst.c_str());
+ }
+ }
+ else
+ copyFile(src.c_str(), dst.c_str());
+ }
+ else {
+ setDebugInfo("Currently unsupported st_mode.", __path_file__, __func__, __LINE__);
+ printDebugInfo();
+ return false;
+ }
+ }
+ else {
+ setDebugInfo("Wildcard feature not yet realized.", __path_file__, __func__, __LINE__);
+ printDebugInfo();
+ return false;
+ }
+
+ return true;
+}
+
+bool CFileHelpers::copyFile(const char *Src, const char *Dst, mode_t forceMode/*=0*/)
{
doCopyFlag = true;
- unlink(Dst);
+
+ /*
+ set mode for Dst
+ ----------------
+ when forceMode==0 (default) then
+ when Dst exists
+ mode = mode from Dst
+ else
+ mode = mode from Src
+ else
+ mode = forceMode
+ */
+ mode_t mode = forceMode & 0x0FFF;
+ if (mode == 0) {
+ static struct stat FileInfo;
+ const char *f = Dst;
+ if (!file_exists(Dst))
+ f = Src;
+ if (lstat(f, &FileInfo) == -1)
+ return false;
+ mode = FileInfo.st_mode & 0x0FFF;
+ }
+
if ((fd1 = open(Src, O_RDONLY)) < 0)
return false;
+ if (file_exists(Dst))
+ unlink(Dst);
if ((fd2 = open(Dst, O_WRONLY | O_CREAT, mode)) < 0) {
close(fd1);
return false;
@@ -821,7 +999,7 @@ bool CFileHelpers::copyDir(const char *Src, const char *Dst, bool backupMode)
std::string save = "";
if (backupMode && (CExtUpdate::getInstance()->isBlacklistEntry(srcPath)))
save = ".save";
- copyFile(srcPath, (dstPath + save).c_str(), FileInfo.st_mode & 0x0FFF);
+ copyFile(srcPath, (dstPath + save).c_str()); /* mode is set by copyFile */
}
}
}
@@ -833,6 +1011,8 @@ bool CFileHelpers::copyDir(const char *Src, const char *Dst, bool backupMode)
// false - errno is set
bool CFileHelpers::createDir(string& Dir, mode_t mode)
{
+ CFileHelpers* fh = CFileHelpers::getInstance();
+ fh->clearDebugInfo();
int res = 0;
for(string::iterator iter = Dir.begin() ; iter != Dir.end();) {
string::iterator newIter = find(iter, Dir.end(), '/' );
@@ -846,7 +1026,12 @@ bool CFileHelpers::createDir(string& Dir, mode_t mode)
// We can assume that if an error
// occured, following will fail too,
// so break here.
- dprintf(DEBUG_NORMAL, "[CFileHelpers %s] creating directory %s: %s\n", __func__, newPath.c_str(), strerror(errno));
+ if (!fh->getConsoleQuiet())
+ dprintf(DEBUG_NORMAL, "[CFileHelpers %s] creating directory %s: %s\n", __func__, newPath.c_str(), strerror(errno));
+ char buf[1024];
+ memset(buf, '\0', sizeof(buf));
+ snprintf(buf, sizeof(buf)-1, "creating directory %s: %s", newPath.c_str(), strerror(errno));
+ fh->setDebugInfo(buf, __path_file__, __func__, __LINE__);
break;
}
}
@@ -861,13 +1046,16 @@ bool CFileHelpers::createDir(string& Dir, mode_t mode)
bool CFileHelpers::removeDir(const char *Dir)
{
+ CFileHelpers* fh = CFileHelpers::getInstance();
+ fh->clearDebugInfo();
DIR *dir;
struct dirent *entry;
char path[PATH_MAX];
dir = opendir(Dir);
if (dir == NULL) {
- printf("Error opendir()\n");
+ fh->setDebugInfo("Error opendir().", __path_file__, __func__, __LINE__);
+ fh->printDebugInfo();
return false;
}
while ((entry = readdir(dir)) != NULL) {
@@ -1080,6 +1268,38 @@ std::string to_string(unsigned long long i)
return s.str();
}
+/**
+ * C++ version 0.4 std::string style "itoa":
+ * Contributions from Stuart Lowe, Ray-Yuan Sheu,
+
+ * Rodrigo de Salvo Braz, Luc Gallant, John Maloney
+ * and Brian Hunt
+ */
+std::string itoa(int value, int base)
+{
+ std::string buf;
+
+ // check that the base if valid
+ if (base < 2 || base > 16) return buf;
+
+ enum { kMaxDigits = 35 };
+ buf.reserve( kMaxDigits ); // Pre-allocate enough space.
+
+ int quotient = value;
+
+ // Translating number to string with base:
+ do {
+ buf += "0123456789abcdef"[ std::abs( quotient % base ) ];
+ quotient /= base;
+ } while ( quotient );
+
+ // Append the negative sign
+ if ( value < 0) buf += '-';
+
+ std::reverse( buf.begin(), buf.end() );
+ return buf;
+}
+
std::string getJFFS2MountPoint(int mtdPos)
{
FILE* fd = fopen("/proc/mounts", "r");
diff --git a/src/system/helpers.h b/src/system/helpers.h
index c3abdb41f..5fd773953 100644
--- a/src/system/helpers.h
+++ b/src/system/helpers.h
@@ -76,6 +76,13 @@ time_t toEpoch(std::string &date);
std::string& str_replace(const std::string &search, const std::string &replace, std::string &text);
std::string& htmlEntityDecode(std::string& text);
+struct helpersDebugInfo {
+ std::string msg;
+ std::string file;
+ std::string func;
+ int line;
+};
+
class CFileHelpers
{
private:
@@ -83,16 +90,27 @@ class CFileHelpers
char *FileBuf;
int fd1, fd2;
+ bool ConsoleQuiet;
+ helpersDebugInfo DebugInfo;
+ void setDebugInfo(const char* msg, const char* file, const char* func, int line);
+ void printDebugInfo();
+
public:
CFileHelpers();
~CFileHelpers();
static CFileHelpers* getInstance();
bool doCopyFlag;
- bool copyFile(const char *Src, const char *Dst, mode_t mode);
+ void clearDebugInfo();
+ void readDebugInfo(helpersDebugInfo* di);
+ void setConsoleQuiet(bool q) { ConsoleQuiet = q; };
+ bool getConsoleQuiet() { return ConsoleQuiet; };
+
+ bool cp(const char *Src, const char *Dst, const char *Flags="");
+ bool copyFile(const char *Src, const char *Dst, mode_t forceMode=0);
bool copyDir(const char *Src, const char *Dst, bool backupMode=false);
- static bool createDir(std::string& Dir, mode_t mode = 755);
- static bool createDir(const char *Dir, mode_t mode = 755){std::string dir = std::string(Dir);return createDir(dir, mode);}
+ static bool createDir(std::string& Dir, mode_t mode = 0755);
+ static bool createDir(const char *Dir, mode_t mode = 0755){std::string dir = std::string(Dir);return createDir(dir, mode);}
static bool removeDir(const char *Dir);
static uint64_t getDirSize(const char *dir);
static uint64_t getDirSize(const std::string& dir){return getDirSize(dir.c_str());};
@@ -107,6 +125,8 @@ std::string to_string(unsigned long);
std::string to_string(long long);
std::string to_string(unsigned long long);
+std::string itoa(int value, int base);
+
inline int atoi(std::string &s) { return atoi(s.c_str()); }
inline int atoi(const std::string &s) { return atoi(s.c_str()); }
inline int access(std::string &s, int mode) { return access(s.c_str(), mode); }