<% for plugin, desc in pairs(plugins) do %>
- <% if luci.fs.access("/usr/lib/collectd/" .. plugin .. ".so") then %>
+ <% if nixio.fs.access("/usr/lib/collectd/" .. plugin .. ".so") then %>
<% end %>
<% end %>
diff --git a/applications/luci-statistics/luasrc/view/admin_statistics/outputplugins.htm b/applications/luci-statistics/luasrc/view/admin_statistics/outputplugins.htm
index e79e2f49f5..ef9ae23b5a 100644
--- a/applications/luci-statistics/luasrc/view/admin_statistics/outputplugins.htm
+++ b/applications/luci-statistics/luasrc/view/admin_statistics/outputplugins.htm
@@ -23,7 +23,7 @@ and to transmit the data over the network to other collectd instances.%>
<% for plugin, desc in pairs(plugins) do %>
- <% if luci.fs.access("/usr/lib/collectd/" .. plugin .. ".so") then %>
+ <% if nixio.fs.access("/usr/lib/collectd/" .. plugin .. ".so") then %>
<% end %>
<% end %>
diff --git a/applications/luci-statistics/luasrc/view/admin_statistics/systemplugins.htm b/applications/luci-statistics/luasrc/view/admin_statistics/systemplugins.htm
index 0c1b2b52bb..0e801c791c 100644
--- a/applications/luci-statistics/luasrc/view/admin_statistics/systemplugins.htm
+++ b/applications/luci-statistics/luasrc/view/admin_statistics/systemplugins.htm
@@ -19,7 +19,7 @@ $Id$
<%:stat_systemplugins_desc System plugins collecting values about system state and ressource usage on the device.:%>
<% for plugin, desc in pairs(plugins) do %>
- <% if luci.fs.access("/usr/lib/collectd/" .. plugin .. ".so") then %>
+ <% if nixio.fs.access("/usr/lib/collectd/" .. plugin .. ".so") then %>
<% end %>
<% end %>
diff --git a/applications/luci-tinyproxy/luasrc/controller/tinyproxy.lua b/applications/luci-tinyproxy/luasrc/controller/tinyproxy.lua
index fb8d9e2b5d..f21b0fc646 100644
--- a/applications/luci-tinyproxy/luasrc/controller/tinyproxy.lua
+++ b/applications/luci-tinyproxy/luasrc/controller/tinyproxy.lua
@@ -15,11 +15,11 @@ $Id$
module("luci.controller.tinyproxy", package.seeall)
function index()
- if not luci.fs.access("/etc/config/tinyproxy") then
+ if not nixio.fs.access("/etc/config/tinyproxy") then
return
end
local page = entry({"admin", "services", "tinyproxy"}, cbi("tinyproxy"), "Tinyproxy")
page.dependent = true
page.i18n = "tinyproxy"
-end
\ No newline at end of file
+end
diff --git a/applications/luci-upnp/luasrc/controller/upnp.lua b/applications/luci-upnp/luasrc/controller/upnp.lua
index c88abddc24..fd3175553c 100644
--- a/applications/luci-upnp/luasrc/controller/upnp.lua
+++ b/applications/luci-upnp/luasrc/controller/upnp.lua
@@ -15,7 +15,7 @@ $Id$
module("luci.controller.upnp", package.seeall)
function index()
- if not luci.fs.access("/etc/config/upnpd") then
+ if not nixio.fs.access("/etc/config/upnpd") then
return
end
diff --git a/applications/luci-ushare/luasrc/controller/ushare.lua b/applications/luci-ushare/luasrc/controller/ushare.lua
index 958f247d98..b9c16a4c16 100644
--- a/applications/luci-ushare/luasrc/controller/ushare.lua
+++ b/applications/luci-ushare/luasrc/controller/ushare.lua
@@ -18,7 +18,7 @@ module("luci.controller.ushare", package.seeall)
function index()
require("luci.i18n")
luci.i18n.loadc("ushare")
- if not luci.fs.access("/etc/config/ushare") then
+ if not nixio.fs.access("/etc/config/ushare") then
return
end
diff --git a/applications/luci-uvc_streamer/luasrc/controller/uvc_streamer.lua b/applications/luci-uvc_streamer/luasrc/controller/uvc_streamer.lua
index 64491dc9dc..8363454ef1 100644
--- a/applications/luci-uvc_streamer/luasrc/controller/uvc_streamer.lua
+++ b/applications/luci-uvc_streamer/luasrc/controller/uvc_streamer.lua
@@ -18,7 +18,7 @@ module("luci.controller.uvc_streamer", package.seeall)
function index()
require("luci.i18n")
luci.i18n.loadc("uvc_streamer")
- if not luci.fs.access("/etc/config/uvc-streamer") then
+ if not nixio.fs.access("/etc/config/uvc-streamer") then
return
end
diff --git a/applications/luci-voice-core/Makefile b/applications/luci-voice-core/Makefile
new file mode 100644
index 0000000000..d57c456d56
--- /dev/null
+++ b/applications/luci-voice-core/Makefile
@@ -0,0 +1,4 @@
+PO=voice_core
+
+include ../../build/config.mk
+include ../../build/module.mk
diff --git a/applications/luci-voice-core/luasrc/controller/luci_voice.lua b/applications/luci-voice-core/luasrc/controller/luci_voice.lua
new file mode 100644
index 0000000000..4d8873e9f5
--- /dev/null
+++ b/applications/luci-voice-core/luasrc/controller/luci_voice.lua
@@ -0,0 +1,37 @@
+--[[
+
+Luci Voice Core
+(c) 2009 Daniel Dickinson
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+]]--
+
+
+module("luci.controller.luci_voice", package.seeall)
+
+function index()
+ require("luci.i18n")
+ luci.i18n.loadc("voice_core")
+
+ local e = entry({"admin", "voice"}, template("luci_voice/index") , luci.i18n.translate("l_v_adminvoice", "Voice"), 90)
+ e.index = true
+ e.i18n = "voice_core"
+
+ e = entry({"mini", "voice"}, template("luci_voice/index"), luci.i18n.translate("l_v_minivoice", "Voice"), 90)
+ e.index = true
+ e.i18n = "voice_core"
+
+ e = entry({"mini", "voice", "phones"}, template("luci_voice/phone_index"), luci.i18n.translate("l_v_miniphones"), 90)
+ e.index = true
+ e.i18n = "voice_core"
+
+ e = entry({"admin", "voice", "phones"}, template("luci_voice/phone_index"), luci.i18n.translate("l_v_adminphones"), 90)
+ e.index = true
+ e.i18n = "voice_core"
+
+end
diff --git a/applications/luci-voice-core/luasrc/view/luci_voice/index.htm b/applications/luci-voice-core/luasrc/view/luci_voice/index.htm
new file mode 100644
index 0000000000..73d2ce4466
--- /dev/null
+++ b/applications/luci-voice-core/luasrc/view/luci_voice/index.htm
@@ -0,0 +1,24 @@
+<%#
+LuCI - Lua Configuration Interface
+(c) 2009 Daniel Dickinson
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+-%>
+<%+header%>
+
Here you can control OpenWRT voice-related settings and see
+ voice-related information from OpenWRT
+
In particular Asterisk configuration and information is displayed
+ here, as well as diagnostics that specifically apply to voice but are
+ not general networking diagnostics (e.g. includes SIP device scans, but not
+ ping tests). Includes PSTN phones as well as VoIP and possibly
+ non-telephony related options.
+
+<%+footer%>
diff --git a/applications/luci-voice-core/luasrc/view/luci_voice/phone_index.htm b/applications/luci-voice-core/luasrc/view/luci_voice/phone_index.htm
new file mode 100644
index 0000000000..89b866114a
--- /dev/null
+++ b/applications/luci-voice-core/luasrc/view/luci_voice/phone_index.htm
@@ -0,0 +1,20 @@
+<%#
+LuCI - Lua Configuration Interface
+(c) 2009 Daniel Dickinson
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+-%>
+<%+header%>
+
<% for _, e in luci.util.vspairs(entries) do
- local stat = luci.fs.stat(filepath..e)
- if e ~= '.' and e ~= '..' and stat and stat.type == 'dir' then
+ local stat = nixio.fs.stat(filepath..e)
+ if stat and stat.type == 'dir' then
-%>
@@ -108,7 +109,7 @@ $Id$
<% end end -%>
<% for _, e in luci.util.vspairs(entries) do
- local stat = luci.fs.stat(filepath..e)
+ local stat = nixio.fs.stat(filepath..e)
if stat and stat.type ~= 'dir' then
-%>
diff --git a/libs/cbi/luasrc/view/cbi/upload.htm b/libs/cbi/luasrc/view/cbi/upload.htm
index a4ab0c958d..7bde74b482 100644
--- a/libs/cbi/luasrc/view/cbi/upload.htm
+++ b/libs/cbi/luasrc/view/cbi/upload.htm
@@ -16,10 +16,11 @@ $Id$
<%
local t = require("luci.tools.webadmin")
local v = self:cfgvalue(section)
+ v = v and nixio.fs.stat(v)
-%>
<%+cbi/valueheader%>
<% if v then %>
- <%:cbi_upload Uploaded File%> (<%=t.byte_format(luci.fs.stat(v, "size") or 0)%>)
+ <%:cbi_upload Uploaded File%> (<%=t.byte_format(v.size)%>)
/>
" alt="<%:cbi_replace%>" title="<%:cbi_replace%>" src="<%=resource%>/cbi/reload.gif" />
<% else %>
diff --git a/libs/core/luasrc/debug.lua b/libs/core/luasrc/debug.lua
index f991ab8a60..3969254a95 100644
--- a/libs/core/luasrc/debug.lua
+++ b/libs/core/luasrc/debug.lua
@@ -6,13 +6,24 @@ module "luci.debug"
__file__ = debug.getinfo(1, 'S').source:sub(2)
-- Enables the memory tracer with given flags and returns a function to disable the tracer again
-function trap_memtrace(flags)
- flags = flags or "l"
- local tracefile = io.open("/tmp/memtrace", "w")
+function trap_memtrace(flags, dest)
+ flags = flags or "clr"
+ local tracefile = io.open(dest or "/tmp/memtrace", "w")
+ local peak = 0
local function trap(what, line)
local info = debug.getinfo(2, "Sn")
- tracefile:write(info.source..":"..line.."\t"..(info.namewhat or "").."\t"..(info.name or "").."\t"..collectgarbage("count").."\n")
+ if collectgarbage("count") > peak then
+ peak = collectgarbage("count")
+ end
+ if tracefile then
+ tracefile:write(
+ "[", what, "] ", info.source, ":", (line or "?"), "\t",
+ (info.namewhat or ""), "\t",
+ (info.name or ""), "\t",
+ collectgarbage("count"), " (", peak, ")\n"
+ )
+ end
end
debug.sethook(trap, flags)
diff --git a/libs/core/luasrc/util.lua b/libs/core/luasrc/util.lua
index 79f01a6269..f83cac5763 100644
--- a/libs/core/luasrc/util.lua
+++ b/libs/core/luasrc/util.lua
@@ -37,6 +37,7 @@ local rawget, rawset, unpack = rawget, rawset, unpack
local tostring, type, assert = tostring, type, assert
local ipairs, pairs, loadstring = ipairs, pairs, loadstring
local require, pcall, xpcall = require, pcall, xpcall
+local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit
--- LuCI utility functions.
module "luci.util"
@@ -554,10 +555,10 @@ function strip_bytecode(code)
end
end
- local strip_function
- strip_function = function(code)
+ local function strip_function(code)
local count, offset = subint(code, 1, size)
- local stripped, dirty = string.rep("\0", size), offset + count
+ local stripped = { string.rep("\0", size) }
+ local dirty = offset + count
offset = offset + count + int * 2 + 4
offset = offset + int + subint(code, offset, int) * ins
count, offset = subint(code, offset, int)
@@ -575,10 +576,11 @@ function strip_bytecode(code)
end
end
count, offset = subint(code, offset, int)
- stripped = stripped .. code:sub(dirty, offset - 1)
+ stripped[#stripped+1] = code:sub(dirty, offset - 1)
for n = 1, count do
local proto, off = strip_function(code:sub(offset, -1))
- stripped, offset = stripped .. proto, offset + off - 1
+ stripped[#stripped+1] = proto
+ offset = offset + off - 1
end
offset = offset + subint(code, offset, int) * int + int
count, offset = subint(code, offset, int)
@@ -589,8 +591,8 @@ function strip_bytecode(code)
for n = 1, count do
offset = offset + subint(code, offset, size) + size
end
- stripped = stripped .. string.rep("\0", int * 3)
- return stripped, offset
+ stripped[#stripped+1] = string.rep("\0", int * 3)
+ return table.concat(stripped), offset
end
return code:sub(1,12) .. strip_function(code:sub(13,-1))
@@ -703,7 +705,7 @@ end
--- Returns the absolute path to LuCI base directory.
-- @return String containing the directory path
function libpath()
- return require "luci.fs".dirname(ldebug.__file__)
+ return require "nixio.fs".dirname(ldebug.__file__)
end
@@ -783,5 +785,11 @@ end
-- Resume execution of protected function call
function performResume(err, co, ...)
+ if get_memory_limit and get_memory_limit() > 0 and
+ collectgarbage("count") > (get_memory_limit() * 0.8)
+ then
+ collectgarbage("collect")
+ end
+
return handleReturnValue(err, co, coroutine.resume(co, ...))
end
diff --git a/libs/lmo/Makefile b/libs/lmo/Makefile
new file mode 100644
index 0000000000..a15390cbe5
--- /dev/null
+++ b/libs/lmo/Makefile
@@ -0,0 +1,46 @@
+ifneq (,$(wildcard ../../build/config.mk))
+include ../../build/config.mk
+include ../../build/module.mk
+include ../../build/gccconfig.mk
+else
+include standalone.mk
+endif
+
+LMO_LDFLAGS =
+LMO_CFLAGS =
+LMO_SO = lmo.so
+LMO_PO2LMO = po2lmo
+LMO_LOOKUP = lookup
+LMO_COMMON_OBJ = src/lmo_core.o src/lmo_hash.o
+LMO_PO2LMO_OBJ = src/lmo_po2lmo.o
+LMO_LOOKUP_OBJ = src/lmo_lookup.o
+LMO_LUALIB_OBJ = src/lmo_lualib.o
+
+%.o: %.c
+ $(COMPILE) $(LMO_CFLAGS) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
+
+compile: build-clean $(LMO_COMMON_OBJ) $(LMO_PO2LMO_OBJ) $(LMO_LOOKUP_OBJ) $(LMO_LUALIB_OBJ)
+ $(LINK) $(SHLIB_FLAGS) $(LMO_LDFLAGS) -o src/$(LMO_SO) \
+ $(LMO_COMMON_OBJ) $(LMO_LUALIB_OBJ)
+ $(LINK) $(LMO_LDFLAGS) -o src/$(LMO_PO2LMO) $(LMO_COMMON_OBJ) $(LMO_PO2LMO_OBJ)
+ $(LINK) $(LMO_LDFLAGS) -o src/$(LMO_LOOKUP) $(LMO_COMMON_OBJ) $(LMO_LOOKUP_OBJ)
+ mkdir -p dist$(LUA_LIBRARYDIR)
+ cp src/$(LMO_SO) dist$(LUA_LIBRARYDIR)/$(LMO_SO)
+
+install: build
+ cp -pR dist$(LUA_LIBRARYDIR)/* $(LUA_LIBRARYDIR)
+
+clean: build-clean
+
+build-clean:
+ rm -f src/*.o src/lookup src/po2lmo src/lmo.so
+
+host-compile: build-clean host-clean $(LMO_COMMON_OBJ) $(LMO_PO2LMO_OBJ)
+ $(LINK) $(LMO_LDFLAGS) -o src/$(LMO_PO2LMO) $(LMO_COMMON_OBJ) $(LMO_PO2LMO_OBJ)
+
+host-install: host-compile
+ cp src/$(LMO_PO2LMO) ../../build/$(LMO_PO2LMO)
+
+host-clean:
+ rm -f ../../build/$(LMO_PO2LMO)
+
diff --git a/libs/lmo/src/lmo.h b/libs/lmo/src/lmo.h
new file mode 100644
index 0000000000..ab17e873f4
--- /dev/null
+++ b/libs/lmo/src/lmo.h
@@ -0,0 +1,72 @@
+/*
+ * lmo - Lua Machine Objects - General header
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LMO_H_
+#define _LMO_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#if (defined(__GNUC__) && defined(__i386__))
+#define sfh_get16(d) (*((const uint16_t *) (d)))
+#else
+#define sfh_get16(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
+ +(uint32_t)(((const uint8_t *)(d))[0]) )
+#endif
+
+
+struct lmo_entry {
+ uint32_t key_id;
+ uint32_t val_id;
+ uint32_t offset;
+ uint32_t length;
+ struct lmo_entry *next;
+} __attribute__((packed));
+
+typedef struct lmo_entry lmo_entry_t;
+
+
+struct lmo_archive {
+ int fd;
+ uint32_t length;
+ lmo_entry_t *index;
+ char *mmap;
+};
+
+typedef struct lmo_archive lmo_archive_t;
+
+
+uint32_t sfh_hash(const char * data, int len);
+
+char _lmo_error[1024];
+const char * lmo_error(void);
+
+lmo_archive_t * lmo_open(const char *file);
+int lmo_lookup(lmo_archive_t *ar, const char *key, char *dest, int len);
+void lmo_close(lmo_archive_t *ar);
+
+#endif
diff --git a/libs/lmo/src/lmo_core.c b/libs/lmo/src/lmo_core.c
new file mode 100644
index 0000000000..b3cb7c0989
--- /dev/null
+++ b/libs/lmo/src/lmo_core.c
@@ -0,0 +1,231 @@
+/*
+ * lmo - Lua Machine Objects - Base functions
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lmo.h"
+
+extern char _lmo_error[1024];
+
+static int lmo_read32( int fd, uint32_t *val )
+{
+ uint8_t buffer[5];
+
+ if( read(fd, buffer, 4) < 4 )
+ return -1;
+
+ buffer[4] = 0;
+ *val = ntohl(*((uint32_t *) buffer));
+
+ return 4;
+}
+
+static char * error(const char *message, int add_errno)
+{
+ memset(_lmo_error, 0, sizeof(_lmo_error));
+
+ if( add_errno )
+ snprintf(_lmo_error, sizeof(_lmo_error),
+ "%s: %s", message, strerror(errno));
+ else
+ snprintf(_lmo_error, sizeof(_lmo_error), "%s", message);
+
+ return NULL;
+}
+
+const char * lmo_error(void)
+{
+ return _lmo_error;
+}
+
+lmo_archive_t * lmo_open(const char *file)
+{
+ int in = -1;
+ uint32_t idx_offset = 0;
+ uint32_t i;
+ struct stat s;
+
+ lmo_archive_t *ar = NULL;
+ lmo_entry_t *head = NULL;
+ lmo_entry_t *entry = NULL;
+
+ if( stat(file, &s) == -1 )
+ {
+ error("Can not stat file", 1);
+ goto cleanup;
+ }
+
+ if( (in = open(file, O_RDONLY)) == -1 )
+ {
+ error("Can not open file", 1);
+ goto cleanup;
+ }
+
+ if( lseek(in, -sizeof(uint32_t), SEEK_END) == -1 )
+ {
+ error("Can not seek to eof", 1);
+ goto cleanup;
+ }
+
+ if( lmo_read32(in, &idx_offset) != 4 )
+ {
+ error("Unexpected EOF while reading index offset", 0);
+ goto cleanup;
+ }
+
+ if( lseek(in, idx_offset, SEEK_SET) == -1 )
+ {
+ error("Can not seek to index offset", 1);
+ goto cleanup;
+ }
+
+ if( (ar = (lmo_archive_t *) malloc(sizeof(lmo_archive_t))) != NULL )
+ {
+ ar->fd = in;
+ ar->length = idx_offset;
+
+ for( i = idx_offset;
+ i < (s.st_size - sizeof(uint32_t));
+ i += (4 * sizeof(uint32_t))
+ ) {
+ if( (entry = (lmo_entry_t *) malloc(sizeof(lmo_entry_t))) != NULL )
+ {
+ if( (lmo_read32(ar->fd, &entry->key_id) == 4) &&
+ (lmo_read32(ar->fd, &entry->val_id) == 4) &&
+ (lmo_read32(ar->fd, &entry->offset) == 4) &&
+ (lmo_read32(ar->fd, &entry->length) == 4)
+ ) {
+ entry->next = head;
+ head = entry;
+ }
+ else
+ {
+ error("Unexpected EOF while reading index entry", 0);
+ goto cleanup;
+ }
+ }
+ else
+ {
+ error("Out of memory", 0);
+ goto cleanup;
+ }
+ }
+
+ ar->index = head;
+
+ if( lseek(ar->fd, 0, SEEK_SET) == -1 )
+ {
+ error("Can not seek to start", 1);
+ goto cleanup;
+ }
+
+ if( (ar->mmap = mmap(NULL, ar->length, PROT_READ, MAP_SHARED, ar->fd, 0)) == MAP_FAILED )
+ {
+ error("Failed to memory map archive contents", 1);
+ goto cleanup;
+ }
+
+ return ar;
+ }
+ else
+ {
+ error("Out of memory", 0);
+ goto cleanup;
+ }
+
+
+ cleanup:
+
+ if( in > -1 )
+ close(in);
+
+ if( head != NULL )
+ {
+ entry = head;
+
+ while( entry != NULL )
+ {
+ head = entry->next;
+ free(entry);
+ entry = head;
+ }
+
+ head = entry = NULL;
+ }
+
+ if( ar != NULL )
+ {
+ if( (ar->mmap != NULL) && (ar->mmap != MAP_FAILED) )
+ munmap(ar->mmap, ar->length);
+
+ free(ar);
+ ar = NULL;
+ }
+
+ return NULL;
+}
+
+void lmo_close(lmo_archive_t *ar)
+{
+ lmo_entry_t *head = NULL;
+ lmo_entry_t *entry = NULL;
+
+ if( ar != NULL )
+ {
+ entry = ar->index;
+
+ while( entry != NULL )
+ {
+ head = entry->next;
+ free(entry);
+ entry = head;
+ }
+
+ head = entry = NULL;
+
+ if( (ar->mmap != NULL) && (ar->mmap != MAP_FAILED) )
+ munmap(ar->mmap, ar->length);
+
+ close(ar->fd);
+ free(ar);
+
+ ar = NULL;
+ }
+}
+
+int lmo_lookup(lmo_archive_t *ar, const char *key, char *dest, int len)
+{
+ uint32_t look_key = sfh_hash(key, strlen(key));
+ int copy_len = -1;
+
+ lmo_entry_t *entry = ar->index;
+
+ while( entry != NULL )
+ {
+ if( entry->key_id == look_key )
+ {
+ copy_len = (len > entry->length) ? entry->length : len;
+ memcpy(dest, &ar->mmap[entry->offset], copy_len);
+
+ break;
+ }
+
+ entry = entry->next;
+ }
+
+ return copy_len;
+}
+
diff --git a/libs/lmo/src/lmo_hash.c b/libs/lmo/src/lmo_hash.c
new file mode 100644
index 0000000000..bc8e6fe4ed
--- /dev/null
+++ b/libs/lmo/src/lmo_hash.c
@@ -0,0 +1,53 @@
+/*
+ * Hash function from http://www.azillionmonkeys.com/qed/hash.html
+ * Copyright (C) 2004-2008 by Paul Hsieh
+ */
+
+#include "lmo.h"
+
+uint32_t sfh_hash(const char * data, int len)
+{
+ uint32_t hash = len, tmp;
+ int rem;
+
+ if (len <= 0 || data == NULL) return 0;
+
+ rem = len & 3;
+ len >>= 2;
+
+ /* Main loop */
+ for (;len > 0; len--) {
+ hash += sfh_get16(data);
+ tmp = (sfh_get16(data+2) << 11) ^ hash;
+ hash = (hash << 16) ^ tmp;
+ data += 2*sizeof(uint16_t);
+ hash += hash >> 11;
+ }
+
+ /* Handle end cases */
+ switch (rem) {
+ case 3: hash += sfh_get16(data);
+ hash ^= hash << 16;
+ hash ^= data[sizeof(uint16_t)] << 18;
+ hash += hash >> 11;
+ break;
+ case 2: hash += sfh_get16(data);
+ hash ^= hash << 11;
+ hash += hash >> 17;
+ break;
+ case 1: hash += *data;
+ hash ^= hash << 10;
+ hash += hash >> 1;
+ }
+
+ /* Force "avalanching" of final 127 bits */
+ hash ^= hash << 3;
+ hash += hash >> 5;
+ hash ^= hash << 4;
+ hash += hash >> 17;
+ hash ^= hash << 25;
+ hash += hash >> 6;
+
+ return hash;
+}
+
diff --git a/libs/lmo/src/lmo_lookup.c b/libs/lmo/src/lmo_lookup.c
new file mode 100644
index 0000000000..8b48f7facb
--- /dev/null
+++ b/libs/lmo/src/lmo_lookup.c
@@ -0,0 +1,58 @@
+/*
+ * lmo - Lua Machine Objects - Lookup utility
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lmo.h"
+
+extern char _lmo_error[1024];
+
+static void die(const char *msg)
+{
+ printf("Error: %s\n", msg);
+ exit(1);
+}
+
+static void usage(const char *name)
+{
+ printf("Usage: %s input.lmo key\n", name);
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ char val[4096];
+ lmo_archive_t *ar = NULL;
+
+ if( argc != 3 )
+ usage(argv[0]);
+
+ if( (ar = (lmo_archive_t *) lmo_open(argv[1])) != NULL )
+ {
+ if( lmo_lookup(ar, argv[2], val, sizeof(val)) > -1 )
+ {
+ printf("%s\n", val);
+ }
+
+ lmo_close(ar);
+ }
+ else
+ {
+ die(lmo_error());
+ }
+
+ return 0;
+}
diff --git a/libs/lmo/src/lmo_lualib.c b/libs/lmo/src/lmo_lualib.c
new file mode 100644
index 0000000000..676f788d28
--- /dev/null
+++ b/libs/lmo/src/lmo_lualib.c
@@ -0,0 +1,152 @@
+/*
+ * lmo - Lua Machine Objects - Lua binding
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lmo_lualib.h"
+
+extern char _lmo_error[1024];
+
+
+static int lmo_L_open(lua_State *L) {
+ const char *filename = luaL_checklstring(L, 1, NULL);
+ lmo_archive_t *ar, **udata;
+
+ if( (ar = lmo_open(filename)) != NULL )
+ {
+ if( (udata = lua_newuserdata(L, sizeof(lmo_archive_t *))) != NULL )
+ {
+ *udata = ar;
+ luaL_getmetatable(L, LMO_ARCHIVE_META);
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+
+ lmo_close(ar);
+ lua_pushnil(L);
+ lua_pushstring(L, "out of memory");
+ return 2;
+ }
+
+ lua_pushnil(L);
+ lua_pushstring(L, lmo_error());
+ return 2;
+}
+
+static int lmo_L_hash(lua_State *L) {
+ const char *data = luaL_checkstring(L, 1);
+ uint32_t hash = sfh_hash(data, strlen(data));
+ lua_pushinteger(L, (lua_Integer)hash);
+ return 1;
+}
+
+static int _lmo_lookup(lua_State *L, lmo_archive_t *ar, uint32_t hash) {
+ lmo_entry_t *e = ar->index;
+
+ while( e != NULL )
+ {
+ if( e->key_id == hash )
+ {
+ lua_pushlstring(L, &ar->mmap[e->offset], e->length);
+ return 1;
+ }
+
+ e = e->next;
+ }
+
+ lua_pushnil(L);
+ return 1;
+}
+
+static int lmo_L_get(lua_State *L) {
+ lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META);
+ uint32_t hash = (uint32_t) luaL_checkinteger(L, 2);
+ return _lmo_lookup(L, *ar, hash);
+}
+
+static int lmo_L_lookup(lua_State *L) {
+ lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META);
+ const char *key = luaL_checkstring(L, 2);
+ uint32_t hash = sfh_hash(key, strlen(key));
+ return _lmo_lookup(L, *ar, hash);
+}
+
+static int lmo_L_foreach(lua_State *L) {
+ lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META);
+ lmo_entry_t *e = (*ar)->index;
+
+ if( lua_isfunction(L, 2) )
+ {
+ while( e != NULL )
+ {
+ lua_pushvalue(L, 2);
+ lua_pushinteger(L, e->key_id);
+ lua_pushlstring(L, &(*ar)->mmap[e->offset], e->length);
+ lua_pcall(L, 2, 0, 0);
+ e = e->next;
+ }
+ }
+
+ return 0;
+}
+
+static int lmo_L__gc(lua_State *L) {
+ lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META);
+
+ if( (*ar) != NULL )
+ lmo_close(*ar);
+
+ *ar = NULL;
+
+ return 0;
+}
+
+static int lmo_L__tostring(lua_State *L) {
+ lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META);
+ lua_pushfstring(L, "LMO Archive (%d bytes)", (*ar)->length);
+ return 1;
+}
+
+
+/* method table */
+static const luaL_reg M[] = {
+ {"close", lmo_L__gc},
+ {"get", lmo_L_get},
+ {"lookup", lmo_L_lookup},
+ {"foreach", lmo_L_foreach},
+ {"__tostring", lmo_L__tostring},
+ {"__gc", lmo_L__gc},
+ {NULL, NULL}
+};
+
+/* module table */
+static const luaL_reg R[] = {
+ {"open", lmo_L_open},
+ {"hash", lmo_L_hash},
+ {NULL, NULL}
+};
+
+LUALIB_API int luaopen_lmo(lua_State *L) {
+ luaL_newmetatable(L, LMO_ARCHIVE_META);
+ luaL_register(L, NULL, M);
+ lua_pushvalue(L, -1);
+ lua_setfield(L, -2, "__index");
+ lua_setglobal(L, LMO_ARCHIVE_META);
+
+ luaL_register(L, LMO_LUALIB_META, R);
+
+ return 1;
+}
diff --git a/libs/lmo/src/lmo_lualib.h b/libs/lmo/src/lmo_lualib.h
new file mode 100644
index 0000000000..096fa027fb
--- /dev/null
+++ b/libs/lmo/src/lmo_lualib.h
@@ -0,0 +1,33 @@
+/*
+ * lmo - Lua Machine Objects - Lua library header
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LMO_LUALIB_H_
+#define _LMO_LUALIB_H_
+
+#include
+#include
+#include
+
+#include "lmo.h"
+
+#define LMO_LUALIB_META "lmo"
+#define LMO_ARCHIVE_META "lmo.archive"
+
+LUALIB_API int luaopen_lmo(lua_State *L);
+
+#endif
diff --git a/libs/lmo/src/lmo_po2lmo.c b/libs/lmo/src/lmo_po2lmo.c
new file mode 100644
index 0000000000..9f78ff2add
--- /dev/null
+++ b/libs/lmo/src/lmo_po2lmo.c
@@ -0,0 +1,199 @@
+/*
+ * lmo - Lua Machine Objects - PO to LMO conversion tool
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lmo.h"
+
+static void die(const char *msg)
+{
+ fprintf(stderr, "Error: %s\n", msg);
+ exit(1);
+}
+
+static void usage(const char *name)
+{
+ fprintf(stderr, "Usage: %s input.po output.lmo\n", name);
+ exit(1);
+}
+
+static void print(const void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
+ if( fwrite(ptr, size, nmemb, stream) == 0 )
+ die("Failed to write stdout");
+}
+
+static int extract_string(const char *src, char *dest, int len)
+{
+ int pos = 0;
+ int esc = 0;
+ int off = -1;
+
+ for( pos = 0; (pos < strlen(src)) && (pos < len); pos++ )
+ {
+ if( (off == -1) && (src[pos] == '"') )
+ {
+ off = pos + 1;
+ }
+ else if( off >= 0 )
+ {
+ if( esc == 1 )
+ {
+ dest[pos-off] = src[pos];
+ esc = 0;
+ }
+ else if( src[pos] == '\\' )
+ {
+ off++;
+ esc = 1;
+
+ }
+ else if( src[pos] != '"' )
+ {
+ dest[pos-off] = src[pos];
+ }
+ else
+ {
+ dest[pos-off] = '\0';
+ break;
+ }
+ }
+ }
+
+ return (off > -1) ? strlen(dest) : -1;
+}
+
+int main(int argc, char *argv[])
+{
+ char line[4096];
+ char key[4096];
+ char val[4096];
+ char tmp[4096];
+ int state = 0;
+ int offset = 0;
+ int length = 0;
+
+ FILE *in;
+ FILE *out;
+
+ lmo_entry_t *head = NULL;
+ lmo_entry_t *entry = NULL;
+
+ if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) )
+ usage(argv[0]);
+
+ memset(line, 0, sizeof(key));
+ memset(key, 0, sizeof(val));
+ memset(val, 0, sizeof(val));
+
+ while( (NULL != fgets(line, sizeof(line), in)) || (state >= 2 && feof(in)) )
+ {
+ if( state == 0 && strstr(line, "msgid \"") == line )
+ {
+ switch(extract_string(line, key, sizeof(key)))
+ {
+ case -1:
+ die("Syntax error in msgid");
+ case 0:
+ continue;
+ default:
+ state = 1;
+ }
+ }
+ else if( state == 1 && strstr(line, "msgstr \"") == line )
+ {
+ switch(extract_string(line, val, sizeof(val)))
+ {
+ case -1:
+ die("Syntax error in msgstr");
+ case 0:
+ state = 2;
+ break;
+ default:
+ state = 3;
+ }
+ }
+ else if( state == 2 )
+ {
+ switch(extract_string(line, tmp, sizeof(tmp)))
+ {
+ case -1:
+ state = 3;
+ break;
+ default:
+ strcat(val, tmp);
+ }
+ }
+ else if( state == 3 )
+ {
+ if( strlen(key) > 0 && strlen(val) > 0 )
+ {
+ if( (entry = (lmo_entry_t *) malloc(sizeof(lmo_entry_t))) != NULL )
+ {
+ memset(entry, 0, sizeof(entry));
+ length = strlen(val) + ((4 - (strlen(val) % 4)) % 4);
+
+ entry->key_id = htonl(sfh_hash(key, strlen(key)));
+ entry->val_id = htonl(sfh_hash(val, strlen(val)));
+ entry->offset = htonl(offset);
+ entry->length = htonl(strlen(val));
+
+ print(val, length, 1, out);
+ offset += length;
+
+ entry->next = head;
+ head = entry;
+ }
+ else
+ {
+ die("Out of memory");
+ }
+ }
+
+ state = 0;
+ memset(key, 0, sizeof(key));
+ memset(val, 0, sizeof(val));
+ }
+
+ memset(line, 0, sizeof(line));
+ }
+
+ entry = head;
+ while( entry != NULL )
+ {
+ print(&entry->key_id, sizeof(uint32_t), 1, out);
+ print(&entry->val_id, sizeof(uint32_t), 1, out);
+ print(&entry->offset, sizeof(uint32_t), 1, out);
+ print(&entry->length, sizeof(uint32_t), 1, out);
+ entry = entry->next;
+ }
+
+ if( offset > 0 )
+ {
+ offset = htonl(offset);
+ print(&offset, sizeof(uint32_t), 1, out);
+ fsync(fileno(out));
+ fclose(out);
+ }
+ else
+ {
+ fclose(out);
+ unlink(argv[2]);
+ }
+
+ fclose(in);
+ return(0);
+}
diff --git a/libs/lmo/standalone.mk b/libs/lmo/standalone.mk
new file mode 100644
index 0000000000..66a0e5a2e7
--- /dev/null
+++ b/libs/lmo/standalone.mk
@@ -0,0 +1,56 @@
+LUAC = luac
+LUAC_OPTIONS = -s
+LUA_TARGET ?= source
+
+LUA_MODULEDIR = /usr/local/share/lua/5.1
+LUA_LIBRARYDIR = /usr/local/lib/lua/5.1
+
+OS ?= $(shell uname)
+
+LUA_SHLIBS = $(shell pkg-config --silence-errors --libs lua5.1 || pkg-config --silence-errors --libs lua-5.1 || pkg-config --silence-errors --libs lua)
+LUA_LIBS = $(if $(LUA_SHLIBS),$(LUA_SHLIBS),$(firstword $(wildcard /usr/lib/liblua.a /usr/local/lib/liblua.a /opt/local/lib/liblua.a)))
+LUA_CFLAGS = $(shell pkg-config --silence-errors --cflags lua5.1 || pkg-config --silence-errors --cflags lua-5.1 || pkg-config --silence-errors --cflags lua)
+
+CC = gcc
+AR = ar
+RANLIB = ranlib
+CFLAGS = -O2
+FPIC = -fPIC
+EXTRA_CFLAGS = --std=gnu99
+WFLAGS = -Wall -Werror -pedantic
+CPPFLAGS =
+COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) $(WFLAGS)
+ifeq ($(OS),Darwin)
+ SHLIB_FLAGS = -bundle -undefined dynamic_lookup
+else
+ SHLIB_FLAGS = -shared
+endif
+LINK = $(CC) $(LDFLAGS)
+
+.PHONY: all build compile luacompile luasource clean luaclean
+
+all: build
+
+build: luabuild gccbuild
+
+luabuild: lua$(LUA_TARGET)
+
+gccbuild: compile
+compile:
+
+clean: luaclean
+
+luasource:
+ mkdir -p dist$(LUA_MODULEDIR)
+ cp -pR root/* dist 2>/dev/null || true
+ cp -pR lua/* dist$(LUA_MODULEDIR) 2>/dev/null || true
+ for i in $$(find dist -name .svn); do rm -rf $$i || true; done
+
+luastrip: luasource
+ for i in $$(find dist -type f -name '*.lua'); do perl -e 'undef $$/; open( F, "< $$ARGV[0]" ) || die $$!; $$src = ; close F; $$src =~ s/--\[\[.*?\]\](--)?//gs; $$src =~ s/^\s*--.*?\n//gm; open( F, "> $$ARGV[0]" ) || die $$!; print F $$src; close F' $$i; done
+
+luacompile: luasource
+ for i in $$(find dist -name *.lua -not -name debug.lua); do $(LUAC) $(LUAC_OPTIONS) -o $$i $$i; done
+
+luaclean:
+ rm -rf dist
diff --git a/libs/lucid-http/luasrc/lucid/http/server.lua b/libs/lucid-http/luasrc/lucid/http/server.lua
index 95484a02f0..4c3016a8ca 100644
--- a/libs/lucid-http/luasrc/lucid/http/server.lua
+++ b/libs/lucid-http/luasrc/lucid/http/server.lua
@@ -14,6 +14,7 @@ $Id$
local ipairs, pairs = ipairs, pairs
local tostring, tonumber = tostring, tonumber
local pcall, assert, type = pcall, assert, type
+local set_memory_limit = set_memory_limit
local os = require "os"
local nixio = require "nixio"
@@ -358,6 +359,11 @@ function Server.process(self, client, env)
local close = false
local stat, code, msg, message, err
+ env.config.memlimit = tonumber(env.config.memlimit)
+ if env.config.memlimit and set_memory_limit then
+ set_memory_limit(env.config.memlimit)
+ end
+
client:setsockopt("socket", "rcvtimeo", 5)
client:setsockopt("socket", "sndtimeo", 5)
diff --git a/libs/lucid/luasrc/lucid.lua b/libs/lucid/luasrc/lucid.lua
index 89ada3c2e8..d743269fe3 100644
--- a/libs/lucid/luasrc/lucid.lua
+++ b/libs/lucid/luasrc/lucid.lua
@@ -41,7 +41,7 @@ local UCINAME = UCINAME
local SSTATE = "/tmp/.lucid_store"
-
+--- Starts a new LuCId superprocess.
function start()
prepare()
@@ -60,6 +60,7 @@ function start()
run()
end
+--- Stops any running LuCId superprocess.
function stop()
local pid = tonumber(state:get(UCINAME, "main", "pid"))
if pid then
@@ -68,6 +69,7 @@ function stop()
return false
end
+--- Prepares the slaves, daemons and publishers, allocate resources.
function prepare()
local debug = tonumber((cursor:get(UCINAME, "main", "debug")))
@@ -104,24 +106,29 @@ function prepare()
end)
end
+--- Run the superprocess if prepared before.
+-- This main function of LuCId will wait for events on given file descriptors.
function run()
local pollint = tonumber((cursor:get(UCINAME, "main", "pollinterval")))
- local threadlimit = tonumber(cursor:get(UCINAME, "main", "threadlimit"))
+ local threadlimit = tonumber((cursor:get(UCINAME, "main", "threadlimit")))
while true do
- if not threadlimit or tcount < threadlimit then
- local stat, code = nixio.poll(pollt, pollint)
+ local stat, code = nixio.poll(pollt, pollint)
- if stat and stat > 0 then
- for _, polle in ipairs(pollt) do
- if polle.revents ~= 0 and polle.handler then
- polle.handler(polle)
- end
+ if stat and stat > 0 then
+ local ok = false
+ for _, polle in ipairs(pollt) do
+ if polle.revents ~= 0 and polle.handler then
+ ok = ok or polle.handler(polle)
end
- elseif stat == 0 then
- ifaddrs = nixio.getifaddrs()
- collectgarbage("collect")
end
+ if not ok then
+ -- Avoid high CPU usage if thread limit is reached
+ nixio.nanosleep(0, 100000000)
+ end
+ elseif stat == 0 then
+ ifaddrs = nixio.getifaddrs()
+ collectgarbage("collect")
end
for _, cb in ipairs(tickt) do
@@ -139,11 +146,20 @@ function run()
end
end
+--- Add a file descriptor for the main loop and associate handler functions.
+-- @param polle Table containing: {fd = FILE DESCRIPTOR, events = POLL EVENTS,
+-- handler = EVENT HANDLER CALLBACK}
+-- @see unregister_pollfd
+-- @return boolean status
function register_pollfd(polle)
pollt[#pollt+1] = polle
return true
end
+--- Unregister a file desciptor and associate handler from the main loop.
+-- @param polle Poll descriptor
+-- @see register_pollfd
+-- @return boolean status
function unregister_pollfd(polle)
for k, v in ipairs(pollt) do
if v == polle then
@@ -154,6 +170,8 @@ function unregister_pollfd(polle)
return false
end
+--- Close all registered file descriptors from main loop.
+-- This is useful for forked child processes.
function close_pollfds()
for k, v in ipairs(pollt) do
if v.fd and v.fd.close then
@@ -162,11 +180,19 @@ function close_pollfds()
end
end
+--- Register a tick function that will be called at each cycle of the main loop.
+-- @param cb Callback
+-- @see unregister_tick
+-- @return boolean status
function register_tick(cb)
tickt[#tickt+1] = cb
return true
end
+--- Unregister a tick function from the main loop.
+-- @param cb Callback
+-- @see register_tick
+-- @return boolean status
function unregister_tick(cb)
for k, v in ipairs(tickt) do
if v == cb then
@@ -177,10 +203,22 @@ function unregister_tick(cb)
return false
end
+--- Tests whether a given number of processes can be created.
+-- @oaram num Processes to be created
+-- @return boolean status
+function try_process(num)
+ local threadlimit = tonumber((cursor:get(UCINAME, "main", "threadlimit")))
+ return not threadlimit or (threadlimit - tcount) >= (num or 1)
+end
+
+--- Create a new child process from a Lua function and assign a destructor.
+-- @param threadcb main function of the new process
+-- @param waitcb destructor callback
+-- @return process identifier or nil, error code, error message
function create_process(threadcb, waitcb)
local threadlimit = tonumber(cursor:get(UCINAME, "main", "threadlimit"))
if threadlimit and tcount >= threadlimit then
- nixio.syslog("warning", "Unable to create thread: process limit reached")
+ nixio.syslog("warning", "Cannot create thread: process limit reached")
return nil
end
local pid, code, err = nixio.fork()
@@ -196,6 +234,9 @@ function create_process(threadcb, waitcb)
return pid, code, err
end
+--- Prepare a daemon from a given configuration table.
+-- @param config Configuration data.
+-- @return boolean status or nil, error code, error message
function prepare_daemon(config)
nixio.syslog("info", "Preparing daemon " .. config[".name"])
local modname = cursor:get(UCINAME, config.slave)
@@ -213,6 +254,9 @@ function prepare_daemon(config)
return module.prepare_daemon(config, _M)
end
+--- Prepare a slave.
+-- @param name slave name
+-- @return table containing slave module and configuration or nil, error message
function prepare_slave(name)
local slave = slaves[name]
if not slave then
@@ -231,16 +275,24 @@ function prepare_slave(name)
end
end
+--- Return a list of available network interfaces on the host.
+-- @return table returned by nixio.getifaddrs()
function get_interfaces()
return ifaddrs
end
+--- Revoke process privileges.
+-- @param user new user name or uid
+-- @param group new group name or gid
+-- @return boolean status or nil, error code, error message
function revoke_privileges(user, group)
if nixio.getuid() == 0 then
return nixio.setgid(group) and nixio.setuid(user)
end
end
+--- Return a secure UCI cursor.
+-- @return UCI cursor
function securestate()
local stat = nixio.fs.stat(SSTATE) or {}
local uid = nixio.getuid()
@@ -256,6 +308,8 @@ function securestate()
return uci.cursor(nil, SSTATE)
end
+--- Daemonize the process.
+-- @return boolean status or nil, error code, error message
function daemonize()
if nixio.getppid() == 1 then
return
diff --git a/libs/lucid/luasrc/lucid/tcpserver.lua b/libs/lucid/luasrc/lucid/tcpserver.lua
index b1b95c1fb3..6c61ff6d7d 100644
--- a/libs/lucid/luasrc/lucid/tcpserver.lua
+++ b/libs/lucid/luasrc/lucid/tcpserver.lua
@@ -105,6 +105,9 @@ function prepare_daemon(config, server)
end
function accept(polle)
+ if not lucid.try_process() then
+ return false
+ end
local socket, host, port = polle.fd:accept()
if not socket then
return nixio.syslog("warn", "accept() failed: " .. port)
diff --git a/libs/lucid/root/etc/config/lucid b/libs/lucid/root/etc/config/lucid
index a8f70da67e..c5a3f3d8ee 100644
--- a/libs/lucid/root/etc/config/lucid
+++ b/libs/lucid/root/etc/config/lucid
@@ -30,6 +30,7 @@ config daemon http
list publisher webroot
list publisher luciweb
option nokeepalive 1
+ option memlimit 1572864
option enabled 1
config daemon https
@@ -38,6 +39,7 @@ config daemon https
list publisher webroot
list publisher luciweb
option nokeepalive 1
+ option memlimit 1572864
option enabled 1
option tls maincert
option encryption enable
diff --git a/libs/nixio/Makefile b/libs/nixio/Makefile
index 044764e92a..f70f75421c 100644
--- a/libs/nixio/Makefile
+++ b/libs/nixio/Makefile
@@ -87,6 +87,18 @@ $(AXTLS_DIR)/.prepared:
src/libaxtls.a: $(AXTLS_DIR)/.prepared
$(MAKE) -C $(AXTLS_DIR) CC="$(CC)" CFLAGS="$(CFLAGS) $(EXTRA_CFLAGS) $(FPIC) -Wall -pedantic -I../config -I../ssl -I../crypto" LDFLAGS="$(LDFLAGS)" OS="$(OS)" clean all
cp -p $(AXTLS_DIR)/_stage/libaxtls.a src
+ # *************************************************************************
+ #
+ #
+ #
+ # *** WARNING ***
+ # The use of the axTLS cryptographical provider is discouraged!
+ # Please switch to either CyaSSL or OpenSSL.
+ # Support for axTLS might be removed in the near future.
+ #
+ #
+ #
+ #**************************************************************************
clean: luaclean
rm -f src/*.o src/*.so src/*.a src/*.dll
diff --git a/libs/nixio/docsrc/CHANGELOG.lua b/libs/nixio/docsrc/CHANGELOG.lua
new file mode 100644
index 0000000000..fb1cf160b6
--- /dev/null
+++ b/libs/nixio/docsrc/CHANGELOG.lua
@@ -0,0 +1,29 @@
+--- Changes and improvements.
+module "CHANGELOG"
+
+--- Service Release.
+--
+--
Added getifaddrs() function.
+--
Added getsockopt(), setsockopt(), getsockname() and getpeername()
+-- directly to TLS-socket objects unifying the socket interface.
+--
Added support for CyaSSL as cryptographical backend.
+--
Added support for x509 certificates in DER format.
+--
Added support for splice() in UnifiedIO.copyz().
+--
Added interface to inject chunks into UnifiedIO.linesource() buffer.
+--
Changed TLS behaviour to explicitely separate servers and clients.
+--
Fixed usage of signed datatype breaking Base64 decoding.
+--
Fixed namespace clashes for nixio.fs.
+--
Fixed splice() support for some exotic C libraries.
+--
Reconfigure axTLS cryptographical provider and mark it as obsolete.
+-- @class table
+-- @name 0.2
+-- @return !
\ No newline at end of file
diff --git a/libs/nixio/docsrc/README.lua b/libs/nixio/docsrc/README.lua
index 20793cefea..b957a69903 100644
--- a/libs/nixio/docsrc/README.lua
+++ b/libs/nixio/docsrc/README.lua
@@ -80,15 +80,12 @@ module "README"
--- Cryptography and TLS libraries.
--
---
Currently 2 underlying cryptography libraries are supported: openssl and
--- axTLS. The name of the library in use is written to
+--
Currently 3 underlying cryptography libraries are supported: openssl,
+-- cyassl and axTLS. The name of the library in use is written to
-- nixio.tls_provider
---
You should whenever possible use openssl as axTLS has only limited
--- support. It does not provide support for non-blocking sockets and
--- is probably less audited than openssl.
---
However in embedded development if you don't need openssl anyway
--- you may safe an essential amount of flash space (about 1 MB for the openssl
--- library) by choosing axTLS over openssl.
+--
You should whenever possible use openssl or cyassl as axTLS has only
+-- limited support. It does not provide support for non-blocking sockets and
+-- is probably less audited than the other ones.
--
As the supported Windows versions are not suitable for embedded devices
-- axTLS is at the moment not supported on Windows.
--
diff --git a/libs/nixio/docsrc/nixio.UnifiedIO.lua b/libs/nixio/docsrc/nixio.UnifiedIO.lua
index d0b189cf44..6e407ff2ca 100644
--- a/libs/nixio/docsrc/nixio.UnifiedIO.lua
+++ b/libs/nixio/docsrc/nixio.UnifiedIO.lua
@@ -111,7 +111,6 @@ module "nixio.UnifiedIO"
-- @usage This function uses the sendfile() syscall to copy the data or the
-- blocksource function of the source descriptor and the sink function
-- of the target descriptor as a fallback mechanism.
--- @usage Support for splice() on Linux is not implemented yet.
-- @usage If the limit parameter is ommited, data is copied
-- until an end-of-file, end-of-stream, connection shutdown or similar happens.
-- @usage If the descriptor is non-blocking the function may fail with EAGAIN.
diff --git a/libs/nixio/docsrc/nixio.bit.lua b/libs/nixio/docsrc/nixio.bit.lua
index 3bdad51f2f..6951dd5321 100644
--- a/libs/nixio/docsrc/nixio.bit.lua
+++ b/libs/nixio/docsrc/nixio.bit.lua
@@ -10,6 +10,12 @@ module "nixio.bit"
-- @param ... More Operands
-- @return number
+--- Invert given number.
+-- @class function
+-- @name bnot
+-- @param oper Operand
+-- @return number
+
--- Bitwise AND several numbers.
-- @class function
-- @name band
@@ -28,21 +34,21 @@ module "nixio.bit"
--- Left shift a number.
-- @class function
--- @name shl
+-- @name lshift
-- @param oper number
-- @param shift bits to shift
-- @return number
--- Right shift a number.
-- @class function
--- @name shr
+-- @name rshift
-- @param oper number
-- @param shift bits to shift
-- @return number
--- Arithmetically right shift a number.
-- @class function
--- @name ashr
+-- @name arshift
-- @param oper number
-- @param shift bits to shift
-- @return number
diff --git a/libs/nixio/lua/nixio/util.lua b/libs/nixio/lua/nixio/util.lua
index 0e8c90c9a5..ecefb4c97f 100644
--- a/libs/nixio/lua/nixio/util.lua
+++ b/libs/nixio/lua/nixio/util.lua
@@ -26,10 +26,12 @@ local file = nixio.meta_file
local uname = nixio.uname()
local ZBUG = uname.sysname == "Linux" and uname.release:sub(1, 3) == "2.4"
-function consume(iter)
- local tbl = {}
- for obj in iter do
- tbl[#tbl+1] = obj
+function consume(iter, append)
+ local tbl = append or {}
+ if iter then
+ for obj in iter do
+ tbl[#tbl+1] = obj
+ end
end
return tbl
end
@@ -259,4 +261,4 @@ for k, v in pairs(meta) do
file[k] = v
socket[k] = v
tls_socket[k] = v
-end
\ No newline at end of file
+end
diff --git a/libs/nixio/nixio-0.3-1.rockspec b/libs/nixio/nixio-0.3-1.rockspec
new file mode 100644
index 0000000000..755cf815d2
--- /dev/null
+++ b/libs/nixio/nixio-0.3-1.rockspec
@@ -0,0 +1,37 @@
+package = "nixio"
+version = "0.3-1"
+source = {
+ url = "http://dev.luci.freifunk-halle.net/nixio/nixio-0.3.tar.bz2"
+}
+description = {
+ summary = "System, Networking and I/O library for Lua",
+ detailed = [[
+ Nixio is a multi-platform library offering a wide variety
+ of features such as IPv4, IPv6 and UNIX networking, large file I/O, file
+ system operations, system and process control, POSIX user/group management,
+ basic cryptographical hashing, hmac and TLS support, bit operations and
+ binary conversion.
+ ]],
+ homepage = "http://luci.subsignal.org",
+ license = "Apache 2.0",
+ maintainer = "Steven Barth",
+}
+dependencies = {
+ "lua >= 5.1"
+}
+external_dependencies = {
+ OPENSSL = {
+ header = "openssl/ssl.h",
+ }
+}
+build = {
+ type = "make",
+ build_variables = {
+ NIXIO_LDFLAGS = "-lcrypt -L$(OPENSSL_LIBDIR) -I$(OPENSSL_INCDIR)",
+ LUA_CFLAGS = "$(CFLAGS) -I$(LUA_INCDIR)",
+ },
+ install_variables = {
+ LUA_MODULEDIR = "$(LUADIR)",
+ LUA_LIBRARYDIR = "$(LIBDIR)",
+ },
+}
diff --git a/libs/nixio/src/address.c b/libs/nixio/src/address.c
index 3547f19bef..41ab8a367c 100644
--- a/libs/nixio/src/address.c
+++ b/libs/nixio/src/address.c
@@ -18,6 +18,7 @@
#include "nixio.h"
#include
+#include
#include
#include
@@ -346,6 +347,9 @@ static int nixio_sock_getpeername(lua_State *L) {
}
#if defined(__linux__) || defined(BSD)
+#ifdef BSD
+#include
+#endif
#include
static int nixio_getifaddrs(lua_State *L) {
diff --git a/libs/nixio/src/bit.c b/libs/nixio/src/bit.c
index 14fdecab13..9991a7ca41 100644
--- a/libs/nixio/src/bit.c
+++ b/libs/nixio/src/bit.c
@@ -97,6 +97,13 @@ static int nixio_bit_cast(lua_State *L) {
return 1;
}
+static int nixio_bit_swap(lua_State *L) {
+ uint64_t op = luaL_checknumber(L, 1);
+ op = (op >> 24) | ((op >> 8) & 0xff00) | ((op & 0xff00) << 8) | (op << 24);
+ lua_pushnumber(L, op);
+ return 1;
+}
+
/* module table */
static const luaL_reg R[] = {
{"bor", nixio_bit_or},
@@ -111,6 +118,8 @@ static const luaL_reg R[] = {
{"div", nixio_bit_div},
{"check", nixio_bit_check},
{"cast", nixio_bit_cast},
+ {"tobit", nixio_bit_cast},
+ {"bswap", nixio_bit_swap},
{NULL, NULL}
};
diff --git a/libs/nixio/src/file.c b/libs/nixio/src/file.c
index 4827525227..9f99fb8277 100644
--- a/libs/nixio/src/file.c
+++ b/libs/nixio/src/file.c
@@ -123,14 +123,18 @@ static int nixio_dup(lua_State *L) {
if (stat == -1) {
return nixio__perror(L);
} else {
- int *udata = lua_newuserdata(L, sizeof(int));
- if (!udata) {
- return luaL_error(L, "out of memory");
- }
+ if (newfd == -1) {
+ int *udata = lua_newuserdata(L, sizeof(int));
+ if (!udata) {
+ return luaL_error(L, "out of memory");
+ }
- *udata = stat;
- luaL_getmetatable(L, NIXIO_FILE_META);
- lua_setmetatable(L, -2);
+ *udata = stat;
+ luaL_getmetatable(L, NIXIO_FILE_META);
+ lua_setmetatable(L, -2);
+ } else {
+ lua_pushvalue(L, 2);
+ }
return 1;
}
}
@@ -325,7 +329,7 @@ static int nixio_file_close(lua_State *L) {
static int nixio_file__gc(lua_State *L) {
int *fdp = luaL_checkudata(L, 1, NIXIO_FILE_META);
int res;
- if (*fdp != -1) {
+ if (*fdp > 2) {
do {
res = close(*fdp);
} while (res == -1 && errno == EINTR);
diff --git a/libs/nixio/standalone.mk b/libs/nixio/standalone.mk
index fe71f581a6..95f6bece42 100644
--- a/libs/nixio/standalone.mk
+++ b/libs/nixio/standalone.mk
@@ -42,7 +42,6 @@ clean: luaclean
luasource:
mkdir -p dist$(LUA_MODULEDIR)
- cp -pR root/* dist 2>/dev/null || true
cp -pR lua/* dist$(LUA_MODULEDIR) 2>/dev/null || true
for i in $$(find dist -name .svn); do rm -rf $$i || true; done
@@ -53,4 +52,4 @@ luacompile: luasource
for i in $$(find dist -name *.lua -not -name debug.lua); do $(LUAC) $(LUAC_OPTIONS) -o $$i $$i; done
luaclean:
- rm -rf dist
\ No newline at end of file
+ rm -rf dist
diff --git a/libs/sys/luasrc/sys.lua b/libs/sys/luasrc/sys.lua
index c9f0bcc884..d57077026f 100644
--- a/libs/sys/luasrc/sys.lua
+++ b/libs/sys/luasrc/sys.lua
@@ -27,16 +27,16 @@ limitations under the License.
local io = require "io"
local os = require "os"
-local nixio = require "nixio"
local table = require "table"
+local nixio = require "nixio"
+local fs = require "nixio.fs"
local luci = {}
luci.util = require "luci.util"
-luci.fs = require "luci.fs"
luci.ip = require "luci.ip"
-local tonumber, ipairs, pairs, pcall, type =
- tonumber, ipairs, pairs, pcall, type
+local tonumber, ipairs, pairs, pcall, type, next =
+ tonumber, ipairs, pairs, pcall, type, next
--- LuCI Linux and POSIX system utilities.
@@ -135,7 +135,7 @@ getenv = nixio.getenv
-- @return String containing the system hostname
function hostname(newname)
if type(newname) == "string" and #newname > 0 then
- luci.fs.writefile( "/proc/sys/kernel/hostname", newname .. "\n" )
+ fs.writefile( "/proc/sys/kernel/hostname", newname )
return newname
else
return nixio.uname().nodename
@@ -180,8 +180,8 @@ end
-- @return String containing the memory used for buffering in kB
-- @return String containing the free memory amount in kB
function sysinfo()
- local cpuinfo = luci.fs.readfile("/proc/cpuinfo")
- local meminfo = luci.fs.readfile("/proc/meminfo")
+ local cpuinfo = fs.readfile("/proc/cpuinfo")
+ local meminfo = fs.readfile("/proc/meminfo")
local system = cpuinfo:match("system typ.-:%s*([^\n]+)")
local model = ""
@@ -219,26 +219,14 @@ end
-- @param bytes Number of bytes for the unique id
-- @return String containing hex encoded id
function uniqueid(bytes)
- local fp = io.open("/dev/urandom")
- local chunk = { fp:read(bytes):byte(1, bytes) }
- fp:close()
-
- local hex = ""
-
- local pattern = "%02X"
- for i, byte in ipairs(chunk) do
- hex = hex .. pattern:format(byte)
- end
-
- return hex
+ local rand = fs.readfile("/dev/urandom", bytes)
+ return rand and nixio.bin.hexlify(rand)
end
--- Returns the current system uptime stats.
-- @return String containing total uptime in seconds
--- @return String containing idle time in seconds
function uptime()
- local loadavg = io.lines("/proc/uptime")()
- return loadavg:match("^(.-) (.-)$")
+ return nixio.sysinfo().uptime
end
@@ -251,15 +239,15 @@ net = {}
-- @return Table of table containing the current arp entries.
-- The following fields are defined for arp entry objects:
-- { "IP address", "HW address", "HW type", "Flags", "Mask", "Device" }
-function net.arptable()
- return _parse_delimited_table(io.lines("/proc/net/arp"), "%s%s+")
+function net.arptable(callback)
+ return _parse_delimited_table(io.lines("/proc/net/arp"), "%s%s+", callback)
end
--- Returns conntrack information
-- @return Table with the currently tracked IP connections
-function net.conntrack()
+function net.conntrack(callback)
local connt = {}
- if luci.fs.access("/proc/net/nf_conntrack", "r") then
+ if fs.access("/proc/net/nf_conntrack", "r") then
for line in io.lines("/proc/net/nf_conntrack") do
line = line:match "^(.-( [^ =]+=).-)%2"
local entry, flags = _parse_mixed_record(line, " +")
@@ -269,9 +257,13 @@ function net.conntrack()
entry[i] = nil
end
- connt[#connt+1] = entry
+ if callback then
+ callback(entry)
+ else
+ connt[#connt+1] = entry
+ end
end
- elseif luci.fs.access("/proc/net/ip_conntrack", "r") then
+ elseif fs.access("/proc/net/ip_conntrack", "r") then
for line in io.lines("/proc/net/ip_conntrack") do
line = line:match "^(.-( [^ =]+=).-)%2"
local entry, flags = _parse_mixed_record(line, " +")
@@ -281,7 +273,11 @@ function net.conntrack()
entry[i] = nil
end
- connt[#connt+1] = entry
+ if callback then
+ callback(entry)
+ else
+ connt[#connt+1] = entry
+ end
end
else
return nil
@@ -296,12 +292,14 @@ end
-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
-- "flags", "device" }
function net.defaultroute()
- local route = nil
- for _, r in pairs(net.routes()) do
- if r.dest:prefix() == 0 and (not route or route.metric > r.metric) then
- route = r
+ local route
+
+ net.routes(function(rt)
+ if rt.dest:prefix() == 0 and (not route or route.metric > rt.metric) then
+ route = rt
end
- end
+ end)
+
return route
end
@@ -312,42 +310,57 @@ end
-- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
-- "flags", "device" }
function net.defaultroute6()
- local route = nil
- local routes6 = net.routes6()
- if routes6 then
- for _, r in pairs(routes6) do
- if r.dest:prefix() == 0 and
- (not route or route.metric > r.metric)
- then
- route = r
- end
+ local route
+
+ net.routes6(function(rt)
+ if rt.dest:prefix() == 0 and (not route or route.metric > rt.metric) then
+ route = rt
end
- end
+ end)
+
return route
end
--- Determine the names of available network interfaces.
-- @return Table containing all current interface names
function net.devices()
- local devices = {}
- for line in io.lines("/proc/net/dev") do
- table.insert(devices, line:match(" *(.-):"))
+ local devs = {}
+ for k, v in ipairs(nixio.getifaddrs()) do
+ if v.family == "packet" then
+ devs[#devs+1] = v.name
+ end
end
- return devices
+ return devs
end
--- Return information about available network interfaces.
-- @return Table containing all current interface names and their information
function net.deviceinfo()
- local devices = {}
- for line in io.lines("/proc/net/dev") do
- local name, data = line:match("^ *(.-): *(.*)$")
- if name and data then
- devices[name] = luci.util.split(data, " +", nil, true)
+ local devs = {}
+ for k, v in ipairs(nixio.getifaddrs()) do
+ if v.family == "packet" then
+ local d = v.data
+ d[1] = d.rx_bytes
+ d[2] = d.rx_packets
+ d[3] = d.rx_errors
+ d[4] = d.rx_dropped
+ d[5] = 0
+ d[6] = 0
+ d[7] = 0
+ d[8] = d.multicast
+ d[9] = d.tx_bytes
+ d[10] = d.tx_packets
+ d[11] = d.tx_errors
+ d[12] = d.tx_dropped
+ d[13] = 0
+ d[14] = d.collisions
+ d[15] = 0
+ d[16] = 0
+ devs[v.name] = d
end
end
- return devices
+ return devs
end
@@ -356,13 +369,11 @@ end
-- @return String containing the MAC address or nil if it cannot be found
function net.ip4mac(ip)
local mac = nil
-
- for i, l in ipairs(net.arptable()) do
- if l["IP address"] == ip then
- mac = l["HW address"]
+ net.arptable(function(e)
+ if e["IP address"] == ip then
+ mac = e["HW address"]
end
- end
-
+ end)
return mac
end
@@ -371,7 +382,7 @@ end
-- The following fields are defined for route entry tables:
-- { "dest", "gateway", "metric", "refcount", "usecount", "irtt",
-- "flags", "device" }
-function net.routes()
+function net.routes(callback)
local routes = { }
for line in io.lines("/proc/net/route") do
@@ -389,7 +400,7 @@ function net.routes()
dst_ip, dst_mask:prefix(dst_mask), luci.ip.FAMILY_INET4
)
- routes[#routes+1] = {
+ local rt = {
dest = dst_ip,
gateway = gateway,
metric = tonumber(metric),
@@ -401,6 +412,12 @@ function net.routes()
flags = tonumber(flags, 16),
device = dev
}
+
+ if callback then
+ callback(rt)
+ else
+ routes[#routes+1] = rt
+ end
end
end
@@ -412,8 +429,8 @@ end
-- The following fields are defined for route entry tables:
-- { "source", "dest", "nexthop", "metric", "refcount", "usecount",
-- "flags", "device" }
-function net.routes6()
- if luci.fs.access("/proc/net/ipv6_route", "r") then
+function net.routes6(callback)
+ if fs.access("/proc/net/ipv6_route", "r") then
local routes = { }
for line in io.lines("/proc/net/ipv6_route") do
@@ -437,7 +454,7 @@ function net.routes6()
nexthop = luci.ip.Hex( nexthop, 128, luci.ip.FAMILY_INET6, false )
- routes[#routes+1] = {
+ local rt = {
source = src_ip,
dest = dst_ip,
nexthop = nexthop,
@@ -447,6 +464,12 @@ function net.routes6()
flags = tonumber(flags, 16),
device = dev
}
+
+ if callback then
+ callback(rt)
+ else
+ routes[#routes+1] = rt
+ end
end
return routes
@@ -665,7 +688,7 @@ function wifi.channels(iface)
fd:close()
end
- if not ((pairs(cns))(cns)) then
+ if not next(cns) then
cns = {
2.412, 2.417, 2.422, 2.427, 2.432, 2.437,
2.442, 2.447, 2.452, 2.457, 2.462
@@ -686,8 +709,8 @@ init.dir = "/etc/init.d/"
-- @return Table containing the names of all inistalled init scripts
function init.names()
local names = { }
- for _, name in ipairs(luci.fs.glob(init.dir.."*")) do
- names[#names+1] = luci.fs.basename(name)
+ for name in fs.glob(init.dir.."*") do
+ names[#names+1] = fs.basename(name)
end
return names
end
@@ -696,7 +719,7 @@ end
-- @param name Name of the init script
-- @return Boolean indicating whether init is enabled
function init.enabled(name)
- if luci.fs.access(init.dir..name) then
+ if fs.access(init.dir..name) then
return ( call(init.dir..name.." enabled") == 0 )
end
return false
@@ -706,7 +729,7 @@ end
-- @param name Name of the init script
-- @return Numeric index value
function init.index(name)
- if luci.fs.access(init.dir..name) then
+ if fs.access(init.dir..name) then
return call("source "..init.dir..name.."; exit $START")
end
end
@@ -715,7 +738,7 @@ end
-- @param name Name of the init script
-- @return Boolean indicating success
function init.enable(name)
- if luci.fs.access(init.dir..name) then
+ if fs.access(init.dir..name) then
return ( call(init.dir..name.." enable") == 1 )
end
end
@@ -724,7 +747,7 @@ end
-- @param name Name of the init script
-- @return Boolean indicating success
function init.disable(name)
- if luci.fs.access(init.dir..name) then
+ if fs.access(init.dir..name) then
return ( call(init.dir..name.." disable") == 0 )
end
end
@@ -732,7 +755,7 @@ end
-- Internal functions
-function _parse_delimited_table(iter, delimiter)
+function _parse_delimited_table(iter, delimiter, callback)
delimiter = delimiter or "%s+"
local data = {}
@@ -754,7 +777,12 @@ function _parse_delimited_table(iter, delimiter)
end
end
end
- table.insert(data, row)
+
+ if callback then
+ callback(row)
+ else
+ data[#data+1] = row
+ end
end
return data
diff --git a/libs/sys/luasrc/sys/zoneinfo.lua b/libs/sys/luasrc/sys/zoneinfo.lua
index 4bae1e1e5c..f5a12bfcb6 100644
--- a/libs/sys/luasrc/sys/zoneinfo.lua
+++ b/libs/sys/luasrc/sys/zoneinfo.lua
@@ -9,565 +9,20 @@ You may obtain a copy of the License at
]]--
+local setmetatable, require, rawget, rawset = setmetatable, require, rawget, rawset
+
module "luci.sys.zoneinfo"
-TZ = {
- { 'Africa/Abidjan', 'GMT0' },
- { 'Africa/Accra', 'GMT0' },
- { 'Africa/Addis Ababa', 'EAT-3' },
- { 'Africa/Algiers', 'CET-1' },
- { 'Africa/Asmara', 'EAT-3' },
- { 'Africa/Bamako', 'GMT0' },
- { 'Africa/Bangui', 'WAT-1' },
- { 'Africa/Banjul', 'GMT0' },
- { 'Africa/Bissau', 'GMT0' },
- { 'Africa/Blantyre', 'CAT-2' },
- { 'Africa/Brazzaville', 'WAT-1' },
- { 'Africa/Bujumbura', 'CAT-2' },
- { 'Africa/Casablanca', 'WET0' },
- { 'Africa/Ceuta', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Africa/Conakry', 'GMT0' },
- { 'Africa/Dakar', 'GMT0' },
- { 'Africa/Dar es Salaam', 'EAT-3' },
- { 'Africa/Djibouti', 'EAT-3' },
- { 'Africa/Douala', 'WAT-1' },
- { 'Africa/El Aaiun', 'WET0' },
- { 'Africa/Freetown', 'GMT0' },
- { 'Africa/Gaborone', 'CAT-2' },
- { 'Africa/Harare', 'CAT-2' },
- { 'Africa/Johannesburg', 'SAST-2' },
- { 'Africa/Kampala', 'EAT-3' },
- { 'Africa/Khartoum', 'EAT-3' },
- { 'Africa/Kigali', 'CAT-2' },
- { 'Africa/Kinshasa', 'WAT-1' },
- { 'Africa/Lagos', 'WAT-1' },
- { 'Africa/Libreville', 'WAT-1' },
- { 'Africa/Lome', 'GMT0' },
- { 'Africa/Luanda', 'WAT-1' },
- { 'Africa/Lubumbashi', 'CAT-2' },
- { 'Africa/Lusaka', 'CAT-2' },
- { 'Africa/Malabo', 'WAT-1' },
- { 'Africa/Maputo', 'CAT-2' },
- { 'Africa/Maseru', 'SAST-2' },
- { 'Africa/Mbabane', 'SAST-2' },
- { 'Africa/Mogadishu', 'EAT-3' },
- { 'Africa/Monrovia', 'GMT0' },
- { 'Africa/Nairobi', 'EAT-3' },
- { 'Africa/Ndjamena', 'WAT-1' },
- { 'Africa/Niamey', 'WAT-1' },
- { 'Africa/Nouakchott', 'GMT0' },
- { 'Africa/Ouagadougou', 'GMT0' },
- { 'Africa/Porto-Novo', 'WAT-1' },
- { 'Africa/Sao Tome', 'GMT0' },
- { 'Africa/Tripoli', 'EET-2' },
- { 'Africa/Tunis', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Africa/Windhoek', 'WAT-1WAST,M9.1.0,M4.1.0' },
- { 'America/Adak', 'HAST10HADT,M3.2.0,M11.1.0' },
- { 'America/Anchorage', 'AKST9AKDT,M3.2.0,M11.1.0' },
- { 'America/Anguilla', 'AST4' },
- { 'America/Antigua', 'AST4' },
- { 'America/Araguaina', 'BRT3' },
- { 'America/Argentina/Buenos Aires', 'ART3ARST,M10.3.0/0,M3.3.0/0' },
- { 'America/Argentina/Catamarca', 'ART3' },
- { 'America/Argentina/Cordoba', 'ART3ARST,M10.3.0/0,M3.3.0/0' },
- { 'America/Argentina/Jujuy', 'ART3' },
- { 'America/Argentina/La Rioja', 'ART3' },
- { 'America/Argentina/Mendoza', 'ART3' },
- { 'America/Argentina/Rio Gallegos', 'ART3' },
- { 'America/Argentina/Salta', 'ART3' },
- { 'America/Argentina/San Juan', 'ART3' },
- { 'America/Argentina/San Luis', 'WART4WARST,M10.3.0/0,M3.3.0/0' },
- { 'America/Argentina/Tucuman', 'ART3ARST,M10.3.0/0,M3.3.0/0' },
- { 'America/Argentina/Ushuaia', 'ART3' },
- { 'America/Aruba', 'AST4' },
- { 'America/Asuncion', 'PYT4PYST,M10.3.0/0,M3.2.0/0' },
- { 'America/Atikokan', 'EST5' },
- { 'America/Bahia', 'BRT3' },
- { 'America/Barbados', 'AST4' },
- { 'America/Belem', 'BRT3' },
- { 'America/Belize', 'CST6' },
- { 'America/Blanc-Sablon', 'AST4' },
- { 'America/Boa Vista', 'AMT4' },
- { 'America/Bogota', 'COT5' },
- { 'America/Boise', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'America/Cambridge Bay', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'America/Campo Grande', 'AMT4AMST,M10.3.0/0,M2.3.0/0' },
- { 'America/Cancun', 'CST6CDT,M4.1.0,M10.5.0' },
- { 'America/Caracas', 'VET4:30' },
- { 'America/Cayenne', 'GFT3' },
- { 'America/Cayman', 'EST5' },
- { 'America/Chicago', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Chihuahua', 'MST7MDT,M4.1.0,M10.5.0' },
- { 'America/Costa Rica', 'CST6' },
- { 'America/Cuiaba', 'AMT4AMST,M10.3.0/0,M2.3.0/0' },
- { 'America/Curacao', 'AST4' },
- { 'America/Danmarkshavn', 'GMT0' },
- { 'America/Dawson', 'PST8PDT,M3.2.0,M11.1.0' },
- { 'America/Dawson Creek', 'MST7' },
- { 'America/Denver', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'America/Detroit', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Dominica', 'AST4' },
- { 'America/Edmonton', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'America/Eirunepe', 'AMT4' },
- { 'America/El Salvador', 'CST6' },
- { 'America/Fortaleza', 'BRT3' },
- { 'America/Glace Bay', 'AST4ADT,M3.2.0,M11.1.0' },
- { 'America/Goose Bay', 'AST4ADT,M3.2.0/0:01,M11.1.0/0:01' },
- { 'America/Grand Turk', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Grenada', 'AST4' },
- { 'America/Guadeloupe', 'AST4' },
- { 'America/Guatemala', 'CST6' },
- { 'America/Guayaquil', 'ECT5' },
- { 'America/Guyana', 'GYT4' },
- { 'America/Halifax', 'AST4ADT,M3.2.0,M11.1.0' },
- { 'America/Havana', 'CST5CDT,M3.2.0/0,M10.5.0/1' },
- { 'America/Hermosillo', 'MST7' },
- { 'America/Indiana/Indianapolis', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Indiana/Knox', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Indiana/Marengo', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Indiana/Petersburg', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Indiana/Tell City', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Indiana/Vevay', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Indiana/Vincennes', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Indiana/Winamac', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Inuvik', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'America/Iqaluit', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Jamaica', 'EST5' },
- { 'America/Juneau', 'AKST9AKDT,M3.2.0,M11.1.0' },
- { 'America/Kentucky/Louisville', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Kentucky/Monticello', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/La Paz', 'BOT4' },
- { 'America/Lima', 'PET5' },
- { 'America/Los Angeles', 'PST8PDT,M3.2.0,M11.1.0' },
- { 'America/Maceio', 'BRT3' },
- { 'America/Managua', 'CST6' },
- { 'America/Manaus', 'AMT4' },
- { 'America/Marigot', 'AST4' },
- { 'America/Martinique', 'AST4' },
- { 'America/Mazatlan', 'MST7MDT,M4.1.0,M10.5.0' },
- { 'America/Menominee', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Merida', 'CST6CDT,M4.1.0,M10.5.0' },
- { 'America/Mexico City', 'CST6CDT,M4.1.0,M10.5.0' },
- { 'America/Miquelon', 'PMST3PMDT,M3.2.0,M11.1.0' },
- { 'America/Moncton', 'AST4ADT,M3.2.0,M11.1.0' },
- { 'America/Monterrey', 'CST6CDT,M4.1.0,M10.5.0' },
- { 'America/Montevideo', 'UYT3UYST,M10.1.0,M3.2.0' },
- { 'America/Montreal', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Montserrat', 'AST4' },
- { 'America/Nassau', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/New York', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Nipigon', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Nome', 'AKST9AKDT,M3.2.0,M11.1.0' },
- { 'America/Noronha', 'FNT2' },
- { 'America/North Dakota/Center', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/North Dakota/New Salem', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Panama', 'EST5' },
- { 'America/Pangnirtung', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Paramaribo', 'SRT3' },
- { 'America/Phoenix', 'MST7' },
- { 'America/Port of Spain', 'AST4' },
- { 'America/Port-au-Prince', 'EST5' },
- { 'America/Porto Velho', 'AMT4' },
- { 'America/Puerto Rico', 'AST4' },
- { 'America/Rainy River', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Rankin Inlet', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Recife', 'BRT3' },
- { 'America/Regina', 'CST6' },
- { 'America/Rio Branco', 'AMT4' },
- { 'America/Santarem', 'BRT3' },
- { 'America/Santo Domingo', 'AST4' },
- { 'America/Sao Paulo', 'BRT3BRST,M10.3.0/0,M2.3.0/0' },
- { 'America/Scoresbysund', 'EGT1EGST,M3.5.0/0,M10.5.0/1' },
- { 'America/Shiprock', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'America/St Barthelemy', 'AST4' },
- { 'America/St Johns', 'NST3:30NDT,M3.2.0/0:01,M11.1.0/0:01' },
- { 'America/St Kitts', 'AST4' },
- { 'America/St Lucia', 'AST4' },
- { 'America/St Thomas', 'AST4' },
- { 'America/St Vincent', 'AST4' },
- { 'America/Swift Current', 'CST6' },
- { 'America/Tegucigalpa', 'CST6' },
- { 'America/Thule', 'AST4ADT,M3.2.0,M11.1.0' },
- { 'America/Thunder Bay', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Tijuana', 'PST8PDT,M4.1.0,M10.5.0' },
- { 'America/Toronto', 'EST5EDT,M3.2.0,M11.1.0' },
- { 'America/Tortola', 'AST4' },
- { 'America/Vancouver', 'PST8PDT,M3.2.0,M11.1.0' },
- { 'America/Whitehorse', 'PST8PDT,M3.2.0,M11.1.0' },
- { 'America/Winnipeg', 'CST6CDT,M3.2.0,M11.1.0' },
- { 'America/Yakutat', 'AKST9AKDT,M3.2.0,M11.1.0' },
- { 'America/Yellowknife', 'MST7MDT,M3.2.0,M11.1.0' },
- { 'Antarctica/Casey', 'WST-8' },
- { 'Antarctica/Davis', 'DAVT-7' },
- { 'Antarctica/DumontDUrville', 'DDUT-10' },
- { 'Antarctica/Mawson', 'MAWT-6' },
- { 'Antarctica/McMurdo', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
- { 'Antarctica/Rothera', 'ROTT3' },
- { 'Antarctica/South Pole', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
- { 'Antarctica/Syowa', 'SYOT-3' },
- { 'Antarctica/Vostok', 'VOST-6' },
- { 'Arctic/Longyearbyen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Asia/Aden', 'AST-3' },
- { 'Asia/Almaty', 'ALMT-6' },
- { 'Asia/Amman', 'EET-2EEST,M3.5.4/0,M10.5.5/1' },
- { 'Asia/Anadyr', 'ANAT-12ANAST,M3.5.0,M10.5.0/3' },
- { 'Asia/Aqtau', 'AQTT-5' },
- { 'Asia/Aqtobe', 'AQTT-5' },
- { 'Asia/Ashgabat', 'TMT-5' },
- { 'Asia/Baghdad', 'AST-3' },
- { 'Asia/Bahrain', 'AST-3' },
- { 'Asia/Baku', 'AZT-4AZST,M3.5.0/4,M10.5.0/5' },
- { 'Asia/Bangkok', 'ICT-7' },
- { 'Asia/Beirut', 'EET-2EEST,M3.5.0/0,M10.5.0/0' },
- { 'Asia/Bishkek', 'KGT-6' },
- { 'Asia/Brunei', 'BNT-8' },
- { 'Asia/Choibalsan', 'CHOT-8' },
- { 'Asia/Chongqing', 'CST-8' },
- { 'Asia/Colombo', 'IST-5:30' },
- { 'Asia/Damascus', 'EET-2EEST,M3.5.5/0,J305/0' },
- { 'Asia/Dhaka', 'BDT-6' },
- { 'Asia/Dili', 'TLT-9' },
- { 'Asia/Dubai', 'GST-4' },
- { 'Asia/Dushanbe', 'TJT-5' },
- { 'Asia/Gaza', 'EET-2EEST,J91/0,M8.5.4' },
- { 'Asia/Harbin', 'CST-8' },
- { 'Asia/Ho Chi Minh', 'ICT-7' },
- { 'Asia/Hong Kong', 'HKT-8' },
- { 'Asia/Hovd', 'HOVT-7' },
- { 'Asia/Irkutsk', 'IRKT-8IRKST,M3.5.0,M10.5.0/3' },
- { 'Asia/Jakarta', 'WIT-7' },
- { 'Asia/Jayapura', 'EIT-9' },
- { 'Asia/Kabul', 'AFT-4:30' },
- { 'Asia/Kamchatka', 'PETT-12PETST,M3.5.0,M10.5.0/3' },
- { 'Asia/Karachi', 'PKT-5' },
- { 'Asia/Kashgar', 'CST-8' },
- { 'Asia/Kathmandu', 'NPT-5:45' },
- { 'Asia/Kolkata', 'IST-5:30' },
- { 'Asia/Krasnoyarsk', 'KRAT-7KRAST,M3.5.0,M10.5.0/3' },
- { 'Asia/Kuala Lumpur', 'MYT-8' },
- { 'Asia/Kuching', 'MYT-8' },
- { 'Asia/Kuwait', 'AST-3' },
- { 'Asia/Macau', 'CST-8' },
- { 'Asia/Magadan', 'MAGT-11MAGST,M3.5.0,M10.5.0/3' },
- { 'Asia/Makassar', 'CIT-8' },
- { 'Asia/Manila', 'PHT-8' },
- { 'Asia/Muscat', 'GST-4' },
- { 'Asia/Nicosia', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Asia/Novosibirsk', 'NOVT-6NOVST,M3.5.0,M10.5.0/3' },
- { 'Asia/Omsk', 'OMST-6OMSST,M3.5.0,M10.5.0/3' },
- { 'Asia/Oral', 'ORAT-5' },
- { 'Asia/Phnom Penh', 'ICT-7' },
- { 'Asia/Pontianak', 'WIT-7' },
- { 'Asia/Pyongyang', 'KST-9' },
- { 'Asia/Qatar', 'AST-3' },
- { 'Asia/Qyzylorda', 'QYZT-6' },
- { 'Asia/Rangoon', 'MMT-6:30' },
- { 'Asia/Riyadh', 'AST-3' },
- { 'Asia/Sakhalin', 'SAKT-10SAKST,M3.5.0,M10.5.0/3' },
- { 'Asia/Samarkand', 'UZT-5' },
- { 'Asia/Seoul', 'KST-9' },
- { 'Asia/Shanghai', 'CST-8' },
- { 'Asia/Singapore', 'SGT-8' },
- { 'Asia/Taipei', 'CST-8' },
- { 'Asia/Tashkent', 'UZT-5' },
- { 'Asia/Tbilisi', 'GET-4' },
- { 'Asia/Thimphu', 'BTT-6' },
- { 'Asia/Tokyo', 'JST-9' },
- { 'Asia/Ulaanbaatar', 'ULAT-8' },
- { 'Asia/Urumqi', 'CST-8' },
- { 'Asia/Vientiane', 'ICT-7' },
- { 'Asia/Vladivostok', 'VLAT-10VLAST,M3.5.0,M10.5.0/3' },
- { 'Asia/Yakutsk', 'YAKT-9YAKST,M3.5.0,M10.5.0/3' },
- { 'Asia/Yekaterinburg', 'YEKT-5YEKST,M3.5.0,M10.5.0/3' },
- { 'Asia/Yerevan', 'AMT-4AMST,M3.5.0,M10.5.0/3' },
- { 'Atlantic/Azores', 'AZOT1AZOST,M3.5.0/0,M10.5.0/1' },
- { 'Atlantic/Bermuda', 'AST4ADT,M3.2.0,M11.1.0' },
- { 'Atlantic/Canary', 'WET0WEST,M3.5.0/1,M10.5.0' },
- { 'Atlantic/Cape Verde', 'CVT1' },
- { 'Atlantic/Faroe', 'WET0WEST,M3.5.0/1,M10.5.0' },
- { 'Atlantic/Madeira', 'WET0WEST,M3.5.0/1,M10.5.0' },
- { 'Atlantic/Reykjavik', 'GMT0' },
- { 'Atlantic/South Georgia', 'GST2' },
- { 'Atlantic/St Helena', 'GMT0' },
- { 'Atlantic/Stanley', 'FKT4FKST,M9.1.0,M4.3.0' },
- { 'Australia/Adelaide', 'CST-9:30CST,M10.1.0,M4.1.0/3' },
- { 'Australia/Brisbane', 'EST-10' },
- { 'Australia/Broken Hill', 'CST-9:30CST,M10.1.0,M4.1.0/3' },
- { 'Australia/Currie', 'EST-10EST,M10.1.0,M4.1.0/3' },
- { 'Australia/Darwin', 'CST-9:30' },
- { 'Australia/Eucla', 'CWST-8:45' },
- { 'Australia/Hobart', 'EST-10EST,M10.1.0,M4.1.0/3' },
- { 'Australia/Lindeman', 'EST-10' },
- { 'Australia/Lord Howe', 'LHST-10:30LHST-11,M10.1.0,M4.1.0' },
- { 'Australia/Melbourne', 'EST-10EST,M10.1.0,M4.1.0/3' },
- { 'Australia/Perth', 'WST-8' },
- { 'Australia/Sydney', 'EST-10EST,M10.1.0,M4.1.0/3' },
- { 'Europe/Amsterdam', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Andorra', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Athens', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Belgrade', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Berlin', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Bratislava', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Brussels', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Bucharest', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Budapest', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Chisinau', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Copenhagen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Dublin', 'GMT0IST,M3.5.0/1,M10.5.0' },
- { 'Europe/Gibraltar', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Guernsey', 'GMT0BST,M3.5.0/1,M10.5.0' },
- { 'Europe/Helsinki', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Isle of Man', 'GMT0BST,M3.5.0/1,M10.5.0' },
- { 'Europe/Istanbul', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Jersey', 'GMT0BST,M3.5.0/1,M10.5.0' },
- { 'Europe/Kaliningrad', 'EET-2EEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Kiev', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Lisbon', 'WET0WEST,M3.5.0/1,M10.5.0' },
- { 'Europe/Ljubljana', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/London', 'GMT0BST,M3.5.0/1,M10.5.0' },
- { 'Europe/Luxembourg', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Madrid', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Malta', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Mariehamn', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Minsk', 'EET-2EEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Monaco', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Moscow', 'MSK-3MSD,M3.5.0,M10.5.0/3' },
- { 'Europe/Oslo', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Paris', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Podgorica', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Prague', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Riga', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Rome', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Samara', 'SAMT-4SAMST,M3.5.0,M10.5.0/3' },
- { 'Europe/San Marino', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Sarajevo', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Simferopol', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Skopje', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Sofia', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Stockholm', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Tallinn', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Tirane', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Uzhgorod', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Vaduz', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Vatican', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Vienna', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Vilnius', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Volgograd', 'VOLT-3VOLST,M3.5.0,M10.5.0/3' },
- { 'Europe/Warsaw', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Zagreb', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Zaporozhye', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
- { 'Europe/Zurich', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Indian/Antananarivo', 'EAT-3' },
- { 'Indian/Chagos', 'IOT-6' },
- { 'Indian/Christmas', 'CXT-7' },
- { 'Indian/Cocos', 'CCT-6:30' },
- { 'Indian/Comoro', 'EAT-3' },
- { 'Indian/Kerguelen', 'TFT-5' },
- { 'Indian/Mahe', 'SCT-4' },
- { 'Indian/Maldives', 'MVT-5' },
- { 'Indian/Mauritius', 'MUT-4MUST,M10.5.0,M3.5.0/3' },
- { 'Indian/Mayotte', 'EAT-3' },
- { 'Indian/Reunion', 'RET-4' },
- { 'Pacific/Apia', 'WST11' },
- { 'Pacific/Auckland', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
- { 'Pacific/Chatham', 'CHAST-12:45CHADT,M9.5.0/2:45,M4.1.0/3:45' },
- { 'Pacific/Efate', 'VUT-11' },
- { 'Pacific/Enderbury', 'PHOT-13' },
- { 'Pacific/Fakaofo', 'TKT10' },
- { 'Pacific/Fiji', 'FJT-12' },
- { 'Pacific/Funafuti', 'TVT-12' },
- { 'Pacific/Galapagos', 'GALT6' },
- { 'Pacific/Gambier', 'GAMT9' },
- { 'Pacific/Guadalcanal', 'SBT-11' },
- { 'Pacific/Guam', 'ChST-10' },
- { 'Pacific/Honolulu', 'HST10' },
- { 'Pacific/Johnston', 'HST10' },
- { 'Pacific/Kiritimati', 'LINT-14' },
- { 'Pacific/Kosrae', 'KOST-11' },
- { 'Pacific/Kwajalein', 'MHT-12' },
- { 'Pacific/Majuro', 'MHT-12' },
- { 'Pacific/Marquesas', 'MART9:30' },
- { 'Pacific/Midway', 'SST11' },
- { 'Pacific/Nauru', 'NRT-12' },
- { 'Pacific/Niue', 'NUT11' },
- { 'Pacific/Norfolk', 'NFT-11:30' },
- { 'Pacific/Noumea', 'NCT-11' },
- { 'Pacific/Pago Pago', 'SST11' },
- { 'Pacific/Palau', 'PWT-9' },
- { 'Pacific/Pitcairn', 'PST8' },
- { 'Pacific/Ponape', 'PONT-11' },
- { 'Pacific/Port Moresby', 'PGT-10' },
- { 'Pacific/Rarotonga', 'CKT10' },
- { 'Pacific/Saipan', 'ChST-10' },
- { 'Pacific/Tahiti', 'TAHT10' },
- { 'Pacific/Tarawa', 'GILT-12' },
- { 'Pacific/Tongatapu', 'TOT-13' },
- { 'Pacific/Truk', 'TRUT-10' },
- { 'Pacific/Wake', 'WAKT-12' },
- { 'Pacific/Wallis', 'WFT-12' },
-}
+setmetatable(_M, {
+ __index = function(t, k)
+ if k == "TZ" and not rawget(t, k) then
+ local m = require "luci.sys.zoneinfo.tzdata"
+ rawset(t, k, rawget(m, k))
+ elseif k == "OFFSET" and not rawget(t, k) then
+ local m = require "luci.sys.zoneinfo.tzoffset"
+ rawset(t, k, rawget(m, k))
+ end
-OFFSET = {
- gmt = 0, -- GMT
- eat = 10800, -- EAT
- cet = 3600, -- CET
- wat = 3600, -- WAT
- cat = 7200, -- CAT
- wet = 0, -- WET
- sast = 7200, -- SAST
- eet = 7200, -- EET
- hast = -36000, -- HAST
- hadt = -32400, -- HADT
- akst = -32400, -- AKST
- akdt = -28800, -- AKDT
- ast = -14400, -- AST
- brt = -10800, -- BRT
- art = -10800, -- ART
- arst = -7200, -- ARST
- wart = -14400, -- WART
- warst = -10800, -- WARST
- pyt = -14400, -- PYT
- pyst = -10800, -- PYST
- est = -18000, -- EST
- cst = -21600, -- CST
- amt = -14400, -- AMT
- cot = -18000, -- COT
- mst = -25200, -- MST
- mdt = -21600, -- MDT
- vet = -16200, -- VET
- gft = -10800, -- GFT
- pst = -28800, -- PST
- pdt = -25200, -- PDT
- ect = -18000, -- ECT
- gyt = -14400, -- GYT
- bot = -14400, -- BOT
- pet = -18000, -- PET
- pmst = -10800, -- PMST
- pmdt = -7200, -- PMDT
- uyt = -10800, -- UYT
- uyst = -7200, -- UYST
- fnt = -7200, -- FNT
- srt = -10800, -- SRT
- egt = -3600, -- EGT
- egst = 0, -- EGST
- nst = -12600, -- NST
- ndt = -9000, -- NDT
- wst = 28800, -- WST
- davt = 25200, -- DAVT
- ddut = 36000, -- DDUT
- mawt = 21600, -- MAWT
- nzst = 43200, -- NZST
- nzdt = 46800, -- NZDT
- rott = -10800, -- ROTT
- syot = 10800, -- SYOT
- vost = 21600, -- VOST
- almt = 21600, -- ALMT
- anat = 43200, -- ANAT
- anast = 46800, -- ANAST
- aqtt = 18000, -- AQTT
- tmt = 18000, -- TMT
- azt = 14400, -- AZT
- azst = 18000, -- AZST
- ict = 25200, -- ICT
- kgt = 21600, -- KGT
- bnt = 28800, -- BNT
- chot = 28800, -- CHOT
- ist = 19800, -- IST
- bdt = 21600, -- BDT
- tlt = 32400, -- TLT
- gst = 14400, -- GST
- tjt = 18000, -- TJT
- hkt = 28800, -- HKT
- hovt = 25200, -- HOVT
- irkt = 28800, -- IRKT
- irkst = 32400, -- IRKST
- wit = 25200, -- WIT
- eit = 32400, -- EIT
- aft = 16200, -- AFT
- pett = 43200, -- PETT
- petst = 46800, -- PETST
- pkt = 18000, -- PKT
- npt = 20700, -- NPT
- krat = 25200, -- KRAT
- krast = 28800, -- KRAST
- myt = 28800, -- MYT
- magt = 39600, -- MAGT
- magst = 43200, -- MAGST
- cit = 28800, -- CIT
- pht = 28800, -- PHT
- novt = 21600, -- NOVT
- novst = 25200, -- NOVST
- omst = 21600, -- OMST
- omsst = 25200, -- OMSST
- orat = 18000, -- ORAT
- kst = 32400, -- KST
- qyzt = 21600, -- QYZT
- mmt = 23400, -- MMT
- sakt = 36000, -- SAKT
- sakst = 39600, -- SAKST
- uzt = 18000, -- UZT
- sgt = 28800, -- SGT
- get = 14400, -- GET
- btt = 21600, -- BTT
- jst = 32400, -- JST
- ulat = 28800, -- ULAT
- vlat = 36000, -- VLAT
- vlast = 39600, -- VLAST
- yakt = 32400, -- YAKT
- yakst = 36000, -- YAKST
- yekt = 18000, -- YEKT
- yekst = 21600, -- YEKST
- azot = -3600, -- AZOT
- azost = 0, -- AZOST
- cvt = -3600, -- CVT
- fkt = -14400, -- FKT
- fkst = -10800, -- FKST
- cwst = 31500, -- CWST
- lhst = 37800, -- LHST
- lhst = 39600, -- LHST
- msk = 10800, -- MSK
- msd = 14400, -- MSD
- samt = 14400, -- SAMT
- samst = 18000, -- SAMST
- volt = 10800, -- VOLT
- volst = 14400, -- VOLST
- iot = 21600, -- IOT
- cxt = 25200, -- CXT
- cct = 23400, -- CCT
- tft = 18000, -- TFT
- sct = 14400, -- SCT
- mvt = 18000, -- MVT
- mut = 14400, -- MUT
- must = 18000, -- MUST
- ret = 14400, -- RET
- chast = 45900, -- CHAST
- chadt = 49500, -- CHADT
- vut = 39600, -- VUT
- phot = 46800, -- PHOT
- tkt = -36000, -- TKT
- fjt = 43200, -- FJT
- tvt = 43200, -- TVT
- galt = -21600, -- GALT
- gamt = -32400, -- GAMT
- sbt = 39600, -- SBT
- hst = -36000, -- HST
- lint = 50400, -- LINT
- kost = 39600, -- KOST
- mht = 43200, -- MHT
- mart = -34200, -- MART
- sst = -39600, -- SST
- nrt = 43200, -- NRT
- nut = -39600, -- NUT
- nft = 41400, -- NFT
- nct = 39600, -- NCT
- pwt = 32400, -- PWT
- pont = 39600, -- PONT
- pgt = 36000, -- PGT
- ckt = -36000, -- CKT
- taht = -36000, -- TAHT
- gilt = 43200, -- GILT
- tot = 46800, -- TOT
- trut = 36000, -- TRUT
- wakt = 43200, -- WAKT
- wft = 43200, -- WFT
-}
+ return rawget(t, k)
+ end
+})
diff --git a/libs/sys/luasrc/sys/zoneinfo/tzdata.lua b/libs/sys/luasrc/sys/zoneinfo/tzdata.lua
new file mode 100644
index 0000000000..1fd02c4bb5
--- /dev/null
+++ b/libs/sys/luasrc/sys/zoneinfo/tzdata.lua
@@ -0,0 +1,408 @@
+--[[
+LuCI - Autogenerated Zoneinfo Module
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+]]--
+
+module "luci.sys.zoneinfo.tzdata"
+
+TZ = {
+ { 'Africa/Abidjan', 'GMT0' },
+ { 'Africa/Accra', 'GMT0' },
+ { 'Africa/Addis Ababa', 'EAT-3' },
+ { 'Africa/Algiers', 'CET-1' },
+ { 'Africa/Asmara', 'EAT-3' },
+ { 'Africa/Bamako', 'GMT0' },
+ { 'Africa/Bangui', 'WAT-1' },
+ { 'Africa/Banjul', 'GMT0' },
+ { 'Africa/Bissau', 'GMT0' },
+ { 'Africa/Blantyre', 'CAT-2' },
+ { 'Africa/Brazzaville', 'WAT-1' },
+ { 'Africa/Bujumbura', 'CAT-2' },
+ { 'Africa/Casablanca', 'WET0' },
+ { 'Africa/Ceuta', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Africa/Conakry', 'GMT0' },
+ { 'Africa/Dakar', 'GMT0' },
+ { 'Africa/Dar es Salaam', 'EAT-3' },
+ { 'Africa/Djibouti', 'EAT-3' },
+ { 'Africa/Douala', 'WAT-1' },
+ { 'Africa/El Aaiun', 'WET0' },
+ { 'Africa/Freetown', 'GMT0' },
+ { 'Africa/Gaborone', 'CAT-2' },
+ { 'Africa/Harare', 'CAT-2' },
+ { 'Africa/Johannesburg', 'SAST-2' },
+ { 'Africa/Kampala', 'EAT-3' },
+ { 'Africa/Khartoum', 'EAT-3' },
+ { 'Africa/Kigali', 'CAT-2' },
+ { 'Africa/Kinshasa', 'WAT-1' },
+ { 'Africa/Lagos', 'WAT-1' },
+ { 'Africa/Libreville', 'WAT-1' },
+ { 'Africa/Lome', 'GMT0' },
+ { 'Africa/Luanda', 'WAT-1' },
+ { 'Africa/Lubumbashi', 'CAT-2' },
+ { 'Africa/Lusaka', 'CAT-2' },
+ { 'Africa/Malabo', 'WAT-1' },
+ { 'Africa/Maputo', 'CAT-2' },
+ { 'Africa/Maseru', 'SAST-2' },
+ { 'Africa/Mbabane', 'SAST-2' },
+ { 'Africa/Mogadishu', 'EAT-3' },
+ { 'Africa/Monrovia', 'GMT0' },
+ { 'Africa/Nairobi', 'EAT-3' },
+ { 'Africa/Ndjamena', 'WAT-1' },
+ { 'Africa/Niamey', 'WAT-1' },
+ { 'Africa/Nouakchott', 'GMT0' },
+ { 'Africa/Ouagadougou', 'GMT0' },
+ { 'Africa/Porto-Novo', 'WAT-1' },
+ { 'Africa/Sao Tome', 'GMT0' },
+ { 'Africa/Tripoli', 'EET-2' },
+ { 'Africa/Tunis', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Africa/Windhoek', 'WAT-1WAST,M9.1.0,M4.1.0' },
+ { 'America/Adak', 'HAST10HADT,M3.2.0,M11.1.0' },
+ { 'America/Anchorage', 'AKST9AKDT,M3.2.0,M11.1.0' },
+ { 'America/Anguilla', 'AST4' },
+ { 'America/Antigua', 'AST4' },
+ { 'America/Araguaina', 'BRT3' },
+ { 'America/Argentina/Buenos Aires', 'ART3ARST,M10.3.0/0,M3.3.0/0' },
+ { 'America/Argentina/Catamarca', 'ART3' },
+ { 'America/Argentina/Cordoba', 'ART3ARST,M10.3.0/0,M3.3.0/0' },
+ { 'America/Argentina/Jujuy', 'ART3' },
+ { 'America/Argentina/La Rioja', 'ART3' },
+ { 'America/Argentina/Mendoza', 'ART3' },
+ { 'America/Argentina/Rio Gallegos', 'ART3' },
+ { 'America/Argentina/Salta', 'ART3' },
+ { 'America/Argentina/San Juan', 'ART3' },
+ { 'America/Argentina/San Luis', 'WART4WARST,M10.3.0/0,M3.3.0/0' },
+ { 'America/Argentina/Tucuman', 'ART3ARST,M10.3.0/0,M3.3.0/0' },
+ { 'America/Argentina/Ushuaia', 'ART3' },
+ { 'America/Aruba', 'AST4' },
+ { 'America/Asuncion', 'PYT4PYST,M10.3.0/0,M3.2.0/0' },
+ { 'America/Atikokan', 'EST5' },
+ { 'America/Bahia', 'BRT3' },
+ { 'America/Barbados', 'AST4' },
+ { 'America/Belem', 'BRT3' },
+ { 'America/Belize', 'CST6' },
+ { 'America/Blanc-Sablon', 'AST4' },
+ { 'America/Boa Vista', 'AMT4' },
+ { 'America/Bogota', 'COT5' },
+ { 'America/Boise', 'MST7MDT,M3.2.0,M11.1.0' },
+ { 'America/Cambridge Bay', 'MST7MDT,M3.2.0,M11.1.0' },
+ { 'America/Campo Grande', 'AMT4AMST,M10.3.0/0,M2.3.0/0' },
+ { 'America/Cancun', 'CST6CDT,M4.1.0,M10.5.0' },
+ { 'America/Caracas', 'VET4:30' },
+ { 'America/Cayenne', 'GFT3' },
+ { 'America/Cayman', 'EST5' },
+ { 'America/Chicago', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/Chihuahua', 'MST7MDT,M4.1.0,M10.5.0' },
+ { 'America/Costa Rica', 'CST6' },
+ { 'America/Cuiaba', 'AMT4AMST,M10.3.0/0,M2.3.0/0' },
+ { 'America/Curacao', 'AST4' },
+ { 'America/Danmarkshavn', 'GMT0' },
+ { 'America/Dawson', 'PST8PDT,M3.2.0,M11.1.0' },
+ { 'America/Dawson Creek', 'MST7' },
+ { 'America/Denver', 'MST7MDT,M3.2.0,M11.1.0' },
+ { 'America/Detroit', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Dominica', 'AST4' },
+ { 'America/Edmonton', 'MST7MDT,M3.2.0,M11.1.0' },
+ { 'America/Eirunepe', 'AMT4' },
+ { 'America/El Salvador', 'CST6' },
+ { 'America/Fortaleza', 'BRT3' },
+ { 'America/Glace Bay', 'AST4ADT,M3.2.0,M11.1.0' },
+ { 'America/Goose Bay', 'AST4ADT,M3.2.0/0:01,M11.1.0/0:01' },
+ { 'America/Grand Turk', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Grenada', 'AST4' },
+ { 'America/Guadeloupe', 'AST4' },
+ { 'America/Guatemala', 'CST6' },
+ { 'America/Guayaquil', 'ECT5' },
+ { 'America/Guyana', 'GYT4' },
+ { 'America/Halifax', 'AST4ADT,M3.2.0,M11.1.0' },
+ { 'America/Havana', 'CST5CDT,M3.2.0/0,M10.5.0/1' },
+ { 'America/Hermosillo', 'MST7' },
+ { 'America/Indiana/Indianapolis', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Indiana/Knox', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/Indiana/Marengo', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Indiana/Petersburg', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Indiana/Tell City', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/Indiana/Vevay', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Indiana/Vincennes', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Indiana/Winamac', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Inuvik', 'MST7MDT,M3.2.0,M11.1.0' },
+ { 'America/Iqaluit', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Jamaica', 'EST5' },
+ { 'America/Juneau', 'AKST9AKDT,M3.2.0,M11.1.0' },
+ { 'America/Kentucky/Louisville', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Kentucky/Monticello', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/La Paz', 'BOT4' },
+ { 'America/Lima', 'PET5' },
+ { 'America/Los Angeles', 'PST8PDT,M3.2.0,M11.1.0' },
+ { 'America/Maceio', 'BRT3' },
+ { 'America/Managua', 'CST6' },
+ { 'America/Manaus', 'AMT4' },
+ { 'America/Marigot', 'AST4' },
+ { 'America/Martinique', 'AST4' },
+ { 'America/Mazatlan', 'MST7MDT,M4.1.0,M10.5.0' },
+ { 'America/Menominee', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/Merida', 'CST6CDT,M4.1.0,M10.5.0' },
+ { 'America/Mexico City', 'CST6CDT,M4.1.0,M10.5.0' },
+ { 'America/Miquelon', 'PMST3PMDT,M3.2.0,M11.1.0' },
+ { 'America/Moncton', 'AST4ADT,M3.2.0,M11.1.0' },
+ { 'America/Monterrey', 'CST6CDT,M4.1.0,M10.5.0' },
+ { 'America/Montevideo', 'UYT3UYST,M10.1.0,M3.2.0' },
+ { 'America/Montreal', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Montserrat', 'AST4' },
+ { 'America/Nassau', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/New York', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Nipigon', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Nome', 'AKST9AKDT,M3.2.0,M11.1.0' },
+ { 'America/Noronha', 'FNT2' },
+ { 'America/North Dakota/Center', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/North Dakota/New Salem', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/Panama', 'EST5' },
+ { 'America/Pangnirtung', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Paramaribo', 'SRT3' },
+ { 'America/Phoenix', 'MST7' },
+ { 'America/Port of Spain', 'AST4' },
+ { 'America/Port-au-Prince', 'EST5' },
+ { 'America/Porto Velho', 'AMT4' },
+ { 'America/Puerto Rico', 'AST4' },
+ { 'America/Rainy River', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/Rankin Inlet', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/Recife', 'BRT3' },
+ { 'America/Regina', 'CST6' },
+ { 'America/Rio Branco', 'AMT4' },
+ { 'America/Santarem', 'BRT3' },
+ { 'America/Santo Domingo', 'AST4' },
+ { 'America/Sao Paulo', 'BRT3BRST,M10.3.0/0,M2.3.0/0' },
+ { 'America/Scoresbysund', 'EGT1EGST,M3.5.0/0,M10.5.0/1' },
+ { 'America/Shiprock', 'MST7MDT,M3.2.0,M11.1.0' },
+ { 'America/St Barthelemy', 'AST4' },
+ { 'America/St Johns', 'NST3:30NDT,M3.2.0/0:01,M11.1.0/0:01' },
+ { 'America/St Kitts', 'AST4' },
+ { 'America/St Lucia', 'AST4' },
+ { 'America/St Thomas', 'AST4' },
+ { 'America/St Vincent', 'AST4' },
+ { 'America/Swift Current', 'CST6' },
+ { 'America/Tegucigalpa', 'CST6' },
+ { 'America/Thule', 'AST4ADT,M3.2.0,M11.1.0' },
+ { 'America/Thunder Bay', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Tijuana', 'PST8PDT,M4.1.0,M10.5.0' },
+ { 'America/Toronto', 'EST5EDT,M3.2.0,M11.1.0' },
+ { 'America/Tortola', 'AST4' },
+ { 'America/Vancouver', 'PST8PDT,M3.2.0,M11.1.0' },
+ { 'America/Whitehorse', 'PST8PDT,M3.2.0,M11.1.0' },
+ { 'America/Winnipeg', 'CST6CDT,M3.2.0,M11.1.0' },
+ { 'America/Yakutat', 'AKST9AKDT,M3.2.0,M11.1.0' },
+ { 'America/Yellowknife', 'MST7MDT,M3.2.0,M11.1.0' },
+ { 'Antarctica/Casey', 'WST-8' },
+ { 'Antarctica/Davis', 'DAVT-7' },
+ { 'Antarctica/DumontDUrville', 'DDUT-10' },
+ { 'Antarctica/Mawson', 'MAWT-6' },
+ { 'Antarctica/McMurdo', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
+ { 'Antarctica/Rothera', 'ROTT3' },
+ { 'Antarctica/South Pole', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
+ { 'Antarctica/Syowa', 'SYOT-3' },
+ { 'Antarctica/Vostok', 'VOST-6' },
+ { 'Arctic/Longyearbyen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Aden', 'AST-3' },
+ { 'Asia/Almaty', 'ALMT-6' },
+ { 'Asia/Amman', 'EET-2EEST,M3.5.4/0,M10.5.5/1' },
+ { 'Asia/Anadyr', 'ANAT-12ANAST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Aqtau', 'AQTT-5' },
+ { 'Asia/Aqtobe', 'AQTT-5' },
+ { 'Asia/Ashgabat', 'TMT-5' },
+ { 'Asia/Baghdad', 'AST-3' },
+ { 'Asia/Bahrain', 'AST-3' },
+ { 'Asia/Baku', 'AZT-4AZST,M3.5.0/4,M10.5.0/5' },
+ { 'Asia/Bangkok', 'ICT-7' },
+ { 'Asia/Beirut', 'EET-2EEST,M3.5.0/0,M10.5.0/0' },
+ { 'Asia/Bishkek', 'KGT-6' },
+ { 'Asia/Brunei', 'BNT-8' },
+ { 'Asia/Choibalsan', 'CHOT-8' },
+ { 'Asia/Chongqing', 'CST-8' },
+ { 'Asia/Colombo', 'IST-5:30' },
+ { 'Asia/Damascus', 'EET-2EEST,M3.5.5/0,J305/0' },
+ { 'Asia/Dhaka', 'BDT-6' },
+ { 'Asia/Dili', 'TLT-9' },
+ { 'Asia/Dubai', 'GST-4' },
+ { 'Asia/Dushanbe', 'TJT-5' },
+ { 'Asia/Gaza', 'EET-2EEST,J91/0,M8.5.4' },
+ { 'Asia/Harbin', 'CST-8' },
+ { 'Asia/Ho Chi Minh', 'ICT-7' },
+ { 'Asia/Hong Kong', 'HKT-8' },
+ { 'Asia/Hovd', 'HOVT-7' },
+ { 'Asia/Irkutsk', 'IRKT-8IRKST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Jakarta', 'WIT-7' },
+ { 'Asia/Jayapura', 'EIT-9' },
+ { 'Asia/Kabul', 'AFT-4:30' },
+ { 'Asia/Kamchatka', 'PETT-12PETST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Karachi', 'PKT-5' },
+ { 'Asia/Kashgar', 'CST-8' },
+ { 'Asia/Kathmandu', 'NPT-5:45' },
+ { 'Asia/Kolkata', 'IST-5:30' },
+ { 'Asia/Krasnoyarsk', 'KRAT-7KRAST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Kuala Lumpur', 'MYT-8' },
+ { 'Asia/Kuching', 'MYT-8' },
+ { 'Asia/Kuwait', 'AST-3' },
+ { 'Asia/Macau', 'CST-8' },
+ { 'Asia/Magadan', 'MAGT-11MAGST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Makassar', 'CIT-8' },
+ { 'Asia/Manila', 'PHT-8' },
+ { 'Asia/Muscat', 'GST-4' },
+ { 'Asia/Nicosia', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Asia/Novosibirsk', 'NOVT-6NOVST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Omsk', 'OMST-6OMSST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Oral', 'ORAT-5' },
+ { 'Asia/Phnom Penh', 'ICT-7' },
+ { 'Asia/Pontianak', 'WIT-7' },
+ { 'Asia/Pyongyang', 'KST-9' },
+ { 'Asia/Qatar', 'AST-3' },
+ { 'Asia/Qyzylorda', 'QYZT-6' },
+ { 'Asia/Rangoon', 'MMT-6:30' },
+ { 'Asia/Riyadh', 'AST-3' },
+ { 'Asia/Sakhalin', 'SAKT-10SAKST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Samarkand', 'UZT-5' },
+ { 'Asia/Seoul', 'KST-9' },
+ { 'Asia/Shanghai', 'CST-8' },
+ { 'Asia/Singapore', 'SGT-8' },
+ { 'Asia/Taipei', 'CST-8' },
+ { 'Asia/Tashkent', 'UZT-5' },
+ { 'Asia/Tbilisi', 'GET-4' },
+ { 'Asia/Thimphu', 'BTT-6' },
+ { 'Asia/Tokyo', 'JST-9' },
+ { 'Asia/Ulaanbaatar', 'ULAT-8' },
+ { 'Asia/Urumqi', 'CST-8' },
+ { 'Asia/Vientiane', 'ICT-7' },
+ { 'Asia/Vladivostok', 'VLAT-10VLAST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Yakutsk', 'YAKT-9YAKST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Yekaterinburg', 'YEKT-5YEKST,M3.5.0,M10.5.0/3' },
+ { 'Asia/Yerevan', 'AMT-4AMST,M3.5.0,M10.5.0/3' },
+ { 'Atlantic/Azores', 'AZOT1AZOST,M3.5.0/0,M10.5.0/1' },
+ { 'Atlantic/Bermuda', 'AST4ADT,M3.2.0,M11.1.0' },
+ { 'Atlantic/Canary', 'WET0WEST,M3.5.0/1,M10.5.0' },
+ { 'Atlantic/Cape Verde', 'CVT1' },
+ { 'Atlantic/Faroe', 'WET0WEST,M3.5.0/1,M10.5.0' },
+ { 'Atlantic/Madeira', 'WET0WEST,M3.5.0/1,M10.5.0' },
+ { 'Atlantic/Reykjavik', 'GMT0' },
+ { 'Atlantic/South Georgia', 'GST2' },
+ { 'Atlantic/St Helena', 'GMT0' },
+ { 'Atlantic/Stanley', 'FKT4FKST,M9.1.0,M4.3.0' },
+ { 'Australia/Adelaide', 'CST-9:30CST,M10.1.0,M4.1.0/3' },
+ { 'Australia/Brisbane', 'EST-10' },
+ { 'Australia/Broken Hill', 'CST-9:30CST,M10.1.0,M4.1.0/3' },
+ { 'Australia/Currie', 'EST-10EST,M10.1.0,M4.1.0/3' },
+ { 'Australia/Darwin', 'CST-9:30' },
+ { 'Australia/Eucla', 'CWST-8:45' },
+ { 'Australia/Hobart', 'EST-10EST,M10.1.0,M4.1.0/3' },
+ { 'Australia/Lindeman', 'EST-10' },
+ { 'Australia/Lord Howe', 'LHST-10:30LHST-11,M10.1.0,M4.1.0' },
+ { 'Australia/Melbourne', 'EST-10EST,M10.1.0,M4.1.0/3' },
+ { 'Australia/Perth', 'WST-8' },
+ { 'Australia/Sydney', 'EST-10EST,M10.1.0,M4.1.0/3' },
+ { 'Europe/Amsterdam', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Andorra', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Athens', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Belgrade', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Berlin', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Bratislava', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Brussels', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Bucharest', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Budapest', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Chisinau', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Copenhagen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Dublin', 'GMT0IST,M3.5.0/1,M10.5.0' },
+ { 'Europe/Gibraltar', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Guernsey', 'GMT0BST,M3.5.0/1,M10.5.0' },
+ { 'Europe/Helsinki', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Isle of Man', 'GMT0BST,M3.5.0/1,M10.5.0' },
+ { 'Europe/Istanbul', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Jersey', 'GMT0BST,M3.5.0/1,M10.5.0' },
+ { 'Europe/Kaliningrad', 'EET-2EEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Kiev', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Lisbon', 'WET0WEST,M3.5.0/1,M10.5.0' },
+ { 'Europe/Ljubljana', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/London', 'GMT0BST,M3.5.0/1,M10.5.0' },
+ { 'Europe/Luxembourg', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Madrid', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Malta', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Mariehamn', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Minsk', 'EET-2EEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Monaco', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Moscow', 'MSK-3MSD,M3.5.0,M10.5.0/3' },
+ { 'Europe/Oslo', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Paris', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Podgorica', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Prague', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Riga', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Rome', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Samara', 'SAMT-4SAMST,M3.5.0,M10.5.0/3' },
+ { 'Europe/San Marino', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Sarajevo', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Simferopol', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Skopje', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Sofia', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Stockholm', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Tallinn', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Tirane', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Uzhgorod', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Vaduz', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Vatican', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Vienna', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Vilnius', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Volgograd', 'VOLT-3VOLST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Warsaw', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Zagreb', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Europe/Zaporozhye', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Zurich', 'CET-1CEST,M3.5.0,M10.5.0/3' },
+ { 'Indian/Antananarivo', 'EAT-3' },
+ { 'Indian/Chagos', 'IOT-6' },
+ { 'Indian/Christmas', 'CXT-7' },
+ { 'Indian/Cocos', 'CCT-6:30' },
+ { 'Indian/Comoro', 'EAT-3' },
+ { 'Indian/Kerguelen', 'TFT-5' },
+ { 'Indian/Mahe', 'SCT-4' },
+ { 'Indian/Maldives', 'MVT-5' },
+ { 'Indian/Mauritius', 'MUT-4MUST,M10.5.0,M3.5.0/3' },
+ { 'Indian/Mayotte', 'EAT-3' },
+ { 'Indian/Reunion', 'RET-4' },
+ { 'Pacific/Apia', 'WST11' },
+ { 'Pacific/Auckland', 'NZST-12NZDT,M9.5.0,M4.1.0/3' },
+ { 'Pacific/Chatham', 'CHAST-12:45CHADT,M9.5.0/2:45,M4.1.0/3:45' },
+ { 'Pacific/Efate', 'VUT-11' },
+ { 'Pacific/Enderbury', 'PHOT-13' },
+ { 'Pacific/Fakaofo', 'TKT10' },
+ { 'Pacific/Fiji', 'FJT-12' },
+ { 'Pacific/Funafuti', 'TVT-12' },
+ { 'Pacific/Galapagos', 'GALT6' },
+ { 'Pacific/Gambier', 'GAMT9' },
+ { 'Pacific/Guadalcanal', 'SBT-11' },
+ { 'Pacific/Guam', 'ChST-10' },
+ { 'Pacific/Honolulu', 'HST10' },
+ { 'Pacific/Johnston', 'HST10' },
+ { 'Pacific/Kiritimati', 'LINT-14' },
+ { 'Pacific/Kosrae', 'KOST-11' },
+ { 'Pacific/Kwajalein', 'MHT-12' },
+ { 'Pacific/Majuro', 'MHT-12' },
+ { 'Pacific/Marquesas', 'MART9:30' },
+ { 'Pacific/Midway', 'SST11' },
+ { 'Pacific/Nauru', 'NRT-12' },
+ { 'Pacific/Niue', 'NUT11' },
+ { 'Pacific/Norfolk', 'NFT-11:30' },
+ { 'Pacific/Noumea', 'NCT-11' },
+ { 'Pacific/Pago Pago', 'SST11' },
+ { 'Pacific/Palau', 'PWT-9' },
+ { 'Pacific/Pitcairn', 'PST8' },
+ { 'Pacific/Ponape', 'PONT-11' },
+ { 'Pacific/Port Moresby', 'PGT-10' },
+ { 'Pacific/Rarotonga', 'CKT10' },
+ { 'Pacific/Saipan', 'ChST-10' },
+ { 'Pacific/Tahiti', 'TAHT10' },
+ { 'Pacific/Tarawa', 'GILT-12' },
+ { 'Pacific/Tongatapu', 'TOT-13' },
+ { 'Pacific/Truk', 'TRUT-10' },
+ { 'Pacific/Wake', 'WAKT-12' },
+ { 'Pacific/Wallis', 'WFT-12' },
+}
diff --git a/libs/sys/luasrc/sys/zoneinfo/tzoffset.lua b/libs/sys/luasrc/sys/zoneinfo/tzoffset.lua
new file mode 100644
index 0000000000..b396345c9a
--- /dev/null
+++ b/libs/sys/luasrc/sys/zoneinfo/tzoffset.lua
@@ -0,0 +1,177 @@
+--[[
+LuCI - Autogenerated Zoneinfo Module
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+]]--
+
+module "luci.sys.zoneinfo.tzoffset"
+
+OFFSET = {
+ gmt = 0, -- GMT
+ eat = 10800, -- EAT
+ cet = 3600, -- CET
+ wat = 3600, -- WAT
+ cat = 7200, -- CAT
+ wet = 0, -- WET
+ sast = 7200, -- SAST
+ eet = 7200, -- EET
+ hast = -36000, -- HAST
+ hadt = -32400, -- HADT
+ akst = -32400, -- AKST
+ akdt = -28800, -- AKDT
+ ast = -14400, -- AST
+ brt = -10800, -- BRT
+ art = -10800, -- ART
+ arst = -7200, -- ARST
+ wart = -14400, -- WART
+ warst = -10800, -- WARST
+ pyt = -14400, -- PYT
+ pyst = -10800, -- PYST
+ est = -18000, -- EST
+ cst = -21600, -- CST
+ amt = -14400, -- AMT
+ cot = -18000, -- COT
+ mst = -25200, -- MST
+ mdt = -21600, -- MDT
+ vet = -16200, -- VET
+ gft = -10800, -- GFT
+ pst = -28800, -- PST
+ pdt = -25200, -- PDT
+ ect = -18000, -- ECT
+ gyt = -14400, -- GYT
+ bot = -14400, -- BOT
+ pet = -18000, -- PET
+ pmst = -10800, -- PMST
+ pmdt = -7200, -- PMDT
+ uyt = -10800, -- UYT
+ uyst = -7200, -- UYST
+ fnt = -7200, -- FNT
+ srt = -10800, -- SRT
+ egt = -3600, -- EGT
+ egst = 0, -- EGST
+ nst = -12600, -- NST
+ ndt = -9000, -- NDT
+ wst = 28800, -- WST
+ davt = 25200, -- DAVT
+ ddut = 36000, -- DDUT
+ mawt = 21600, -- MAWT
+ nzst = 43200, -- NZST
+ nzdt = 46800, -- NZDT
+ rott = -10800, -- ROTT
+ syot = 10800, -- SYOT
+ vost = 21600, -- VOST
+ almt = 21600, -- ALMT
+ anat = 43200, -- ANAT
+ anast = 46800, -- ANAST
+ aqtt = 18000, -- AQTT
+ tmt = 18000, -- TMT
+ azt = 14400, -- AZT
+ azst = 18000, -- AZST
+ ict = 25200, -- ICT
+ kgt = 21600, -- KGT
+ bnt = 28800, -- BNT
+ chot = 28800, -- CHOT
+ ist = 19800, -- IST
+ bdt = 21600, -- BDT
+ tlt = 32400, -- TLT
+ gst = 14400, -- GST
+ tjt = 18000, -- TJT
+ hkt = 28800, -- HKT
+ hovt = 25200, -- HOVT
+ irkt = 28800, -- IRKT
+ irkst = 32400, -- IRKST
+ wit = 25200, -- WIT
+ eit = 32400, -- EIT
+ aft = 16200, -- AFT
+ pett = 43200, -- PETT
+ petst = 46800, -- PETST
+ pkt = 18000, -- PKT
+ npt = 20700, -- NPT
+ krat = 25200, -- KRAT
+ krast = 28800, -- KRAST
+ myt = 28800, -- MYT
+ magt = 39600, -- MAGT
+ magst = 43200, -- MAGST
+ cit = 28800, -- CIT
+ pht = 28800, -- PHT
+ novt = 21600, -- NOVT
+ novst = 25200, -- NOVST
+ omst = 21600, -- OMST
+ omsst = 25200, -- OMSST
+ orat = 18000, -- ORAT
+ kst = 32400, -- KST
+ qyzt = 21600, -- QYZT
+ mmt = 23400, -- MMT
+ sakt = 36000, -- SAKT
+ sakst = 39600, -- SAKST
+ uzt = 18000, -- UZT
+ sgt = 28800, -- SGT
+ get = 14400, -- GET
+ btt = 21600, -- BTT
+ jst = 32400, -- JST
+ ulat = 28800, -- ULAT
+ vlat = 36000, -- VLAT
+ vlast = 39600, -- VLAST
+ yakt = 32400, -- YAKT
+ yakst = 36000, -- YAKST
+ yekt = 18000, -- YEKT
+ yekst = 21600, -- YEKST
+ azot = -3600, -- AZOT
+ azost = 0, -- AZOST
+ cvt = -3600, -- CVT
+ fkt = -14400, -- FKT
+ fkst = -10800, -- FKST
+ cwst = 31500, -- CWST
+ lhst = 37800, -- LHST
+ lhst = 39600, -- LHST
+ msk = 10800, -- MSK
+ msd = 14400, -- MSD
+ samt = 14400, -- SAMT
+ samst = 18000, -- SAMST
+ volt = 10800, -- VOLT
+ volst = 14400, -- VOLST
+ iot = 21600, -- IOT
+ cxt = 25200, -- CXT
+ cct = 23400, -- CCT
+ tft = 18000, -- TFT
+ sct = 14400, -- SCT
+ mvt = 18000, -- MVT
+ mut = 14400, -- MUT
+ must = 18000, -- MUST
+ ret = 14400, -- RET
+ chast = 45900, -- CHAST
+ chadt = 49500, -- CHADT
+ vut = 39600, -- VUT
+ phot = 46800, -- PHOT
+ tkt = -36000, -- TKT
+ fjt = 43200, -- FJT
+ tvt = 43200, -- TVT
+ galt = -21600, -- GALT
+ gamt = -32400, -- GAMT
+ sbt = 39600, -- SBT
+ hst = -36000, -- HST
+ lint = 50400, -- LINT
+ kost = 39600, -- KOST
+ mht = 43200, -- MHT
+ mart = -34200, -- MART
+ sst = -39600, -- SST
+ nrt = 43200, -- NRT
+ nut = -39600, -- NUT
+ nft = 41400, -- NFT
+ nct = 39600, -- NCT
+ pwt = 32400, -- PWT
+ pont = 39600, -- PONT
+ pgt = 36000, -- PGT
+ ckt = -36000, -- CKT
+ taht = -36000, -- TAHT
+ gilt = 43200, -- GILT
+ tot = 46800, -- TOT
+ trut = 36000, -- TRUT
+ wakt = 43200, -- WAKT
+ wft = 43200, -- WFT
+}
diff --git a/libs/uvl/luasrc/uvl.lua b/libs/uvl/luasrc/uvl.lua
index dd8058f03b..7f149cf759 100644
--- a/libs/uvl/luasrc/uvl.lua
+++ b/libs/uvl/luasrc/uvl.lua
@@ -19,9 +19,10 @@ $Id$
-- @class module
-- @cstyle instance
-local fs = require "luci.fs"
+local fs = require "nixio.fs"
local uci = require "luci.model.uci"
local util = require "luci.util"
+local nutil = require "nixio.util"
local table = require "table"
local string = require "string"
@@ -403,11 +404,11 @@ function UVL.read_scheme( self, shm, alias )
local bc = "%s/bytecode/%s.lua" %{ self.schemedir, shm }
if not fs.access(bc) then
- local files = fs.glob(self.schemedir .. '/*/' .. shm)
+ local files = nutil.consume((fs.glob(self.schemedir .. '/*/' .. shm)))
- if files then
+ if #files > 0 then
local ok, err
- for i, file in ipairs( files ) do
+ for _, file in ipairs(files) do
if not fs.access(file) then
return false, so:error(ERR.SME_READ(so,file))
end
diff --git a/libs/uvl/luasrc/uvl/datatypes.lua b/libs/uvl/luasrc/uvl/datatypes.lua
index 1ad0891f2d..c6a5de3988 100644
--- a/libs/uvl/luasrc/uvl/datatypes.lua
+++ b/libs/uvl/luasrc/uvl/datatypes.lua
@@ -14,7 +14,7 @@ $Id$
]]--
-local fs = require "luci.fs"
+local fs = require "nixio.fs"
local ip = require "luci.ip"
local math = require "math"
local util = require "luci.util"
diff --git a/libs/uvl/luasrc/uvl/validation.lua b/libs/uvl/luasrc/uvl/validation.lua
index 90fde64f19..47eed6b1cd 100644
--- a/libs/uvl/luasrc/uvl/validation.lua
+++ b/libs/uvl/luasrc/uvl/validation.lua
@@ -15,7 +15,7 @@ $Id$
]]--
local os = require "os"
-local fs = require "luci.fs"
+local fs = require "nixio.fs"
local sys = require "luci.sys"
local ERR = require "luci.uvl.errors"
diff --git a/libs/uvldoc/luasrc/uvldoc/renderer.lua b/libs/uvldoc/luasrc/uvldoc/renderer.lua
index 7a188f6cf9..79b6cdb280 100644
--- a/libs/uvldoc/luasrc/uvldoc/renderer.lua
+++ b/libs/uvldoc/luasrc/uvldoc/renderer.lua
@@ -14,7 +14,7 @@ $Id$
]]--
local io = require "io"
-local fs = require "luci.fs"
+local fs = require "nixio.fs"
local uvl = require "luci.uvl"
local util = require "luci.util"
local ltn12 = require "luci.ltn12"
@@ -48,7 +48,7 @@ function Generator.make(self)
fs.mkdir(self.output)
for i, file in ipairs(self.additionals) do
- fs.copy(self.sourcedir .. file, self.output .. "/" .. file)
+ fs.datacopy(self.sourcedir .. file, self.output .. "/" .. file)
end
template.compiler_mode = "memory"
diff --git a/libs/web/Makefile b/libs/web/Makefile
index f7fac7740e..cc3bc96fc1 100644
--- a/libs/web/Makefile
+++ b/libs/web/Makefile
@@ -1,2 +1,28 @@
include ../../build/config.mk
include ../../build/module.mk
+include ../../build/gccconfig.mk
+
+TPL_LDFLAGS =
+TPL_CFLAGS =
+TPL_SO = parser.so
+TPL_COMMON_OBJ = src/template_parser.o
+TPL_LUALIB_OBJ = src/template_lualib.o
+
+%.o: %.c
+ $(COMPILE) $(TPL_CFLAGS) $(LUA_CFLAGS) $(FPIC) -c -o $@ $<
+
+compile: build-clean $(TPL_COMMON_OBJ) $(TPL_LUALIB_OBJ)
+ $(LINK) $(SHLIB_FLAGS) $(TPL_LDFLAGS) -o src/$(TPL_SO) \
+ $(TPL_COMMON_OBJ) $(TPL_LUALIB_OBJ)
+ mkdir -p dist$(LUCI_LIBRARYDIR)/template
+ cp src/$(TPL_SO) dist$(LUCI_LIBRARYDIR)/template/$(TPL_SO)
+
+install: build
+ cp -pR dist$(LUA_LIBRARYDIR)/* $(LUA_LIBRARYDIR)
+
+clean: build-clean
+
+build-clean:
+ rm -f src/*.o src/$(TPL_SO)
+
+
diff --git a/libs/web/luasrc/dispatcher.lua b/libs/web/luasrc/dispatcher.lua
index b0f6c1e4da..37008b5946 100644
--- a/libs/web/luasrc/dispatcher.lua
+++ b/libs/web/luasrc/dispatcher.lua
@@ -25,7 +25,7 @@ limitations under the License.
]]--
--- LuCI web dispatcher.
-local fs = require "luci.fs"
+local fs = require "nixio.fs"
local sys = require "luci.sys"
local init = require "luci.init"
local util = require "luci.util"
@@ -258,7 +258,7 @@ function dispatch(request)
local verifytoken = false
if not sess then
sess = luci.http.getcookie("sysauth")
- sess = sess and sess:match("^[A-F0-9]+$")
+ sess = sess and sess:match("^[a-f0-9]+$")
verifytoken = true
end
@@ -394,19 +394,16 @@ end
function createindex_plain(path, suffixes)
local controllers = { }
for _, suffix in ipairs(suffixes) do
- controllers = util.combine(
- controllers,
- luci.fs.glob(path .. "*" .. suffix) or {},
- luci.fs.glob(path .. "*/*" .. suffix) or {}
- )
+ nixio.util.consume((fs.glob(path .. "*" .. suffix)), controllers)
+ nixio.util.consume((fs.glob(path .. "*/*" .. suffix)), controllers)
end
if indexcache then
- local cachedate = fs.mtime(indexcache)
+ local cachedate = fs.stat(indexcache, "mtime")
if cachedate then
local realdate = 0
for _, obj in ipairs(controllers) do
- local omtime = fs.mtime(path .. "/" .. obj)
+ local omtime = fs.stat(path .. "/" .. obj, "mtime")
realdate = (omtime and omtime > realdate) and omtime or realdate
end
diff --git a/libs/web/luasrc/i18n.lua b/libs/web/luasrc/i18n.lua
index 082a600783..dcca13ec64 100644
--- a/libs/web/luasrc/i18n.lua
+++ b/libs/web/luasrc/i18n.lua
@@ -27,6 +27,7 @@ limitations under the License.
--- LuCI translation library.
module("luci.i18n", package.seeall)
require("luci.util")
+require("lmo")
table = {}
i18ndir = luci.util.libpath() .. "/i18n/"
@@ -47,13 +48,22 @@ end
function load(file, lang, force)
lang = lang and lang:gsub("_", "-") or ""
if force or not loaded[lang] or not loaded[lang][file] then
- local f = loadfile(i18ndir .. file .. "." .. lang .. ".lua") or
- loadfile(i18ndir .. file .. "." .. lang .. ".lua.gz")
-
+ local f = lmo.open(i18ndir .. file .. "." .. lang .. ".lmo")
if f then
- table[lang] = table[lang] or {}
- setfenv(f, table[lang])
- f()
+ if not table[lang] then
+ table[lang] = { f }
+ setmetatable(table[lang], {
+ __index = function(tbl, key)
+ for i = 1, #tbl do
+ local s = rawget(tbl, i):lookup(key)
+ if s then return s end
+ end
+ end
+ })
+ else
+ table[lang][#table[lang]+1] = f
+ end
+
loaded[lang] = loaded[lang] or {}
loaded[lang][file] = true
return true
diff --git a/libs/web/luasrc/sauth.lua b/libs/web/luasrc/sauth.lua
index e5cb178459..8ae24a5411 100644
--- a/libs/web/luasrc/sauth.lua
+++ b/libs/web/luasrc/sauth.lua
@@ -15,7 +15,6 @@ $Id$
--- LuCI session library.
module("luci.sauth", package.seeall)
-require("luci.fs")
require("luci.util")
require("luci.sys")
require("luci.config")
@@ -30,17 +29,17 @@ sessiontime = tonumber(luci.config.sauth.sessiontime) or 15 * 60
--- Manually clean up expired sessions.
function clean()
local now = os.time()
- local files = luci.fs.dir(sessionpath)
+ local files = fs.dir(sessionpath)
if not files then
return nil
end
- for i, file in pairs(files) do
+ for file in files do
local fname = sessionpath .. "/" .. file
- local stat = luci.fs.stat(fname)
+ local stat = fs.stat(fname)
if stat and stat.type == "reg" and stat.mtime + sessiontime < now then
- luci.fs.unlink(fname)
+ fs.unlink(fname)
end
end
end
@@ -68,8 +67,8 @@ function read(id)
if not sane(sessionpath .. "/" .. id) then
return
end
- luci.fs.utime(sessionpath .. "/" .. id)
- return luci.fs.readfile(sessionpath .. "/" .. id)
+ fs.utimes(sessionpath .. "/" .. id)
+ return fs.readfile(sessionpath .. "/" .. id)
end
@@ -77,8 +76,8 @@ end
-- @return Boolean status
function sane(file)
return luci.sys.process.info("uid")
- == luci.fs.stat(file or sessionpath, "uid")
- and luci.fs.stat(file or sessionpath, "modestr")
+ == fs.stat(file or sessionpath, "uid")
+ and fs.stat(file or sessionpath, "modestr")
== (file and "rw-------" or "rwx------")
end
@@ -106,5 +105,5 @@ function kill(id)
if not id:match("^%w+$") then
error("Session ID is not sane!")
end
- luci.fs.unlink(sessionpath .. "/" .. id)
-end
\ No newline at end of file
+ fs.unlink(sessionpath .. "/" .. id)
+end
diff --git a/libs/web/luasrc/template.lua b/libs/web/luasrc/template.lua
index 83efd22009..7cc6e11b08 100644
--- a/libs/web/luasrc/template.lua
+++ b/libs/web/luasrc/template.lua
@@ -24,7 +24,7 @@ limitations under the License.
]]--
-local fs = require"luci.fs"
+local fs = require "nixio.fs"
local sys = require "luci.sys"
local util = require "luci.util"
local table = require "table"
@@ -32,6 +32,7 @@ local string = require "string"
local config = require "luci.config"
local coroutine = require "coroutine"
local nixio = require "nixio", require "nixio.util"
+local tparser = require "luci.template.parser"
local tostring, pairs, loadstring = tostring, pairs, loadstring
local setmetatable, loadfile = setmetatable, loadfile
@@ -89,9 +90,9 @@ function compile(template)
-- Replacements
local r_include = '")\ninclude("%s")\nwrite("'
- local r_i18n = '"..translate("%1","%2").."'
- local r_i18n2 = '"..translate("%1", "").."'
- local r_pexec = '"..(%s or "").."'
+ local r_i18n = '")\nwrite(translate("%1","%2"))\nwrite("'
+ local r_i18n2 = '")\nwrite(translate("%1", ""))\nwrite("'
+ local r_pexec = '")\nwrite(tostring(%s or ""))\nwrite("'
local r_exec = '")\n%s\nwrite("'
-- Parse the expressions
@@ -173,18 +174,18 @@ function Template.__init__(self, name)
local err
if compiler_mode == "file" then
- local tplmt = fs.mtime(sourcefile) or fs.mtime(sourcefile .. ".htm")
- local commt = fs.mtime(compiledfile)
+ local tplmt = fs.stat(sourcefile, "mtime") or fs.stat(sourcefile .. ".htm", "mtime")
+ local commt = fs.stat(compiledfile, "mtime")
- if not fs.mtime(cdir) then
- fs.mkdir(cdir, true)
+ if not fs.stat(cdir, "mtime") then
+ fs.mkdirr(cdir)
fs.chmod(fs.dirname(cdir), 777)
end
assert(tplmt or commt, "No such template: " .. name)
-- Build if there is no compiled file or if compiled file is outdated
- if not commt or (commt and tplmt and commt < tplmt) then
+ if not commt or (commt and tplmt and commt < tplmt) then
local source
source, err = fs.readfile(sourcefile) or fs.readfile(sourcefile .. ".htm")
@@ -206,12 +207,7 @@ function Template.__init__(self, name)
end
elseif compiler_mode == "memory" then
- local source
- source, err = fs.readfile(sourcefile) or fs.readfile(sourcefile .. ".htm")
- if source then
- self.template, err = compile(source)
- end
-
+ self.template, _, err = tparser.parse(sourcefile .. ".htm")
end
-- If we have no valid template throw error, otherwise cache the template
diff --git a/libs/web/src/template_lualib.c b/libs/web/src/template_lualib.c
new file mode 100644
index 0000000000..685613fbdc
--- /dev/null
+++ b/libs/web/src/template_lualib.c
@@ -0,0 +1,62 @@
+/*
+ * LuCI Template - Lua binding
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "template_lualib.h"
+
+int template_L_parse(lua_State *L)
+{
+ const char *file = luaL_checkstring(L, 1);
+ struct template_parser parser;
+ int lua_status;
+
+ if( (parser.fd = open(file, O_RDONLY)) > 0 )
+ {
+ parser.flags = 0;
+ parser.bufsize = 0;
+ parser.state = T_STATE_TEXT_NEXT;
+
+ if( !(lua_status = lua_load(L, template_reader, &parser, file)) )
+ {
+ return 1;
+ }
+ else
+ {
+ lua_pushnil(L);
+ lua_pushinteger(L, lua_status);
+ lua_pushlstring(L, parser.out, parser.outsize);
+ return 3;
+ }
+ }
+
+ lua_pushnil(L);
+ lua_pushinteger(L, 255);
+ lua_pushstring(L, "No such file or directory");
+ return 3;
+}
+
+/* module table */
+static const luaL_reg R[] = {
+ {"parse", template_L_parse},
+ {NULL, NULL}
+};
+
+LUALIB_API int luaopen_luci_template_parser(lua_State *L) {
+ luaL_register(L, TEMPLATE_LUALIB_META, R);
+ return 1;
+}
+
diff --git a/libs/web/src/template_lualib.h b/libs/web/src/template_lualib.h
new file mode 100644
index 0000000000..de915e1a25
--- /dev/null
+++ b/libs/web/src/template_lualib.h
@@ -0,0 +1,28 @@
+/*
+ * LuCI Template - Lua library header
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _TEMPLATE_LUALIB_H_
+#define _TEMPLATE_LUALIB_H_
+
+#include "template_parser.h"
+
+#define TEMPLATE_LUALIB_META "template.parser"
+
+LUALIB_API int luaopen_luci_template_parser(lua_State *L);
+
+#endif
diff --git a/libs/web/src/template_parser.c b/libs/web/src/template_parser.c
new file mode 100644
index 0000000000..58de5bb774
--- /dev/null
+++ b/libs/web/src/template_parser.c
@@ -0,0 +1,463 @@
+/*
+ * LuCI Template - Parser implementation
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "template_parser.h"
+
+
+/* leading and trailing code for different types */
+const char * gen_code[6][2] = {
+ { "write(\"", "\")" },
+ { NULL, NULL },
+ { "write(tostring(", "))" },
+ { "include(\"", "\")" },
+ { "write(translate(\"", "\"))" },
+ { NULL, " " }
+};
+
+/* Simple strstr() like function that takes len arguments for both haystack and needle. */
+static char *strfind(char *haystack, int hslen, const char *needle, int ndlen)
+{
+ int match = 0;
+ int i, j;
+
+ for( i = 0; i < hslen; i++ )
+ {
+ if( haystack[i] == needle[0] )
+ {
+ match = ((ndlen == 1) || ((i + ndlen) <= hslen));
+
+ for( j = 1; (j < ndlen) && ((i + j) < hslen); j++ )
+ {
+ if( haystack[i+j] != needle[j] )
+ {
+ match = 0;
+ break;
+ }
+ }
+
+ if( match )
+ return &haystack[i];
+ }
+ }
+
+ return NULL;
+}
+
+/*
+ * Inspect current read buffer and find the number of "vague" characters at the end
+ * which could indicate an opening token. Returns the number of "vague" chars.
+ * The last continuous sequence of whitespace, optionally followed by a "<" is
+ * treated as "vague" because whitespace may be discarded if the upcoming opening
+ * token indicates pre-whitespace-removal ("<%-"). A single remaining "<" char
+ * can't be differentiated from an opening token ("<%"), so it's kept to be processed
+ * in the next cycle.
+ */
+static int stokscan(struct template_parser *data, int off, int no_whitespace)
+{
+ int i;
+ int skip = 0;
+ int tokoff = data->bufsize - 1;
+
+ for( i = tokoff; i >= off; i-- )
+ {
+ if( data->buf[i] == T_TOK_START[0] )
+ {
+ skip = tokoff - i + 1;
+ tokoff = i - 1;
+ break;
+ }
+ }
+
+ if( !no_whitespace )
+ {
+ for( i = tokoff; i >= off; i-- )
+ {
+ if( isspace(data->buf[i]) )
+ skip++;
+ else
+ break;
+ }
+ }
+
+ return skip;
+}
+
+/*
+ * Similar to stokscan() but looking for closing token indicators.
+ * Matches "-", optionally followed by a "%" char.
+ */
+static int etokscan(struct template_parser *data)
+{
+ int skip = 0;
+
+ if( (data->bufsize > 0) && (data->buf[data->bufsize-1] == T_TOK_END[0]) )
+ skip++;
+
+ if( (data->bufsize > skip) && (data->buf[data->bufsize-skip-1] == T_TOK_SKIPWS[0]) )
+ skip++;
+
+ return skip;
+}
+
+/*
+ * Generate Lua expressions from the given raw code, write it into the
+ * output buffer and set the lua_Reader specific size pointer.
+ * Takes parser-state, lua_Reader's size pointer and generator flags
+ * as parameter. The given flags indicate whether leading or trailing
+ * code should be added. Returns a pointer to the output buffer.
+ */
+static const char * generate_expression(struct template_parser *data, size_t *sz, int what)
+{
+ char tmp[T_OUTBUFSZ];
+ int i;
+ int size = 0;
+ int start = 0;
+ int i18n_hasdef = 0;
+
+ memset(tmp, 0, T_OUTBUFSZ);
+
+ /* Inject leading expression code (if any) */
+ if( (what & T_GEN_START) && (gen_code[data->type][0] != NULL) )
+ {
+ memcpy(tmp, gen_code[data->type][0], strlen(gen_code[data->type][0]));
+ size += strlen(gen_code[data->type][0]);
+ }
+
+ /* Parse source buffer */
+ for( i = 0; i < data->outsize; i++ )
+ {
+ /* Skip leading whitespace for non-raw and non-expr chunks */
+ if( !start && isspace(data->out[i]) && (data->type == T_TYPE_I18N || data->type == T_TYPE_INCLUDE) )
+ continue;
+ else if( !start )
+ start = 1;
+
+ /* Found whitespace after i18n key */
+ if( (data->type == T_TYPE_I18N) && (i18n_hasdef == 1) )
+ {
+ /* At non-whitespace char, inject seperator token */
+ if( !isspace(data->out[i]) )
+ {
+ memcpy(&tmp[size], T_TOK_I18NSEP, strlen(T_TOK_I18NSEP));
+ size += strlen(T_TOK_I18NSEP);
+ i18n_hasdef = 2;
+ }
+
+ /* At further whitespace, skip */
+ else
+ {
+ continue;
+ }
+ }
+
+ /* Escape quotes, backslashes and newlines for plain, i18n and include expressions */
+ if( (data->type == T_TYPE_TEXT || data->type == T_TYPE_I18N || data->type == T_TYPE_INCLUDE) &&
+ (data->out[i] == '\\' || data->out[i] == '"' || data->out[i] == '\n' || data->out[i] == '\t') )
+ {
+ tmp[size++] = '\\';
+
+ switch(data->out[i])
+ {
+ case '\n':
+ tmp[size++] = 'n';
+ break;
+
+ case '\t':
+ tmp[size++] = 't';
+ break;
+
+ default:
+ tmp[size++] = data->out[i];
+ }
+ }
+
+ /* Found whitespace in i18n expression, raise flag */
+ else if( isspace(data->out[i]) && (data->type == T_TYPE_I18N) )
+ {
+ i18n_hasdef = 1;
+ }
+
+ /* Normal char */
+ else
+ {
+ tmp[size++] = data->out[i];
+ }
+ }
+
+ /* Processed i18n expression without default text, inject separator */
+ if( (data->type == T_TYPE_I18N) && (i18n_hasdef < 2) )
+ {
+ memcpy(&tmp[size], T_TOK_I18NSEP, strlen(T_TOK_I18NSEP));
+ size += strlen(T_TOK_I18NSEP);
+ }
+
+ /* Inject trailing expression code (if any) */
+ if( (what & T_GEN_END) && (gen_code[data->type][1] != NULL) )
+ {
+ memcpy(&tmp[size], gen_code[data->type][1], strlen(gen_code[data->type][1]));
+ size += strlen(gen_code[data->type][1]);
+ }
+
+ *sz = data->outsize = size;
+ memset(data->out, 0, T_OUTBUFSZ);
+ memcpy(data->out, tmp, size);
+
+ //printf("<<<%i|%i|%i|%s>>>\n", what, data->type, *sz, data->out);
+
+ return data->out;
+}
+
+/*
+ * Move the number of bytes specified in data->bufsize from the
+ * given source pointer to the beginning of the read buffer.
+ */
+static void bufmove(struct template_parser *data, const char *src)
+{
+ if( data->bufsize > 0 )
+ memmove(data->buf, src, data->bufsize);
+ else if( data->bufsize < 0 )
+ data->bufsize = 0;
+
+ data->buf[data->bufsize] = 0;
+}
+
+/*
+ * Move the given amount of bytes from the given source pointer
+ * to the output buffer and set data->outputsize.
+ */
+static void bufout(struct template_parser *data, const char *src, int len)
+{
+ if( len >= 0 )
+ {
+ memset(data->out, 0, T_OUTBUFSZ);
+ memcpy(data->out, src, len);
+ data->outsize = len;
+ }
+ else
+ {
+ data->outsize = 0;
+ }
+}
+
+/*
+ * lua_Reader compatible function that parses template code on demand from
+ * the given file handle.
+ */
+const char *template_reader(lua_State *L, void *ud, size_t *sz)
+{
+ struct template_parser *data = ud;
+ char *match = NULL;
+ int off = 0;
+ int ignore = 0;
+ int genflags = 0;
+ int readlen = 0;
+ int vague = 0;
+
+ while( !(data->flags & T_FLAG_EOF) || (data->bufsize > 0) )
+ {
+ /* Fill buffer */
+ if( !(data->flags & T_FLAG_EOF) && (data->bufsize < T_READBUFSZ) )
+ {
+ if( (readlen = read(data->fd, &data->buf[data->bufsize], T_READBUFSZ - data->bufsize)) > 0 )
+ data->bufsize += readlen;
+ else if( readlen == 0 )
+ data->flags |= T_FLAG_EOF;
+ else
+ return NULL;
+ }
+
+ /* Evaluate state */
+ switch(data->state)
+ {
+ /* Plain text chunk (before "<%") */
+ case T_STATE_TEXT_INIT:
+ case T_STATE_TEXT_NEXT:
+ off = 0; ignore = 0; *sz = 0;
+ data->type = T_TYPE_TEXT;
+
+ /* Skip leading whitespace if requested */
+ if( data->flags & T_FLAG_SKIPWS )
+ {
+ data->flags &= ~T_FLAG_SKIPWS;
+ while( (off < data->bufsize) && isspace(data->buf[off]) )
+ off++;
+ }
+
+ /* Found "<%" */
+ if( (match = strfind(&data->buf[off], data->bufsize - off - 1, T_TOK_START, strlen(T_TOK_START))) != NULL )
+ {
+ readlen = (int)(match - &data->buf[off]);
+ data->bufsize -= (readlen + strlen(T_TOK_START) + off);
+ match += strlen(T_TOK_START);
+
+ /* Check for leading '-' */
+ if( match[0] == T_TOK_SKIPWS[0] )
+ {
+ data->bufsize--;
+ match++;
+
+ while( (readlen > 1) && isspace(data->buf[off+readlen-1]) )
+ {
+ readlen--;
+ }
+ }
+
+ bufout(data, &data->buf[off], readlen);
+ bufmove(data, match);
+ data->state = T_STATE_CODE_INIT;
+ }
+
+ /* Maybe plain chunk */
+ else
+ {
+ /* Preserve trailing "<" or white space, maybe a start token */
+ vague = stokscan(data, off, 0);
+
+ /* We can process some bytes ... */
+ if( vague < data->bufsize )
+ {
+ readlen = data->bufsize - vague - off;
+ }
+
+ /* No bytes to process, so try to remove at least whitespace ... */
+ else
+ {
+ /* ... but try to preserve trailing "<" ... */
+ vague = stokscan(data, off, 1);
+
+ if( vague < data->bufsize )
+ {
+ readlen = data->bufsize - vague - off;
+ }
+
+ /* ... no chance, push out buffer */
+ else
+ {
+ readlen = vague - off;
+ vague = 0;
+ }
+ }
+
+ bufout(data, &data->buf[off], readlen);
+
+ data->state = T_STATE_TEXT_NEXT;
+ data->bufsize = vague;
+ bufmove(data, &data->buf[off+readlen]);
+ }
+
+ if( ignore || data->outsize == 0 )
+ continue;
+ else
+ return generate_expression(data, sz, T_GEN_START | T_GEN_END);
+
+ break;
+
+ /* Ignored chunk (inside "<%# ... %>") */
+ case T_STATE_SKIP:
+ ignore = 1;
+
+ /* Initial code chunk ("<% ...") */
+ case T_STATE_CODE_INIT:
+ off = 0;
+
+ /* Check for leading '-' */
+ if( data->buf[off] == T_TOK_SKIPWS[0] )
+ off++;
+
+ /* Determine code type */
+ switch(data->buf[off])
+ {
+ case '#':
+ ignore = 1;
+ off++;
+ data->type = T_TYPE_COMMENT;
+ break;
+
+ case '=':
+ off++;
+ data->type = T_TYPE_EXPR;
+ break;
+
+ case '+':
+ off++;
+ data->type = T_TYPE_INCLUDE;
+ break;
+
+ case ':':
+ off++;
+ data->type = T_TYPE_I18N;
+ break;
+
+ default:
+ data->type = T_TYPE_CODE;
+ break;
+ }
+
+ /* Subsequent code chunk ("..." or "... %>") */
+ case T_STATE_CODE_NEXT:
+ /* Found "%>" */
+ if( (match = strfind(&data->buf[off], data->bufsize - off, T_TOK_END, strlen(T_TOK_END))) != NULL )
+ {
+ genflags = ( data->state == T_STATE_CODE_INIT )
+ ? (T_GEN_START | T_GEN_END) : T_GEN_END;
+
+ readlen = (int)(match - &data->buf[off]);
+
+ /* Check for trailing '-' */
+ if( (match > data->buf) && (*(match-1) == T_TOK_SKIPWS[0]) )
+ {
+ readlen--;
+ data->flags |= T_FLAG_SKIPWS;
+ }
+
+ bufout(data, &data->buf[off], readlen);
+
+ data->state = T_STATE_TEXT_INIT;
+ data->bufsize -= ((int)(match - &data->buf[off]) + strlen(T_TOK_END) + off);
+ bufmove(data, &match[strlen(T_TOK_END)]);
+ }
+
+ /* Code chunk */
+ else
+ {
+ genflags = ( data->state == T_STATE_CODE_INIT ) ? T_GEN_START : 0;
+
+ /* Preserve trailing "%" and "-", maybe an end token */
+ vague = etokscan(data);
+ readlen = data->bufsize - off - vague;
+ bufout(data, &data->buf[off], readlen);
+
+ data->state = T_STATE_CODE_NEXT;
+ data->bufsize = vague;
+ bufmove(data, &data->buf[readlen+off]);
+ }
+
+ if( ignore || (data->outsize == 0 && !genflags) )
+ continue;
+ else
+ return generate_expression(data, sz, genflags);
+
+ break;
+ }
+ }
+
+ *sz = 0;
+ return NULL;
+}
+
+
diff --git a/libs/web/src/template_parser.h b/libs/web/src/template_parser.h
new file mode 100644
index 0000000000..42ebdff69d
--- /dev/null
+++ b/libs/web/src/template_parser.h
@@ -0,0 +1,81 @@
+/*
+ * LuCI Template - Parser header
+ *
+ * Copyright (C) 2009 Jo-Philipp Wich
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _TEMPLATE_PARSER_H_
+#define _TEMPLATE_PARSER_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+
+#define T_READBUFSZ 1024
+#define T_OUTBUFSZ T_READBUFSZ * 3
+
+/* parser states */
+#define T_STATE_TEXT_INIT 0
+#define T_STATE_TEXT_NEXT 1
+#define T_STATE_CODE_INIT 2
+#define T_STATE_CODE_NEXT 3
+#define T_STATE_SKIP 4
+
+/* parser flags */
+#define T_FLAG_EOF 0x01
+#define T_FLAG_SKIPWS 0x02
+
+/* tokens used in matching and expression generation */
+#define T_TOK_START "<%"
+#define T_TOK_END "%>"
+#define T_TOK_SKIPWS "-"
+#define T_TOK_I18NSEP "\", \""
+
+/* generator flags */
+#define T_GEN_START 0x01
+#define T_GEN_END 0x02
+
+/* code types */
+#define T_TYPE_TEXT 0
+#define T_TYPE_COMMENT 1
+#define T_TYPE_EXPR 2
+#define T_TYPE_INCLUDE 3
+#define T_TYPE_I18N 4
+#define T_TYPE_CODE 5
+
+/* parser state */
+struct template_parser {
+ int fd;
+ int bufsize;
+ int outsize;
+ int state;
+ int flags;
+ int type;
+ char buf[T_READBUFSZ];
+ char out[T_OUTBUFSZ];
+};
+
+
+const char *template_reader(lua_State *L, void *ud, size_t *sz);
+
+#endif
diff --git a/modules/admin-full/luasrc/controller/admin/services.lua b/modules/admin-full/luasrc/controller/admin/services.lua
index a137377b39..50c79f6643 100644
--- a/modules/admin-full/luasrc/controller/admin/services.lua
+++ b/modules/admin-full/luasrc/controller/admin/services.lua
@@ -28,14 +28,14 @@ function index()
page.order = 40
page.index = true
- if luci.fs.access("/etc/config/lucittpd") then
+ if nixio.fs.access("/etc/config/lucittpd") then
local page = node("admin", "services", "lucittpd")
page.target = cbi("admin_services/lucittpd")
page.title = "LuCIttpd"
page.order = 10
end
- if luci.fs.access("/etc/config/httpd") then
+ if nixio.fs.access("/etc/config/httpd") then
local page = node("admin", "services", "httpd")
page.target = cbi("admin_services/httpd")
page.title = "Busybox HTTPd"
@@ -51,4 +51,4 @@ function index()
page.target = cbi("admin_services/dnsmasq")
page.title = "Dnsmasq"
page.order = 30
-end
\ No newline at end of file
+end
diff --git a/modules/admin-full/luasrc/controller/admin/status.lua b/modules/admin-full/luasrc/controller/admin/status.lua
index d8fa9e9f60..5d2df9c414 100644
--- a/modules/admin-full/luasrc/controller/admin/status.lua
+++ b/modules/admin-full/luasrc/controller/admin/status.lua
@@ -20,8 +20,8 @@ function index()
entry({"admin", "status"}, template("admin_status/index"), i18n("status", "Status"), 20).index = true
entry({"admin", "status", "interfaces"}, template("admin_status/interfaces"), i18n("interfaces", "Interfaces"), 1)
entry({"admin", "status", "iptables"}, call("action_iptables"), i18n("a_s_ipt", "Firewall"), 2)
- entry({"admin", "status", "conntrack"}, form("admin_status/conntrack"), i18n("a_n_conntrack"), 3)
- entry({"admin", "status", "routes"}, form("admin_status/routes"), i18n("a_n_routes"), 4)
+ entry({"admin", "status", "conntrack"}, template("admin_status/conntrack"), i18n("a_n_conntrack"), 3)
+ entry({"admin", "status", "routes"}, template("admin_status/routes"), i18n("a_n_routes"), 4)
entry({"admin", "status", "syslog"}, call("action_syslog"), i18n("syslog", "System Log"), 5)
entry({"admin", "status", "dmesg"}, call("action_dmesg"), i18n("dmesg", "Kernel Log"), 6)
diff --git a/modules/admin-full/luasrc/controller/admin/system.lua b/modules/admin-full/luasrc/controller/admin/system.lua
index 56010ea9e6..a273ff3f30 100644
--- a/modules/admin-full/luasrc/controller/admin/system.lua
+++ b/modules/admin-full/luasrc/controller/admin/system.lua
@@ -27,7 +27,7 @@ function index()
entry({"admin", "system", "processes"}, form("admin_system/processes"), i18n("process_head"), 45)
entry({"admin", "system", "fstab"}, cbi("admin_system/fstab"), i18n("a_s_fstab"), 50)
- if luci.fs.isdirectory("/sys/class/leds") then
+ if nixio.fs.access("/sys/class/leds") then
entry({"admin", "system", "leds"}, cbi("admin_system/leds"), i18n("leds", "LEDs"), 60)
end
@@ -124,7 +124,7 @@ function action_packages()
-- Remove index cache
if changes then
- luci.fs.unlink("/tmp/luci-indexcache")
+ nixio.fs.unlink("/tmp/luci-indexcache")
end
end
@@ -215,7 +215,7 @@ function action_upgrade()
local function storage_size()
local size = 0
- if luci.fs.access("/proc/mtd") then
+ if nixio.fs.access("/proc/mtd") then
for l in io.lines("/proc/mtd") do
local d, s, e, n = l:match('^([^%s]+)%s+([^%s]+)%s+([^%s]+)%s+"([^%s]+)"')
if n == "linux" then
@@ -223,7 +223,7 @@ function action_upgrade()
break
end
end
- elseif luci.fs.access("/proc/partitions") then
+ elseif nixio.fs.access("/proc/partitions") then
for l in io.lines("/proc/partitions") do
local x, y, b, n = l:match('^%s*(%d+)%s+(%d+)%s+([^%s]+)%s+([^%s]+)')
if b and n and not n:match('[0-9]') then
@@ -240,7 +240,7 @@ function action_upgrade()
local file
luci.http.setfilehandler(
function(meta, chunk, eof)
- if not luci.fs.access(tmpfile) and not file and chunk and #chunk > 0 then
+ if not nixio.fs.access(tmpfile) and not file and chunk and #chunk > 0 then
file = io.open(tmpfile, "w")
end
if file and chunk then
@@ -256,9 +256,9 @@ function action_upgrade()
-- Determine state
local keep_avail = true
local step = tonumber(luci.http.formvalue("step") or 1)
- local has_image = luci.fs.access(tmpfile)
+ local has_image = nixio.fs.access(tmpfile)
local has_support = image_supported()
- local has_platform = luci.fs.access("/lib/upgrade/platform.sh")
+ local has_platform = nixio.fs.access("/lib/upgrade/platform.sh")
local has_upload = luci.http.formvalue("image")
-- This does the actual flashing which is invoked inside an iframe
@@ -299,7 +299,7 @@ function action_upgrade()
-- If there is an image but user has requested step 1
-- or type is not supported, then remove it.
if has_image then
- luci.fs.unlink(tmpfile)
+ nixio.fs.unlink(tmpfile)
end
luci.template.render("admin_system/upgrade", {
@@ -314,7 +314,7 @@ function action_upgrade()
luci.template.render("admin_system/upgrade", {
step=2,
checksum=image_checksum(),
- filesize=luci.fs.stat(tmpfile).size,
+ filesize=nixio.fs.stat(tmpfile).size,
flashsize=storage_size(),
keepconfig=(keep_avail and luci.http.formvalue("keepcfg") == "1")
} )
@@ -334,7 +334,7 @@ function _keep_pattern()
if files then
kpattern = ""
for k, v in pairs(files) do
- if k:sub(1,1) ~= "." and luci.fs.glob(v) then
+ if k:sub(1,1) ~= "." and nixio.fs.glob(v)() then
kpattern = kpattern .. " " .. v
end
end
diff --git a/modules/admin-full/luasrc/model/cbi/admin_index/luci.lua b/modules/admin-full/luasrc/model/cbi/admin_index/luci.lua
index caf7c97889..30e8ddcc17 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_index/luci.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_index/luci.lua
@@ -15,6 +15,8 @@ require("luci.config")
m = Map("luci", translate("webui"), translate("a_i_luci1",
"Hier können Eigenschaften und die Funktionalität der Oberfläche angepasst werden."))
+local fs = require "nixio.fs"
+
-- force reload of global luci config namespace to reflect the changes
function m.commit_handler(self)
package.loaded["luci.config"] = nil
@@ -31,8 +33,8 @@ local i18ndir = luci.i18n.i18ndir .. "default."
for k, v in luci.util.kspairs(luci.config.languages) do
local file = i18ndir .. k:gsub("_", "-")
if k:sub(1, 1) ~= "." and (
- luci.fs.access(file .. ".lua") or
- luci.fs.access(file .. ".lua.gz")
+ fs.access(file .. ".lua") or
+ fs.access(file .. ".lua.gz")
) then
l:value(k, v)
end
diff --git a/modules/admin-full/luasrc/model/cbi/admin_network/dhcpleases.lua b/modules/admin-full/luasrc/model/cbi/admin_network/dhcpleases.lua
index 0b2f55a31d..31a27b3f66 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_network/dhcpleases.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_network/dhcpleases.lua
@@ -11,17 +11,21 @@ You may obtain a copy of the License at
$Id$
]]--
-require("luci.sys")
-require("luci.tools.webadmin")
+
+local uci = require "luci.model.uci".cursor()
+local sys = require "luci.sys"
+local wa = require "luci.tools.webadmin"
+local fs = require "nixio.fs"
+
m2 = Map("luci_ethers", translate("dhcp_leases"))
local leasefn, leasefp, leases
-luci.model.uci.cursor():foreach("dhcp", "dnsmasq",
+uci:foreach("dhcp", "dnsmasq",
function(section)
leasefn = section.leasefile
end
)
-local leasefp = leasefn and luci.fs.access(leasefn) and io.lines(leasefn)
+local leasefp = leasefn and fs.access(leasefn) and io.lines(leasefn)
if leasefp then
leases = {}
for lease in leasefp do
@@ -38,9 +42,7 @@ if leases then
ltime = v:option(DummyValue, 1, translate("dhcp_timeremain"))
function ltime.cfgvalue(self, ...)
local value = DummyValue.cfgvalue(self, ...)
- return luci.tools.webadmin.date_format(
- os.difftime(tonumber(value), os.time())
- )
+ return wa.date_format(os.difftime(tonumber(value), os.time()))
end
end
@@ -51,11 +53,13 @@ s.template = "cbi/tblsection"
mac = s:option(Value, "macaddr", translate("macaddress"))
ip = s:option(Value, "ipaddr", translate("ipaddress"))
-for i, dataset in ipairs(luci.sys.net.arptable()) do
- ip:value(dataset["IP address"])
- mac:value(dataset["HW address"],
- dataset["HW address"] .. " (" .. dataset["IP address"] .. ")")
-end
+sys.net.arptable(function(entry)
+ ip:value(entry["IP address"])
+ mac:value(
+ entry["HW address"],
+ entry["HW address"] .. " (" .. entry["IP address"] .. ")"
+ )
+end)
return m2
diff --git a/modules/admin-full/luasrc/model/cbi/admin_network/ifaces.lua b/modules/admin-full/luasrc/model/cbi/admin_network/ifaces.lua
index b9e65fb889..8758f7300c 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_network/ifaces.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_network/ifaces.lua
@@ -13,14 +13,16 @@ You may obtain a copy of the License at
$Id$
]]--
-require("luci.tools.webadmin")
+local wa = require "luci.tools.webadmin"
+local fs = require "nixio.fs"
+
arg[1] = arg[1] or ""
-local has_3g = luci.fs.mtime("/usr/bin/gcom")
-local has_pptp = luci.fs.mtime("/usr/sbin/pptp")
-local has_pppd = luci.fs.mtime("/usr/sbin/pppd")
-local has_pppoe = luci.fs.glob("/usr/lib/pppd/*/rp-pppoe.so")
-local has_pppoa = luci.fs.glob("/usr/lib/pppd/*/pppoatm.so")
+local has_3g = fs.access("/usr/bin/gcom")
+local has_pptp = fs.access("/usr/sbin/pptp")
+local has_pppd = fs.access("/usr/sbin/pppd")
+local has_pppoe = fs.glob("/usr/lib/pppd/*/rp-pppoe.so")()
+local has_pppoa = fs.glob("/usr/lib/pppd/*/pppoatm.so")()
m = Map("network", translate("interfaces"), translate("a_n_ifaces1"))
@@ -64,7 +66,7 @@ for i,d in ipairs(luci.sys.net.devices()) do
end
end
-local zones = luci.tools.webadmin.network_get_zones(arg[1])
+local zones = wa.network_get_zones(arg[1])
if zones then
if #zones == 0 then
m:chain("firewall")
@@ -83,7 +85,7 @@ if zones then
)
function fwzone.write(self, section, value)
- local zone = luci.tools.webadmin.firewall_find_zone(value)
+ local zone = wa.firewall_find_zone(value)
local stat
if not zone then
diff --git a/modules/admin-full/luasrc/model/cbi/admin_network/network.lua b/modules/admin-full/luasrc/model/cbi/admin_network/network.lua
index 300535d6da..8fd5368884 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_network/network.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_network/network.lua
@@ -12,14 +12,16 @@ You may obtain a copy of the License at
$Id$
]]--
-require("luci.sys")
-require("luci.tools.webadmin")
+
+local sys = require "luci.sys"
+local wa = require "luci.tools.webadmin"
+local fs = require "nixio.fs"
local netstate = luci.model.uci.cursor_state():get_all("network")
m = Map("network", translate("interfaces"))
local created
-local netstat = luci.sys.net.deviceinfo()
+local netstat = sys.net.deviceinfo()
s = m:section(TypedSection, "interface", "")
s.addremove = true
@@ -76,25 +78,22 @@ if luci.model.uci.cursor():load("firewall") then
zone.titleref = luci.dispatcher.build_url("admin", "network", "firewall", "zones")
function zone.cfgvalue(self, section)
- local zones = luci.tools.webadmin.network_get_zones(section)
- return zones and table.concat(zones, ", ") or "-"
+ return table.concat(wa.network_get_zones(section) or { "-" }, ", ")
end
end
hwaddr = s:option(DummyValue, "_hwaddr")
function hwaddr.cfgvalue(self, section)
local ix = self.map:get(section, "ifname") or ""
- return luci.fs.readfile("/sys/class/net/" .. ix .. "/address")
+ return fs.readfile("/sys/class/net/" .. ix .. "/address")
or luci.util.exec("ifconfig " .. ix):match(" ([A-F0-9:]+)%s*\n")
or "n/a"
-
end
ipaddr = s:option(DummyValue, "ipaddr", translate("addresses"))
function ipaddr.cfgvalue(self, section)
- local addr = luci.tools.webadmin.network_get_addresses(section)
- return table.concat(addr, ", ")
+ return table.concat(wa.network_get_addresses(section), ", ")
end
txrx = s:option(DummyValue, "_txrx")
@@ -103,10 +102,10 @@ function txrx.cfgvalue(self, section)
local ix = self.map:get(section, "ifname")
local rx = netstat and netstat[ix] and netstat[ix][1]
- rx = rx and luci.tools.webadmin.byte_format(tonumber(rx)) or "-"
+ rx = rx and wa.byte_format(tonumber(rx)) or "-"
local tx = netstat and netstat[ix] and netstat[ix][9]
- tx = tx and luci.tools.webadmin.byte_format(tonumber(tx)) or "-"
+ tx = tx and wa.byte_format(tonumber(tx)) or "-"
return string.format("%s / %s", tx, rx)
end
diff --git a/modules/admin-full/luasrc/model/cbi/admin_network/wifi.lua b/modules/admin-full/luasrc/model/cbi/admin_network/wifi.lua
index 34992271b2..6e9249249c 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_network/wifi.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_network/wifi.lua
@@ -11,7 +11,10 @@ You may obtain a copy of the License at
$Id$
]]--
-require("luci.tools.webadmin")
+
+local wa = require "luci.tools.webadmin"
+local fs = require "nixio.fs"
+
arg[1] = arg[1] or ""
m = Map("wireless", translate("networks"), translate("a_w_networks1"))
@@ -143,7 +146,7 @@ network = s:option(Value, "network", translate("network"), translate("a_w_networ
network.rmempty = true
network:value("")
network.combobox_manual = translate("a_w_netmanual")
-luci.tools.webadmin.cbi_add_networks(network)
+wa.cbi_add_networks(network)
function network.write(self, section, value)
if not m.uci:get("network", value) then
@@ -173,7 +176,7 @@ bssid = s:option(Value, "bssid", translate("wifi_bssid"))
-------------------- MAC80211 Interface ----------------------
if hwtype == "mac80211" then
- if luci.fs.mtime("/usr/sbin/iw") then
+ if fs.access("/usr/sbin/iw") then
mode:value("mesh", "802.11s")
end
@@ -322,8 +325,8 @@ encr:value("none", "No Encryption")
encr:value("wep", "WEP")
if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then
- local supplicant = luci.fs.mtime("/usr/sbin/wpa_supplicant")
- local hostapd = luci.fs.mtime("/usr/sbin/hostapd")
+ local supplicant = fs.access("/usr/sbin/wpa_supplicant")
+ local hostapd = fs.access("/usr/sbin/hostapd")
if hostapd and supplicant then
encr:value("psk", "WPA-PSK")
diff --git a/modules/admin-full/luasrc/model/cbi/admin_services/crontab.lua b/modules/admin-full/luasrc/model/cbi/admin_services/crontab.lua
index 521e0a27d3..05442dd55f 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_services/crontab.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_services/crontab.lua
@@ -12,6 +12,8 @@ You may obtain a copy of the License at
$Id$
]]--
+
+local fs = require "nixio.fs"
local cronfile = "/etc/crontabs/root"
f = SimpleForm("crontab", translate("a_s_crontab"), translate("a_s_crontab1"))
@@ -20,13 +22,13 @@ t = f:field(TextValue, "crons")
t.rmempty = true
t.rows = 10
function t.cfgvalue()
- return luci.fs.readfile(cronfile) or ""
+ return fs.readfile(cronfile) or ""
end
function f.handle(self, state, data)
if state == FORM_VALID then
if data.crons then
- luci.fs.writefile(cronfile, data.crons:gsub("\r\n", "\n"))
+ fs.writefile(cronfile, data.crons:gsub("\r\n", "\n"))
end
end
return true
diff --git a/modules/admin-full/luasrc/model/cbi/admin_system/fstab.lua b/modules/admin-full/luasrc/model/cbi/admin_system/fstab.lua
index 1e2a12fec1..aa4f12e554 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_system/fstab.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_system/fstab.lua
@@ -13,16 +13,18 @@ $Id$
]]--
require("luci.tools.webadmin")
-local fs = require "luci.fs"
+local fs = require "nixio.fs"
+local util = require "nixio.util"
+
local devices = {}
-luci.util.update(devices, fs.glob("/dev/sd*") or {})
-luci.util.update(devices, fs.glob("/dev/hd*") or {})
-luci.util.update(devices, fs.glob("/dev/scd*") or {})
-luci.util.update(devices, fs.glob("/dev/mmc*") or {})
+util.consume((fs.glob("/dev/sd*")), devices)
+util.consume((fs.glob("/dev/hd*")), devices)
+util.consume((fs.glob("/dev/scd*")), devices)
+util.consume((fs.glob("/dev/mmc*")), devices)
local size = {}
for i, dev in ipairs(devices) do
- local s = tonumber((luci.fs.readfile("/sys/class/block/%s/size" % dev:sub(6))))
+ local s = tonumber((fs.readfile("/sys/class/block/%s/size" % dev:sub(6))))
size[dev] = s and math.floor(s / 2048)
end
diff --git a/modules/admin-full/luasrc/model/cbi/admin_system/ipkg.lua b/modules/admin-full/luasrc/model/cbi/admin_system/ipkg.lua
index fecc294b68..1b540b7051 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_system/ipkg.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_system/ipkg.lua
@@ -19,11 +19,11 @@ f = SimpleForm("ipkgconf", translate("a_s_p_ipkg"))
t = f:field(TextValue, "lines")
t.rows = 10
function t.cfgvalue()
- return luci.fs.readfile(ipkgfile) or ""
+ return nixio.fs.readfile(ipkgfile) or ""
end
function t.write(self, section, data)
- return luci.fs.writefile(ipkgfile, data:gsub("\r\n", "\n"))
+ return nixio.fs.writefile(ipkgfile, data:gsub("\r\n", "\n"))
end
f:append(Template("admin_system/ipkg"))
diff --git a/modules/admin-full/luasrc/model/cbi/admin_system/leds.lua b/modules/admin-full/luasrc/model/cbi/admin_system/leds.lua
index 5074a73396..71bd7d0bb1 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_system/leds.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_system/leds.lua
@@ -16,12 +16,11 @@ m = Map("system", translate("leds"), translate("leds_desc"))
local sysfs_path = "/sys/class/leds/"
local leds = {}
-if luci.fs.access(sysfs_path) then
- for k, v in pairs(luci.fs.dir(sysfs_path)) do
- if v ~= "." and v ~= ".." then
- table.insert(leds, v)
- end
- end
+local fs = require "nixio.fs"
+local util = require "nixio.util"
+
+if fs.access(sysfs_path) then
+ leds = util.consume((fs.dir(sysfs_path)))
end
if #leds == 0 then
@@ -52,7 +51,7 @@ s:option(Flag, "default").rmempty = true
trigger = s:option(ListValue, "trigger")
-local triggers = luci.fs.readfile(sysfs_path .. leds[1] .. "/trigger")
+local triggers = fs.readfile(sysfs_path .. leds[1] .. "/trigger")
for t in triggers:gmatch("[%w-]+") do
trigger:value(t, translate("system_led_trigger_" .. t:gsub("-", "")))
end
@@ -83,4 +82,4 @@ mode:value("link", translate("system_led_mode_link"))
mode:value("tx", translate("system_led_mode_tx"))
mode:value("rx", translate("system_led_mode_rx"))
-return m
\ No newline at end of file
+return m
diff --git a/modules/admin-full/luasrc/model/cbi/admin_system/sshkeys.lua b/modules/admin-full/luasrc/model/cbi/admin_system/sshkeys.lua
index 26410c98a1..b7ff482353 100644
--- a/modules/admin-full/luasrc/model/cbi/admin_system/sshkeys.lua
+++ b/modules/admin-full/luasrc/model/cbi/admin_system/sshkeys.lua
@@ -20,13 +20,13 @@ t = f:field(TextValue, "keys")
t.rmempty = true
t.rows = 10
function t.cfgvalue()
- return luci.fs.readfile(keyfile) or ""
+ return nixio.fs.readfile(keyfile) or ""
end
function f.handle(self, state, data)
if state == FORM_VALID then
if data.keys then
- luci.fs.writefile(keyfile, data.keys:gsub("\r\n", "\n"))
+ nixio.fs.writefile(keyfile, data.keys:gsub("\r\n", "\n"))
end
end
return true
diff --git a/modules/admin-full/luasrc/view/admin_status/conntrack.htm b/modules/admin-full/luasrc/view/admin_status/conntrack.htm
new file mode 100644
index 0000000000..d0a86b6107
--- /dev/null
+++ b/modules/admin-full/luasrc/view/admin_status/conntrack.htm
@@ -0,0 +1,75 @@
+<%#
+LuCI - Lua Configuration Interface
+Copyright 2008-2009 Steven Barth
+Copyright 2008-2009 Jo-Philipp Wich
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+-%>
+
+<%-
+ require "luci.sys"
+ local style = true
+-%>
+
+<%+header%>
+
+
+
+<%+footer%>
+
diff --git a/modules/admin-full/luasrc/view/admin_status/interfaces.htm b/modules/admin-full/luasrc/view/admin_status/interfaces.htm
index 5358caeae6..720ce9c3d7 100644
--- a/modules/admin-full/luasrc/view/admin_status/interfaces.htm
+++ b/modules/admin-full/luasrc/view/admin_status/interfaces.htm
@@ -15,15 +15,15 @@ $Id$
<%-
- require "luci.tools.webadmin"
-
- local wba = luci.tools.webadmin
- local uci = luci.model.uci.cursor_state()
+ local sys = require "luci.sys"
+ local wba = require "luci.tools.webadmin"
+ local uci = require "luci.model.uci".cursor_state()
+ local fs = require "nixio.fs"
local bridge_ifs = { }
local single_ifs = { }
local wifi_ifs = { }
- local devinfo = luci.sys.net.deviceinfo()
+ local devinfo = sys.net.deviceinfo()
uci:foreach("network", "interface",
function(s)
@@ -86,8 +86,8 @@ $Id$
function get_switch_driver(i)
local n, d = i:match("([a-z]+)(%d+)%.%d+$")
- local hw = luci.fs.readfile("/proc/switch/%s%s/driver" %{ n, d })
- or luci.fs.readfile("/proc/switch/%s/driver" % d )
+ local hw = fs.readfile("/proc/switch/%s%s/driver" %{ n, d })
+ or fs.readfile("/proc/switch/%s/driver" % d )
return hw and hw:match("%S+")
end
diff --git a/modules/admin-full/luasrc/view/admin_status/routes.htm b/modules/admin-full/luasrc/view/admin_status/routes.htm
new file mode 100644
index 0000000000..cd62b80e5f
--- /dev/null
+++ b/modules/admin-full/luasrc/view/admin_status/routes.htm
@@ -0,0 +1,89 @@
+<%#
+LuCI - Lua Configuration Interface
+Copyright 2008-2009 Steven Barth
+Copyright 2008-2009 Jo-Philipp Wich
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+-%>
+
+<%-
+ require "bit"
+ require "luci.sys"
+ require "luci.tools.webadmin"
+ require "nixio.fs"
+
+ local style = true
+-%>
+
+<%+header%>
+
+