summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--INSTALL27
-rw-r--r--README.md7
-rw-r--r--applications/luci-app-firewall/luasrc/model/cbi/firewall/zone-details.lua9
-rw-r--r--applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua10
-rw-r--r--applications/luci-app-mjpg-streamer/po/zh-cn/mjpg-streamer.po166
-rw-r--r--applications/luci-app-multiwan/Makefile4
-rw-r--r--applications/luci-app-ocserv/luasrc/controller/ocserv.lua2
-rw-r--r--applications/luci-app-ocserv/luasrc/model/cbi/ocserv/users.lua2
-rw-r--r--applications/luci-app-olsr/Makefile2
-rw-r--r--applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua2
-rw-r--r--applications/luci-app-shadowsocks-libev/Makefile14
-rw-r--r--applications/luci-app-shadowsocks-libev/luasrc/controller/shadowsocks-libev.lua12
-rw-r--r--applications/luci-app-shadowsocks-libev/luasrc/model/cbi/shadowsocks-libev.lua156
-rw-r--r--applications/luci-app-shadowsocks-libev/po/templates/shadowsocks-libev.pot80
-rw-r--r--applications/luci-app-shadowsocks-libev/po/zh-cn/shadowsocks-libev.po91
-rw-r--r--applications/luci-app-shadowsocks-libev/root/etc/uci-defaults/luci-shadowsocks-libev11
-rw-r--r--applications/luci-app-statistics/luasrc/controller/luci_statistics/luci_statistics.lua3
-rw-r--r--applications/luci-app-statistics/luasrc/model/cbi/luci_statistics/entropy.lua14
-rw-r--r--applications/luci-app-statistics/luasrc/statistics/rrdtool.lua6
-rw-r--r--applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/conntrack.lua4
-rw-r--r--applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/cpu.lua19
-rw-r--r--applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/entropy.lua19
-rw-r--r--applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/memory.lua2
-rw-r--r--applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/ping.lua2
-rw-r--r--applications/luci-app-statistics/luasrc/view/admin_statistics/index.htm7
-rw-r--r--applications/luci-app-statistics/root/etc/config/luci_statistics296
-rwxr-xr-xapplications/luci-app-statistics/root/etc/init.d/luci_statistics10
-rwxr-xr-xapplications/luci-app-statistics/root/etc/uci-defaults/luci-statistics20
-rwxr-xr-xapplications/luci-app-statistics/root/usr/bin/stat-genconfig6
-rwxr-xr-xapplications/luci-app-upnp/root/etc/uci-defaults/luci-upnp9
-rw-r--r--applications/luci-app-vnstat/luasrc/view/vnstat.htm2
-rw-r--r--contrib/package/community-profiles/files/etc/config/profile_hameln15
-rw-r--r--contrib/package/freifunk-watchdog/src/watchdog.h1
-rw-r--r--contrib/package/meshwizard/Makefile2
-rw-r--r--contrib/package/meshwizard/files/usr/bin/meshwizard/functions.sh2
-rwxr-xr-xcontrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_dhcp.sh6
-rwxr-xr-xcontrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_firewall.sh3
-rwxr-xr-xcontrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_network.sh24
-rwxr-xr-xcontrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_splash.sh10
-rwxr-xr-xcontrib/package/meshwizard/files/usr/bin/meshwizard/wizard.sh11
-rw-r--r--documentation/CBI.md248
-rw-r--r--documentation/JsonRpcHowTo.md66
-rw-r--r--documentation/LAR.md87
-rw-r--r--documentation/LMO.md144
-rw-r--r--documentation/LuCI-0.10.md202
-rw-r--r--documentation/Modules.md94
-rw-r--r--documentation/ModulesHowTo.md153
-rw-r--r--documentation/SubmitPatchesHowTo:.md33
-rw-r--r--documentation/Templates.md65
-rw-r--r--documentation/ThemesHowTo.md76
-rw-r--r--documentation/i18n.md17
-rw-r--r--libs/luci-lib-jsonc/src/jsonc.c9
-rw-r--r--libs/luci-lib-nixio/src/address.c4
-rw-r--r--modules/luci-base/luasrc/cbi.lua3
-rw-r--r--modules/luci-base/luasrc/http/protocol.lua15
-rw-r--r--modules/luci-base/luasrc/model/ipkg.lua47
-rw-r--r--modules/luci-base/luasrc/model/ipkg.luadoc17
-rw-r--r--modules/luci-base/luasrc/model/network.lua6
-rw-r--r--modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua8
-rw-r--r--modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua3
-rw-r--r--modules/luci-base/luasrc/tools/status.lua4
-rw-r--r--modules/luci-base/luasrc/view/cbi/network_netlist.htm1
-rw-r--r--modules/luci-mod-admin-full/luasrc/controller/admin/status.lua2
-rw-r--r--modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua5
-rw-r--r--modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua2
-rw-r--r--modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm2
-rw-r--r--modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_status.htm2
-rw-r--r--modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm2
-rw-r--r--modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm75
-rw-r--r--modules/luci-mod-rpc/luasrc/controller/rpc.lua2
70 files changed, 2172 insertions, 310 deletions
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 42cf706f39..0000000000
--- a/INSTALL
+++ /dev/null
@@ -1,27 +0,0 @@
-LuCI Installation Instructions
-
-TOC:
-1. Kamikaze Feed
-2. Kamikaze Packages
-
-
-1. Kamikaze Feed
- 1. Change to your OpenWrt buildroot
-
- 2. Add the following line to your OpenWrt feeds.conf:
- src-svn luci http://svn.luci.subsignal.org/luci/trunk/contrib/package
-
- 3. Run ./scripts/feeds update
-
- 4. Run ./scripts/feeds install -a -p luci
-
- 5. Type make menuconfig and you will find luci in the menu "Administration"
-
-
-2. Kamikaze Packages
- 1. cd to the "package" directory of your kamikaze buildroot
-
- 3. Type: ln -s /path/to/luci/contrib/package/* ./
-
- 4. cd to your kamikaze build root and type: make menuconfig
- You will find luci in the menu "Administration"
diff --git a/README.md b/README.md
index d5ad6b46a9..371cee2049 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,12 @@ This is the OpenWrt "luci"-feed containing LuCI - OpenWrt Configuration Interfac
## Usage
-This feed is enabled by default. To install all its package definitions, run:
+This feed is enabled by default. Your feeds.conf.default (or feeds.conf) should contain a line like:
+```
+src-git luci https://github.com/openwrt/luci.git
+```
+
+To install all its package definitions, run:
```
./scripts/feeds update luci
./scripts/feeds install -a -p luci
diff --git a/applications/luci-app-firewall/luasrc/model/cbi/firewall/zone-details.lua b/applications/luci-app-firewall/luasrc/model/cbi/firewall/zone-details.lua
index 3eb95ebb57..46b3744403 100644
--- a/applications/luci-app-firewall/luasrc/model/cbi/firewall/zone-details.lua
+++ b/applications/luci-app-firewall/luasrc/model/cbi/firewall/zone-details.lua
@@ -76,6 +76,15 @@ function name.write(self, section, value)
}
end
+function name.validate(self, value)
+ -- fw3 defines 14 as the maximum length of zone name
+ if #value > 14 then
+ return nil, translate("Zone name is too long")
+ else
+ return value
+ end
+end
+
p = {
s:taboption("general", ListValue, "input", translate("Input")),
s:taboption("general", ListValue, "output", translate("Output")),
diff --git a/applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua b/applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua
index 0e1c8bf9b6..d89ab27c29 100644
--- a/applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua
+++ b/applications/luci-app-mjpg-streamer/luasrc/model/cbi/mjpg-streamer.lua
@@ -5,19 +5,19 @@ m = Map("mjpg-streamer", "MJPG-streamer", translate("mjpg streamer is a streamin
--- General settings ---
-section_gen = m:section(TypedSection, "mjpg-streamer", "General")
+section_gen = m:section(TypedSection, "mjpg-streamer", translate("General"))
section_gen.addremove=false
section_gen.anonymous=true
-enabled = section_gen:option(Flag, "enabled", "Enabled", "Enable MJPG-streamer")
+enabled = section_gen:option(Flag, "enabled", translate("Enabled"), translate("Enable MJPG-streamer"))
-input = section_gen:option(ListValue, "input", "Input plugin")
+input = section_gen:option(ListValue, "input", translate("Input plugin"))
input:depends("enabled", "1")
input:value("uvc", "UVC")
---input:value("file", "File")
input.optional = false
-output = section_gen:option(ListValue, "output", "Output plugin")
+output = section_gen:option(ListValue, "output", translate("Output plugin"))
output:depends("enabled", "1")
output:value("http", "HTTP")
output:value("file", "File")
@@ -26,7 +26,7 @@ output = section_gen:option(ListValue, "output", "Output plugin")
--- Plugin settings ---
-s = m:section(TypedSection, "mjpg-streamer", "Plugin settings")
+s = m:section(TypedSection, "mjpg-streamer", translate("Plugin settings"))
s.addremove=false
s.anonymous=true
diff --git a/applications/luci-app-mjpg-streamer/po/zh-cn/mjpg-streamer.po b/applications/luci-app-mjpg-streamer/po/zh-cn/mjpg-streamer.po
new file mode 100644
index 0000000000..3ad9a4a53b
--- /dev/null
+++ b/applications/luci-app-mjpg-streamer/po/zh-cn/mjpg-streamer.po
@@ -0,0 +1,166 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: luci-app-mjpg-streamer\n"
+"POT-Creation-Date: 2015-06-11 21:11+0100\n"
+"PO-Revision-Date: 2015-06-11 21:11+0100\n"
+"Last-Translator: maz-1 <ohmygod19993 at gmail dotcom>\n"
+"Language-Team: \n"
+"Language: zh-cn\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.5.4\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Poedit-SourceCharset: UTF-8\n"
+
+
+msgid "Enabled"
+msgstr "启用"
+
+msgid "Enable MJPG-streamer"
+msgstr "启用MJPG-streamer"
+
+msgid "General"
+msgstr "一般设置"
+
+msgid "Plugin settings"
+msgstr "插件设置"
+
+msgid "Input plugin"
+msgstr "输入插件"
+
+msgid "Output plugin"
+msgstr "输出插件"
+
+msgid "Allow ringbuffer to exceed limit by this amount"
+msgstr "允许环形缓冲区最多超过这个数值"
+
+msgid "Ask for username and password on connect"
+msgstr "连接时询问用户名和密码"
+
+msgid "Authentication required"
+msgstr "需要验证"
+
+msgid "Auto"
+msgstr "自动"
+
+msgid "Automatic disabling of MJPEG mode"
+msgstr "自动禁用MJPEG模式"
+
+msgid "Blink"
+msgstr "闪烁"
+
+msgid "Check to save the stream to an mjpeg file"
+msgstr "勾选以保存视频流至一个mjpeg文件"
+
+msgid "Command to run"
+msgstr "运行的命令"
+
+msgid "Device"
+msgstr "设备"
+
+msgid "Do not initalize dynctrls of Linux-UVC driver"
+msgstr "不要初始化Linux-UVC驱动的dynctrls"
+
+msgid "Don't initalize dynctrls"
+msgstr "不要初始化dynctrls"
+
+msgid "Drop frames smaller then this limit"
+msgstr "丢弃小于该尺寸限制的帧"
+
+msgid "Enable YUYV format"
+msgstr "启用YUYV格式"
+
+msgid "Exceed"
+msgstr "超出"
+
+msgid ""
+"Execute command after saving picture. Mjpg-streamer parse the filename as "
+"first parameter to your script."
+msgstr "保存图片后执行命令。文件名将作为第一个参数传递给命令。"
+
+msgid "File input"
+msgstr "文件输入"
+
+msgid "File output"
+msgstr "文件输出"
+
+msgid "Folder"
+msgstr "文件夹"
+
+msgid "Folder that contains webpages"
+msgstr "保存网页的文件夹"
+
+msgid "Frames per second"
+msgstr "帧每秒"
+
+msgid "HTTP output"
+msgstr "HTTP输出"
+
+msgid "Interval between saving pictures"
+msgstr "图片保存时间间隔"
+
+msgid "JPEG compression quality"
+msgstr "JPEG压缩品质"
+
+msgid "Led control"
+msgstr "LED控制"
+
+msgid "MJPG-streamer"
+msgstr "MJPG-streamer"
+
+msgid "Max. number of pictures to hold"
+msgstr "保存的图片数量上限"
+
+msgid "Mjpeg output"
+msgstr "Mjpeg输出"
+
+msgid "Off"
+msgstr "关"
+
+msgid "On"
+msgstr "开"
+
+msgid "Password"
+msgstr "密码"
+
+msgid "Port"
+msgstr "端口"
+
+msgid "Resolution"
+msgstr "分辨率"
+
+msgid "Ring buffer size"
+msgstr "环形缓冲区大小"
+
+msgid "Set folder to save pictures"
+msgstr "图片保存位置"
+
+msgid "Set the inteval in millisecond"
+msgstr "设置时间间隔(毫秒)"
+
+msgid ""
+"Set the minimum size if the webcam produces small-sized garbage frames. May "
+"happen under low light conditions"
+msgstr "设置无用帧的最小尺寸。当光照不足时可能出现无用帧。"
+
+msgid ""
+"Set the quality in percent. This setting activates YUYV format, disables "
+"MJPEG"
+msgstr "设置品质(百分比)。此设置会开启YUYV格式输出,关闭MJPEG输出。"
+
+msgid "TCP port for this HTTP server"
+msgstr "HTTP服务监听的TCP端口"
+
+msgid "UVC input"
+msgstr "UVC输入"
+
+msgid "Username"
+msgstr "用户名"
+
+msgid "WWW folder"
+msgstr "WWW文件夹"
+
+msgid ""
+"mjpg streamer is a streaming application for Linux-UVC compatible webcams"
+msgstr "mjpg streamer是一个视频流程序,用于兼容Linux-UVC的摄像头。"
diff --git a/applications/luci-app-multiwan/Makefile b/applications/luci-app-multiwan/Makefile
index 20fba89b0d..c5b731abbe 100644
--- a/applications/luci-app-multiwan/Makefile
+++ b/applications/luci-app-multiwan/Makefile
@@ -6,8 +6,8 @@
include $(TOPDIR)/rules.mk
-LUCI_TITLE:=LuCI Support for the OpenWrt MultiWAN agent
-LUCI_DEPENDS:=+multiwan
+LUCI_TITLE:=LuCI Support for the OpenWrt MultiWAN agent (obsoleted by mwan3)
+LUCI_DEPENDS:=+multiwan @BROKEN
include ../../luci.mk
diff --git a/applications/luci-app-ocserv/luasrc/controller/ocserv.lua b/applications/luci-app-ocserv/luasrc/controller/ocserv.lua
index 91bddc73dd..dbeaaf8524 100644
--- a/applications/luci-app-ocserv/luasrc/controller/ocserv.lua
+++ b/applications/luci-app-ocserv/luasrc/controller/ocserv.lua
@@ -44,7 +44,7 @@ function ocserv_status()
if not ln then break end
local id, user, group, vpn_ip, ip, device, time, cipher, status =
- ln:match("^%s*(%d+)%s+([-_%w]+)%s+([%.%*-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%(%)%:%.-_%w]+)%s+([%:%.-_%w]+).*")
+ ln:match("^%s*(%d+)%s+([-_%w]+)%s+([%(%)%.%*-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%(%)%:%.-_%w]+)%s+([%:%.-_%w]+).*")
if id then
fwd[#fwd+1] = {
id = id,
diff --git a/applications/luci-app-ocserv/luasrc/model/cbi/ocserv/users.lua b/applications/luci-app-ocserv/luasrc/model/cbi/ocserv/users.lua
index c4be1818f2..0fa997c8b3 100644
--- a/applications/luci-app-ocserv/luasrc/model/cbi/ocserv/users.lua
+++ b/applications/luci-app-ocserv/luasrc/model/cbi/ocserv/users.lua
@@ -47,7 +47,7 @@ if fd then local ln
if not ln then break end
local id, user, group, vpn_ip, ip, device, time, cipher, status =
- ln:match("^%s*(%d+)%s+([-_%w]+)%s+([%.%*-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%(%)%:%.-_%w]+)%s+([%:%.-_%w]+).*")
+ ln:match("^%s*(%d+)%s+([-_%w]+)%s+([%(%)%.%*-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%:%.-_%w]+)%s+([%(%)%:%.-_%w]+)%s+([%:%.-_%w]+).*")
if id then
table.insert(lusers, {id, user, group, vpn_ip, ip, device, time, cipher, status})
end
diff --git a/applications/luci-app-olsr/Makefile b/applications/luci-app-olsr/Makefile
index f30c242d53..93815a55e2 100644
--- a/applications/luci-app-olsr/Makefile
+++ b/applications/luci-app-olsr/Makefile
@@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=OLSR configuration and status module
-LUCI_DEPENDS:=+olsrd +olsrd-mod-jsoninfo +luci-lib-luaneightbl
+LUCI_DEPENDS:=+olsrd +olsrd-mod-jsoninfo +luci-lib-luaneightbl +luci-lib-json
include ../../luci.mk
diff --git a/applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua b/applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua
index 7e39dad2eb..fa1530026a 100644
--- a/applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua
+++ b/applications/luci-app-openvpn/luasrc/model/cbi/openvpn-advanced.lua
@@ -48,7 +48,7 @@ local knownParams = {
{ Flag, "client_disconnect", 0, translate("Run script cmd on client disconnection") },
{ Value, "learn_address", "/usr/bin/ovpn-learnaddress", translate("Executed in server mode whenever an IPv4 address/route or MAC address is added to OpenVPN's internal routing table") },
{ Value, "auth_user_pass_verify", "/usr/bin/ovpn-userpass via-env", translate("Executed in server mode on new client connections, when the client is still untrusted") },
- { ListValue, "script_security", { 0, 1, 2, 3 }, translate("Policy level over usage of external programs and scripts"), {mode="server" } },
+ { ListValue, "script_security", { 0, 1, 2, 3 }, translate("Policy level over usage of external programs and scripts") },
} },
{ "Networking", {
diff --git a/applications/luci-app-shadowsocks-libev/Makefile b/applications/luci-app-shadowsocks-libev/Makefile
new file mode 100644
index 0000000000..848a5c8317
--- /dev/null
+++ b/applications/luci-app-shadowsocks-libev/Makefile
@@ -0,0 +1,14 @@
+#
+# Copyright (C) 2008-2014 The LuCI Team <luci@lists.subsignal.org>
+#
+# This is free software, licensed under the Apache License, Version 2.0 .
+#
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:=LuCI Support for Shadowsocks-libev
+LUCI_DEPENDS:=
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-shadowsocks-libev/luasrc/controller/shadowsocks-libev.lua b/applications/luci-app-shadowsocks-libev/luasrc/controller/shadowsocks-libev.lua
new file mode 100644
index 0000000000..ae968168f1
--- /dev/null
+++ b/applications/luci-app-shadowsocks-libev/luasrc/controller/shadowsocks-libev.lua
@@ -0,0 +1,12 @@
+-- Copyright 2015 Jian Chang <aa65535@live.com>
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.controller.shadowsocks-libev", package.seeall)
+
+function index()
+ if not nixio.fs.access("/etc/config/shadowsocks-libev") then
+ return
+ end
+
+ entry({"admin", "services", "shadowsocks-libev"}, cbi("shadowsocks-libev"), _("ShadowSocks-libev"), 74).dependent = true
+end
diff --git a/applications/luci-app-shadowsocks-libev/luasrc/model/cbi/shadowsocks-libev.lua b/applications/luci-app-shadowsocks-libev/luasrc/model/cbi/shadowsocks-libev.lua
new file mode 100644
index 0000000000..76435e2f14
--- /dev/null
+++ b/applications/luci-app-shadowsocks-libev/luasrc/model/cbi/shadowsocks-libev.lua
@@ -0,0 +1,156 @@
+-- Copyright 2015 Jian Chang <aa65535@live.com>
+-- Licensed to the public under the Apache License 2.0.
+
+local m, s, o, e, a
+
+if luci.sys.call("pidof ss-redir >/dev/null") == 0 then
+ m = Map("shadowsocks-libev", translate("ShadowSocks-libev"), translate("ShadowSocks-libev is running"))
+else
+ m = Map("shadowsocks-libev", translate("ShadowSocks-libev"), translate("ShadowSocks-libev is not running"))
+end
+
+e = {
+ "table",
+ "rc4",
+ "rc4-md5",
+ "aes-128-cfb",
+ "aes-192-cfb",
+ "aes-256-cfb",
+ "bf-cfb",
+ "camellia-128-cfb",
+ "camellia-192-cfb",
+ "camellia-256-cfb",
+ "cast5-cfb",
+ "des-cfb",
+ "idea-cfb",
+ "rc2-cfb",
+ "seed-cfb",
+ "salsa20",
+ "chacha20",
+}
+
+-- Global Setting
+s = m:section(TypedSection, "shadowsocks-libev", translate("Global Setting"))
+s.anonymous = true
+
+o = s:option(Flag, "enable", translate("Enable"))
+o.default = 1
+o.rmempty = false
+
+o = s:option(Value, "server", translate("Server Address"))
+o.datatype = "ipaddr"
+o.rmempty = false
+
+o = s:option(Value, "server_port", translate("Server Port"))
+o.datatype = "port"
+o.rmempty = false
+
+o = s:option(Value, "local_port", translate("Local Port"))
+o.datatype = "port"
+o.default = 1080
+o.rmempty = false
+
+o = s:option(Value, "timeout", translate("Connection Timeout"))
+o.datatype = "uinteger"
+o.default = 60
+o.rmempty = false
+
+o = s:option(Value, "password", translate("Password"))
+o.password = true
+o.rmempty = false
+
+o = s:option(ListValue, "encrypt_method", translate("Encrypt Method"))
+for i,v in ipairs(e) do
+ o:value(v)
+end
+o.rmempty = false
+
+o = s:option(Value, "ignore_list", translate("Ignore List"))
+o:value("/dev/null", translate("Disabled"))
+o.default = "/dev/null"
+o.rmempty = false
+
+-- UDP Relay
+s = m:section(TypedSection, "shadowsocks-libev", translate("UDP Relay"))
+s.anonymous = true
+
+o = s:option(ListValue, "udp_mode", translate("Relay Mode"))
+o:value("0", translate("Disabled"))
+o:value("1", translate("Enabled"))
+o:value("2", translate("Custom"))
+o.default = 0
+o.rmempty = false
+
+o = s:option(Value, "udp_server", translate("Server Address"))
+o.datatype = "ipaddr"
+o:depends("udp_mode", 2)
+
+o = s:option(Value, "udp_server_port", translate("Server Port"))
+o.datatype = "port"
+o:depends("udp_mode", 2)
+
+o = s:option(Value, "udp_local_port", translate("Local Port"))
+o.datatype = "port"
+o.default = 1081
+o:depends("udp_mode", 2)
+
+o = s:option(Value, "udp_timeout", translate("Connection Timeout"))
+o.datatype = "uinteger"
+o.default = 60
+o:depends("udp_mode", 2)
+
+o = s:option(Value, "udp_password", translate("Password"))
+o.password = true
+o:depends("udp_mode", 2)
+
+o = s:option(ListValue, "udp_encrypt_method", translate("Encrypt Method"))
+for i,v in ipairs(e) do
+ o:value(v)
+end
+o:depends("udp_mode", 2)
+
+-- UDP Forward
+s = m:section(TypedSection, "shadowsocks-libev", translate("UDP Forward"))
+s.anonymous = true
+
+o = s:option(Flag, "tunnel_enable", translate("Enable"))
+o.default = 1
+o.rmempty = false
+
+o = s:option(Value, "tunnel_port", translate("UDP Local Port"))
+o.datatype = "port"
+o.default = 5300
+
+o = s:option(Value, "tunnel_forward", translate("Forwarding Tunnel"))
+o.default = "8.8.4.4:53"
+
+-- Access Control
+s = m:section(TypedSection, "shadowsocks-libev", translate("Access Control"))
+s.anonymous = true
+
+s:tab("lan_ac", translate("LAN"))
+
+o = s:taboption("lan_ac", ListValue, "lan_ac_mode", translate("Access Control"))
+o:value("0", translate("Disabled"))
+o:value("1", translate("Allow listed only"))
+o:value("2", translate("Allow all except listed"))
+o.default = 0
+o.rmempty = false
+
+a = luci.sys.net.arptable() or {}
+
+o = s:taboption("lan_ac", DynamicList, "lan_ac_ip", translate("LAN IP List"))
+o.datatype = "ipaddr"
+for i,v in ipairs(a) do
+ o:value(v["IP address"])
+end
+
+s:tab("wan_ac", translate("WAN"))
+
+o = s:taboption("wan_ac", DynamicList, "wan_bp_ip", translate("Bypassed IP"))
+o.datatype = "ip4addr"
+
+o = s:taboption("wan_ac", DynamicList, "wan_fw_ip", translate("Forwarded IP"))
+o.datatype = "ip4addr"
+
+return m
diff --git a/applications/luci-app-shadowsocks-libev/po/templates/shadowsocks-libev.pot b/applications/luci-app-shadowsocks-libev/po/templates/shadowsocks-libev.pot
new file mode 100644
index 0000000000..c2bde961e0
--- /dev/null
+++ b/applications/luci-app-shadowsocks-libev/po/templates/shadowsocks-libev.pot
@@ -0,0 +1,80 @@
+msgid ""
+msgstr "Content-Type: text/plain; charset=UTF-8"
+
+msgid "ShadowSocks-libev"
+msgstr ""
+
+msgid "ShadowSocks-libev is running"
+msgstr ""
+
+msgid "ShadowSocks-libev is not running"
+msgstr ""
+
+msgid "Global Setting"
+msgstr ""
+
+msgid "Enable"
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid "Disabled"
+msgstr ""
+
+msgid "Custom"
+msgstr ""
+
+msgid "Server Address"
+msgstr ""
+
+msgid "Server Port"
+msgstr ""
+
+msgid "Local Port"
+msgstr ""
+
+msgid "Connection Timeout"
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "Encrypt Method"
+msgstr ""
+
+msgid "Ignore List"
+msgstr ""
+
+msgid "UDP Relay"
+msgstr ""
+
+msgid "Relay Mode"
+msgstr ""
+
+msgid "UDP Forward"
+msgstr ""
+
+msgid "UDP Local Port"
+msgstr ""
+
+msgid "Forwarding Tunnel"
+msgstr ""
+
+msgid "Access Control"
+msgstr ""
+
+msgid "Allow listed only"
+msgstr ""
+
+msgid "Allow all except listed"
+msgstr ""
+
+msgid "LAN IP List"
+msgstr ""
+
+msgid "Bypassed IP"
+msgstr ""
+
+msgid "Forwarded IP"
+msgstr ""
diff --git a/applications/luci-app-shadowsocks-libev/po/zh-cn/shadowsocks-libev.po b/applications/luci-app-shadowsocks-libev/po/zh-cn/shadowsocks-libev.po
new file mode 100644
index 0000000000..90a0eff996
--- /dev/null
+++ b/applications/luci-app-shadowsocks-libev/po/zh-cn/shadowsocks-libev.po
@@ -0,0 +1,91 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-11-12 14:12+0800\n"
+"PO-Revision-Date: 2015-07-02 14:26+0800\n"
+"Last-Translator: Jian Chang <aa65535@live.com>\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Pootle 2.0.6\n"
+
+msgid "ShadowSocks-libev"
+msgstr "ShadowSocks-libev"
+
+msgid "ShadowSocks-libev is running"
+msgstr "ShadowSocks-libev 运行中"
+
+msgid "ShadowSocks-libev is not running"
+msgstr "ShadowSocks-libev 未运行"
+
+msgid "Global Setting"
+msgstr "全局设置"
+
+msgid "Enable"
+msgstr "启用"
+
+msgid "Enabled"
+msgstr "已启用"
+
+msgid "Disabled"
+msgstr "已禁用"
+
+msgid "Custom"
+msgstr "自定义"
+
+msgid "Server Address"
+msgstr "服务器地址"
+
+msgid "Server Port"
+msgstr "服务器端口"
+
+msgid "Local Port"
+msgstr "本地端口"
+
+msgid "Connection Timeout"
+msgstr "连接超时"
+
+msgid "Password"
+msgstr "密码"
+
+msgid "Encrypt Method"
+msgstr "加密方式"
+
+msgid "Ignore List"
+msgstr "忽略列表"
+
+msgid "UDP Relay"
+msgstr "UDP中继"
+
+msgid "Relay Mode"
+msgstr "中继模式"
+
+msgid "UDP Forward"
+msgstr "UDP转发"
+
+msgid "UDP Local Port"
+msgstr "UDP本地端口"
+
+msgid "Forwarding Tunnel"
+msgstr "UDP转发地址"
+
+msgid "Access Control"
+msgstr "访问控制"
+
+msgid "Allow listed only"
+msgstr "仅允许列表内"
+
+msgid "Allow all except listed"
+msgstr "仅允许列表外"
+
+msgid "LAN IP List"
+msgstr "内网IP列表"
+
+msgid "Bypassed IP"
+msgstr "被忽略的IP"
+
+msgid "Forwarded IP"
+msgstr "走代理的IP"
diff --git a/applications/luci-app-shadowsocks-libev/root/etc/uci-defaults/luci-shadowsocks-libev b/applications/luci-app-shadowsocks-libev/root/etc/uci-defaults/luci-shadowsocks-libev
new file mode 100644
index 0000000000..6f30fa77b7
--- /dev/null
+++ b/applications/luci-app-shadowsocks-libev/root/etc/uci-defaults/luci-shadowsocks-libev
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+uci -q batch <<-EOF >/dev/null
+ delete ucitrack.@shadowsocks-libev[-1]
+ add ucitrack shadowsocks-libev
+ set ucitrack.@shadowsocks-libev[-1].init=shadowsocks-libev
+ commit ucitrack
+EOF
+
+rm -f /tmp/luci-indexcache
+exit 0
diff --git a/applications/luci-app-statistics/luasrc/controller/luci_statistics/luci_statistics.lua b/applications/luci-app-statistics/luasrc/controller/luci_statistics/luci_statistics.lua
index c532b4a6d3..49eab5acd4 100644
--- a/applications/luci-app-statistics/luasrc/controller/luci_statistics/luci_statistics.lua
+++ b/applications/luci-app-statistics/luasrc/controller/luci_statistics/luci_statistics.lua
@@ -30,6 +30,7 @@ function index()
disk = _("Disk Usage"),
dns = _("DNS"),
email = _("Email"),
+ entropy = _("Entropy"),
exec = _("Exec"),
interface = _("Interfaces"),
iptables = _("Firewall"),
@@ -53,7 +54,7 @@ function index()
-- our collectd menu
local collectd_menu = {
output = { "csv", "network", "rrdtool", "unixsock" },
- system = { "cpu", "df", "disk", "email", "exec", "irq", "load", "memory", "nut", "processes", "uptime" },
+ system = { "cpu", "df", "disk", "email", "entropy", "exec", "irq", "load", "memory", "nut", "processes", "uptime" },
network = { "conntrack", "dns", "interface", "iptables", "netlink", "olsrd", "ping", "splash_leases", "tcpconns", "iwinfo" }
}
diff --git a/applications/luci-app-statistics/luasrc/model/cbi/luci_statistics/entropy.lua b/applications/luci-app-statistics/luasrc/model/cbi/luci_statistics/entropy.lua
new file mode 100644
index 0000000000..d18bf910f9
--- /dev/null
+++ b/applications/luci-app-statistics/luasrc/model/cbi/luci_statistics/entropy.lua
@@ -0,0 +1,14 @@
+-- Copyright 2015 Hannu Nyman <hannu.nyman@iki.fi>
+-- Licensed to the public under the Apache License 2.0.
+
+m = Map("luci_statistics",
+ translate("Entropy Plugin Configuration"),
+ translate("The entropy plugin collects statistics about the available entropy."))
+
+s = m:section( NamedSection, "collectd_entropy", "luci_statistics" )
+
+enable = s:option( Flag, "enable", translate("Enable this plugin") )
+enable.default = 0
+
+return m
+
diff --git a/applications/luci-app-statistics/luasrc/statistics/rrdtool.lua b/applications/luci-app-statistics/luasrc/statistics/rrdtool.lua
index 1f8f4ff88b..d8317a8177 100644
--- a/applications/luci-app-statistics/luasrc/statistics/rrdtool.lua
+++ b/applications/luci-app-statistics/luasrc/statistics/rrdtool.lua
@@ -457,6 +457,12 @@ function Graph._generic( self, opts, plugin, plugin_instance, dtype, index )
_ti ( _args, "-X" )
_ti ( _args, opts.units_exponent )
end
+ if opts.alt_autoscale then
+ _ti ( _args, "-A" )
+ end
+ if opts.alt_autoscale_max then
+ _ti ( _args, "-M" )
+ end
-- store additional rrd options
if opts.rrdopts then
diff --git a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/conntrack.lua b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/conntrack.lua
index ee3d68fe16..fbc47731ef 100644
--- a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/conntrack.lua
+++ b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/conntrack.lua
@@ -9,6 +9,10 @@ function rrdargs( graph, plugin, plugin_instance, dtype )
vlabel = "Count",
number_format = "%5.0lf",
data = {
+ -- collectd 5.5+: specify "" to exclude "max" instance
+ instances = {
+ conntrack = { "" }
+ },
sources = {
conntrack = { "value" }
},
diff --git a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/cpu.lua b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/cpu.lua
index 1ca8a23ee9..ae0c0ce778 100644
--- a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/cpu.lua
+++ b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/cpu.lua
@@ -8,22 +8,23 @@ function rrdargs( graph, plugin, plugin_instance, dtype )
return {
title = "%H: Processor usage on core #%pi",
y_min = "0",
+ alt_autoscale_max = true,
vlabel = "Percent",
number_format = "%5.1lf%%",
data = {
instances = {
- cpu = { "idle", "user", "system", "nice" }
+ cpu = { "user", "nice", "system", "softirq", "interrupt" }
},
options = {
- cpu_idle = { color = "ffffff" },
- cpu_nice = { color = "00e000" },
- cpu_user = { color = "0000ff" },
- cpu_wait = { color = "ffb000" },
- cpu_system = { color = "ff0000" },
- cpu_softirq = { color = "ff00ff" },
- cpu_interrupt = { color = "a000a0" },
- cpu_steal = { color = "000000" }
+ cpu_idle = { color = "ffffff", title = "Idle" },
+ cpu_nice = { color = "00e000", title = "Nice" },
+ cpu_user = { color = "0000ff", title = "User" },
+ cpu_wait = { color = "ffb000", title = "Wait" },
+ cpu_system = { color = "ff0000", title = "System" },
+ cpu_softirq = { color = "ff00ff", title = "Softirq" },
+ cpu_interrupt = { color = "a000a0", title = "Interrupt" },
+ cpu_steal = { color = "000000", title = "Steal" }
}
}
}
diff --git a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/entropy.lua b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/entropy.lua
new file mode 100644
index 0000000000..3d30a70afb
--- /dev/null
+++ b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/entropy.lua
@@ -0,0 +1,19 @@
+-- Copyright 2015 Hannu Nyman <hannu.nyman@iki.fi>
+-- Licensed to the public under the Apache License 2.0.
+
+module("luci.statistics.rrdtool.definitions.entropy", package.seeall)
+
+function rrdargs( graph, plugin, plugin_instance, dtype )
+
+ return {
+ title = "%H: Available entropy",
+ vlabel = "bits",
+ number_format = "%4.0lf",
+ data = {
+ types = { "entropy" },
+ options = { entropy = { title = "Entropy %di" } }
+ }
+ }
+
+end
+
diff --git a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/memory.lua b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/memory.lua
index a1c65f56d7..53d559c599 100644
--- a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/memory.lua
+++ b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/memory.lua
@@ -17,6 +17,8 @@ function rrdargs( graph, plugin, plugin_instance, dtype )
title = "%H: Memory usage",
vlabel = "MB",
number_format = "%5.1lf%s",
+ y_min = "0",
+ alt_autoscale_max = true,
data = {
instances = {
memory = { "free", "buffered", "cached", "used" }
diff --git a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/ping.lua b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/ping.lua
index 1a72caf227..347d756f7c 100644
--- a/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/ping.lua
+++ b/applications/luci-app-statistics/luasrc/statistics/rrdtool/definitions/ping.lua
@@ -9,7 +9,7 @@ function rrdargs( graph, plugin, plugin_instance, dtype )
{ title = "%H: ICMP Round Trip Time", vlabel = "ms",
number_format = "%5.1lf ms", data = {
sources = { ping = { "value" } },
- options = { ping__ping = { noarea = true, title = "%di" } }
+ options = { ping__value = { noarea = true, title = "%di" } }
} },
-- Ping droprate
diff --git a/applications/luci-app-statistics/luasrc/view/admin_statistics/index.htm b/applications/luci-app-statistics/luasrc/view/admin_statistics/index.htm
index 0000c1961e..0fb3d56375 100644
--- a/applications/luci-app-statistics/luasrc/view/admin_statistics/index.htm
+++ b/applications/luci-app-statistics/luasrc/view/admin_statistics/index.htm
@@ -8,7 +8,10 @@
<h2><a id="content" name="content"><%:Statistics%></a></h2>
-<p><%_The statistics package is based on <a href="http://collectd.org/index.shtml">Collectd</a>
-and uses <a href="http://oss.oetiker.ch/rrdtool/">RRD Tool</a> to render diagram images from collected data.%></p>
+<p><%_The statistics package uses <a href="https://collectd.org/">Collectd</a>
+to gather data and <a href="http://oss.oetiker.ch/rrdtool/">RRDtool</a> to
+render diagram images.%></p>
+
+<p><%_You can install additional collectd-mod-* plugins to enable more statistics.%></p>
<%+footer%>
diff --git a/applications/luci-app-statistics/root/etc/config/luci_statistics b/applications/luci-app-statistics/root/etc/config/luci_statistics
index e39db3513a..abcee3e938 100644
--- a/applications/luci-app-statistics/root/etc/config/luci_statistics
+++ b/applications/luci-app-statistics/root/etc/config/luci_statistics
@@ -1,143 +1,153 @@
-config 'statistics' 'rrdtool'
- option 'default_timespan' '1hour'
- option 'image_width' '600'
- option 'image_path' '/tmp/rrdimg'
-
-config 'statistics' 'collectd'
- option 'BaseDir' '/var/run/collectd'
- option 'Include' '/etc/collectd/conf.d'
- option 'PIDFile' '/var/run/collectd.pid'
- option 'PluginDir' '/usr/lib/collectd'
- option 'TypesDB' '/usr/share/collectd/types.db'
- option 'Interval' '30'
- option 'ReadThreads' '2'
-
-config 'statistics' 'collectd_ping'
- option 'enable' '0'
- option 'TTL' '127'
- option 'Interval' '30'
- option 'Hosts' '127.0.0.1'
-
-config 'statistics' 'collectd_csv'
- option 'enable' '0'
- option 'StoreRates' '0'
- option 'DataDir' '/tmp'
-
-config 'statistics' 'collectd_df'
- option 'enable' '0'
- option 'Devices' '/dev/mtdblock/4'
- option 'MountPoints' '/jffs'
- option 'FSTypes' 'tmpfs'
- option 'IgnoreSelected' '0'
-
-config 'statistics' 'collectd_disk'
- option 'enable' '0'
- option 'Disks' 'hda1 hdb'
- option 'IgnoreSelected' '0'
-
-config 'statistics' 'collectd_dns'
- option 'enable' '0'
- option 'Interfaces' 'ffdhcp ff br-lan'
- option 'IgnoreSources' '127.0.0.1'
-
-config 'statistics' 'collectd_email'
- option 'enable' '0'
- option 'SocketFile' '/var/run/collectd/email.sock'
- option 'SocketGroup' 'nogroup'
-
-config 'statistics' 'collectd_exec'
- option 'enable' '0'
-
-config 'statistics' 'collectd_interface'
- option 'enable' '1'
- option 'Interfaces' 'br-lan br-ff'
- option 'IgnoreSelected' '0'
-
-config 'statistics' 'collectd_iptables'
- option 'enable' '1'
-
-config 'collectd_iptables_match'
- option 'table' 'nat'
- option 'chain' 'luci_fw_postrouting'
- option 'target' 'MASQUERADE'
- option 'source' '192.168.1.0/24'
- option 'outputif' 'br-ff'
- option 'name' 'Verkehr LAN-Clients'
-
-config 'collectd_iptables_match'
- option 'chain' 'luci_fw_postrouting'
- option 'table' 'nat'
- option 'target' 'MASQUERADE'
- option 'source' '10.61.230.0/24'
- option 'outputif' 'br-ff'
- option 'name' 'Verkehr WLAN-Clients'
-
-config 'statistics' 'collectd_irq'
- option 'enable' '0'
- option 'Irqs' '2 3 4 7'
-
-config 'statistics' 'collectd_load'
- option 'enable' '1'
-
-config 'statistics' 'collectd_logfile'
- option 'enable' '0'
- option 'LogLevel' 'notice'
- option 'File' '/var/log/collectd.log'
- option 'Timestamp' '1'
-
-config 'statistics' 'collectd_netlink'
- option 'enable' '0'
- option 'IgnoreSelected' '0'
- option 'VerboseInterfaces' 'br-lan br-ff'
- option 'QDiscs' 'br-lan br-ff'
-
-config 'statistics' 'collectd_network'
- option 'enable' '0'
-
-config 'statistics' 'collectd_processes'
- option 'enable' '1'
- option 'Processes' 'uhttpd dnsmasq dropbear'
-
-config statistics 'collectd_splash_leases'
- option enable '1'
-
-config 'statistics' 'collectd_tcpconns'
- option 'enable' '1'
- option 'ListeningPorts' '0'
- option 'LocalPorts' '22 80'
-
-config 'statistics' 'collectd_unixsock'
- option 'enable' '0'
- option 'SocketFile' '/var/run/collectd/query.sock'
- option 'SocketGroup' 'nogroup'
-
-config 'statistics' 'collectd_cpu'
- option 'enable' '1'
-
-config 'statistics' 'collectd_rrdtool'
- option 'enable' '1'
- option 'DataDir' '/tmp/rrd'
- option 'RRARows' '100'
- option 'RRASingle' '1'
- option 'RRATimespans' '1hour 1day 1week 1month 1year'
-
-config 'statistics' 'collectd_memory'
- option 'enable' '1'
-
-config 'statistics' 'collectd_conntrack'
- option 'enable' '1'
-
-config 'statistics' 'collectd_olsrd'
- option 'enable' '1'
- option 'Port' '2006'
- option 'Host' '127.0.0.1'
-
-config 'statistics' 'collectd_iwinfo'
- option 'enable' '1'
-
-config 'statistics' 'collectd_nut'
- option 'enable' '0'
- option 'UPS' 'myupsname'
-
-config 'statistics' 'collectd_uptime'
- option 'enable' '1'
+# general settings
+
+config statistics 'collectd'
+ option BaseDir '/var/run/collectd'
+ option Include '/etc/collectd/conf.d'
+ option PIDFile '/var/run/collectd.pid'
+ option PluginDir '/usr/lib/collectd'
+ option TypesDB '/usr/share/collectd/types.db'
+ option Interval '30'
+ option ReadThreads '2'
+
+config statistics 'rrdtool'
+ option default_timespan '1hour'
+ option image_width '600'
+ option image_path '/tmp/rrdimg'
+
+# output plugins
+
+config statistics 'collectd_rrdtool'
+ option enable '1'
+ option DataDir '/tmp/rrd'
+ option RRARows '100'
+ option RRASingle '1'
+ option RRATimespans '1hour 1day 1week 1month 1year'
+
+config statistics 'collectd_csv'
+ option enable '0'
+ option StoreRates '0'
+ option DataDir '/tmp'
+
+config statistics 'collectd_email'
+ option enable '0'
+ option SocketFile '/var/run/collectd/email.sock'
+ option SocketGroup 'nogroup'
+
+config statistics 'collectd_logfile'
+ option enable '0'
+ option LogLevel 'notice'
+ option File '/var/log/collectd.log'
+ option Timestamp '1'
+
+config statistics 'collectd_network'
+ option enable '0'
+
+config statistics 'collectd_unixsock'
+ option enable '0'
+ option SocketFile '/var/run/collectd/query.sock'
+ option SocketGroup 'nogroup'
+
+# input plugins
+
+config statistics 'collectd_conntrack'
+ option enable '0'
+
+config statistics 'collectd_cpu'
+ option enable '0'
+
+config statistics 'collectd_df'
+ option enable '0'
+ option Devices '/dev/mtdblock/4'
+ option MountPoints '/jffs'
+ option FSTypes 'tmpfs'
+ option IgnoreSelected '0'
+
+config statistics 'collectd_disk'
+ option enable '0'
+ option Disks 'hda1 hdb'
+ option IgnoreSelected '0'
+
+config statistics 'collectd_dns'
+ option enable '0'
+ option Interfaces 'br-lan'
+ option IgnoreSources '127.0.0.1'
+
+config statistics 'collectd_entropy'
+ option enable '0'
+
+config statistics 'collectd_exec'
+ option enable '0'
+
+config statistics 'collectd_interface'
+ option enable '1'
+ option Interfaces 'br-lan'
+ option IgnoreSelected '0'
+
+config statistics 'collectd_iptables'
+ option enable '0'
+
+config collectd_iptables_match
+ option table 'nat'
+ option chain 'luci_fw_postrouting'
+ option target 'MASQUERADE'
+ option source '192.168.1.0/24'
+ option outputif 'br-ff'
+ option name 'LAN-Clients traffic'
+
+config collectd_iptables_match
+ option chain 'luci_fw_postrouting'
+ option table 'nat'
+ option target 'MASQUERADE'
+ option source '10.61.230.0/24'
+ option outputif 'br-ff'
+ option name 'WLAN-Clients traffic'
+
+config statistics 'collectd_irq'
+ option enable '0'
+ option Irqs '2 3 4 7'
+
+config statistics 'collectd_iwinfo'
+ option enable '1'
+
+config statistics 'collectd_load'
+ option enable '1'
+
+config statistics 'collectd_memory'
+ option enable '0'
+
+config statistics 'collectd_netlink'
+ option enable '0'
+ option IgnoreSelected '0'
+ option VerboseInterfaces 'br-lan'
+ option QDiscs 'br-lan'
+
+config statistics 'collectd_nut'
+ option enable '0'
+ option UPS 'myupsname'
+
+config statistics 'collectd_olsrd'
+ option enable '0'
+ option Port '2006'
+ option Host '127.0.0.1'
+
+config statistics 'collectd_ping'
+ option enable '0'
+ option TTL '127'
+ option Interval '30'
+ option Hosts '127.0.0.1'
+
+config statistics 'collectd_processes'
+ option enable '0'
+ option Processes 'uhttpd dnsmasq dropbear'
+
+config statistics 'collectd_splash_leases'
+ option enable '0'
+
+config statistics 'collectd_tcpconns'
+ option enable '0'
+ option ListeningPorts '0'
+ option LocalPorts '22 80'
+
+config statistics 'collectd_uptime'
+ option enable '0'
+
diff --git a/applications/luci-app-statistics/root/etc/init.d/luci_statistics b/applications/luci-app-statistics/root/etc/init.d/luci_statistics
index 936f3a63c3..ab75b69df0 100755
--- a/applications/luci-app-statistics/root/etc/init.d/luci_statistics
+++ b/applications/luci-app-statistics/root/etc/init.d/luci_statistics
@@ -3,23 +3,15 @@ START=79
start() {
### replace shipped config with symlink
+ mkdir -p /var/etc
if [ ! -L /etc/collectd.conf ]; then
test -f /etc/collectd.conf && mv /etc/collectd.conf /etc/collectd.conf.bak
ln -s /var/etc/collectd.conf /etc/collectd.conf
fi
### create config
- mkdir -p /var/etc
/usr/bin/stat-genconfig > /var/etc/collectd.conf
- ### prepare rrdimg directory
- if [ -f /etc/config/lucid ] && [ -x /etc/init.d/lucid ] && /etc/init.d/lucid enabled && \
- [ "$(uci get luci_statistics.rrdtool.image_path 2>/dev/null)" != "$(uci get lucid.statistics.physical 2>/dev/null)" ]; then
- uci set lucid.statistics.physical=$(uci get luci_statistics.rrdtool.image_path)
- uci commit lucid
- /etc/init.d/lucid restart
- fi
-
### workaround broken permissions on /tmp
chmod 1777 /tmp
}
diff --git a/applications/luci-app-statistics/root/etc/uci-defaults/luci-statistics b/applications/luci-app-statistics/root/etc/uci-defaults/luci-statistics
index e94a8637c8..28e35298a2 100755
--- a/applications/luci-app-statistics/root/etc/uci-defaults/luci-statistics
+++ b/applications/luci-app-statistics/root/etc/uci-defaults/luci-statistics
@@ -8,29 +8,9 @@ uci -q batch <<-EOF >/dev/null
commit ucitrack
EOF
-# register LuCId virtual path handler
-[ -f /etc/config/lucid ] && \
-uci -q batch <<-EOF >/dev/null
- delete lucid.statistics
-
- set lucid.statistics=DirectoryPublisher
- set lucid.statistics.name='RRDTool Image Cache'
- set lucid.statistics.physical=/tmp/rrdimg
- set lucid.statistics.virtual=/rrdimg
- set lucid.statistics.domain=''
-
- add_list lucid.http.publisher=statistics
- add_list lucid.https.publisher=statistics
-
- commit lucid
-EOF
-
# symlink for busybox httpd
[ -x /usr/sbin/httpd ] && [ ! -h /www/rrdimg ] && \
ln -s /tmp/rrdimg /www/rrdimg
-# restart LuCId service
-[ -x /etc/init.d/lucid ] && /etc/init.d/lucid enabled && /etc/init.d/lucid restart
-
rm -f /tmp/luci-indexcache
exit 0
diff --git a/applications/luci-app-statistics/root/usr/bin/stat-genconfig b/applications/luci-app-statistics/root/usr/bin/stat-genconfig
index cb94e28118..8acae46c61 100755
--- a/applications/luci-app-statistics/root/usr/bin/stat-genconfig
+++ b/applications/luci-app-statistics/root/usr/bin/stat-genconfig
@@ -303,6 +303,12 @@ plugins = {
{ }
},
+ entropy = {
+ { },
+ { },
+ { }
+ },
+
exec = config_exec,
interface = {
diff --git a/applications/luci-app-upnp/root/etc/uci-defaults/luci-upnp b/applications/luci-app-upnp/root/etc/uci-defaults/luci-upnp
deleted file mode 100755
index fe22a3e3c1..0000000000
--- a/applications/luci-app-upnp/root/etc/uci-defaults/luci-upnp
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-/etc/init.d/miniupnpd enabled && {
- /etc/init.d/miniupnpd stop
- /etc/init.d/miniupnpd disable
-}
-
-rm -f /tmp/luci-indexcache
-exit 0
diff --git a/applications/luci-app-vnstat/luasrc/view/vnstat.htm b/applications/luci-app-vnstat/luasrc/view/vnstat.htm
index cfa1a5de51..2b502559b8 100644
--- a/applications/luci-app-vnstat/luasrc/view/vnstat.htm
+++ b/applications/luci-app-vnstat/luasrc/view/vnstat.htm
@@ -22,7 +22,7 @@ style = (style and #style > 0) and style or "s"
--
if iface then
style = style:gsub("[^%w]", "")
- iface = iface:gsub("[^%w%.%-]", "")
+ iface = iface:gsub("[^%w%.%-%_]", "")
luci.http.prepare_content("image/png")
diff --git a/contrib/package/community-profiles/files/etc/config/profile_hameln b/contrib/package/community-profiles/files/etc/config/profile_hameln
new file mode 100644
index 0000000000..f305b597a1
--- /dev/null
+++ b/contrib/package/community-profiles/files/etc/config/profile_hameln
@@ -0,0 +1,15 @@
+config 'community' 'profile'
+ option 'name' 'Hameln'
+ option 'homepage' 'http://freifunk-hameln.de'
+ option 'ssid' 'hameln.freifunk.net'
+ option 'suffix' 'ffhm'
+ option 'latitude' '52.1030706'
+ option 'longitude' '9.3514778'
+ option 'mesh_network' '10.31.0.0/16'
+ option 'splash_network' '10.104.0.0/16'
+ option 'splash_prefix' '27'
+ option 'vap' '1'
+ option adhoc_dhcp_when_vap '1'
+
+config 'defaults' 'interface'
+ option 'netmask' '255.255.0.0'
diff --git a/contrib/package/freifunk-watchdog/src/watchdog.h b/contrib/package/freifunk-watchdog/src/watchdog.h
index 3aa8876400..6f2382de38 100644
--- a/contrib/package/freifunk-watchdog/src/watchdog.h
+++ b/contrib/package/freifunk-watchdog/src/watchdog.h
@@ -29,6 +29,7 @@
#include <math.h>
#include <time.h>
#include <signal.h>
+#include <limits.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
diff --git a/contrib/package/meshwizard/Makefile b/contrib/package/meshwizard/Makefile
index 6959c544cf..b4baab7fa4 100644
--- a/contrib/package/meshwizard/Makefile
+++ b/contrib/package/meshwizard/Makefile
@@ -4,7 +4,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=meshwizard
-PKG_RELEASE:=0.3.0
+PKG_RELEASE:=0.3.1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
diff --git a/contrib/package/meshwizard/files/usr/bin/meshwizard/functions.sh b/contrib/package/meshwizard/files/usr/bin/meshwizard/functions.sh
index 8ace21853d..b0f6cb291e 100644
--- a/contrib/package/meshwizard/files/usr/bin/meshwizard/functions.sh
+++ b/contrib/package/meshwizard/files/usr/bin/meshwizard/functions.sh
@@ -44,7 +44,7 @@ set_defaults() {
a="$(echo $option |cut -d '=' -f1)"
b="$(echo $option |cut -d '=' -f2-)"
b="${b//_/ }"
- string_contains "$a" "_LENGTH" && return
+ string_contains "$a" "_LENGTH" && continue
string_contains "$a" "_ITEM" && {
# special threatment for lists. use add_list and remove the
# item index (_ITEMx).
diff --git a/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_dhcp.sh b/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_dhcp.sh
index 707178d276..8cce8319a6 100755
--- a/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_dhcp.sh
+++ b/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_dhcp.sh
@@ -23,15 +23,19 @@ config_foreach handle_dnsmasq dhcp
if [ "$supports_vap" = 1 -a "$vap" = 1 ]; then
uci batch <<- EOF
set dhcp.${netrenamed}dhcp="dhcp"
+ set dhcp.${netrenamed}dhcp.ignore="0"
set dhcp.${netrenamed}dhcp.interface="${netrenamed}dhcp"
EOF
set_defaults "dhcp_" dhcp.${netrenamed}dhcp
fi
ahdhcp_when_vap="$(uci get profile_$community.profile.adhoc_dhcp_when_vap)"
-if [ "$supports_vap" = 0 ] || [ "$supports_vap" = 1 -a "$vap" = 1 -a "$ahdhcp_when_vap" = 1 ]; then
+if [ "$supports_vap" = 0 ] || \
+ [ "$supports_vap" = 1 -a "$vap" = 1 -a "$ahdhcp_when_vap" = 1 ] || \
+ [ "$lan_is_olsr" = "1" -a "$lan_dhcp" = 1 ]; then
uci batch <<- EOF
set dhcp.${netrenamed}ahdhcp="dhcp"
+ set dhcp.${netrenamed}ahdhcp.ignore="0"
set dhcp.${netrenamed}ahdhcp.interface="${netrenamed}ahdhcp"
EOF
fi
diff --git a/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_firewall.sh b/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_firewall.sh
index 52659457d1..154b2b6913 100755
--- a/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_firewall.sh
+++ b/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_firewall.sh
@@ -7,7 +7,6 @@
. $dir/functions.sh
wan_is_olsr=$(uci -q get meshwizard.netconfig.wan_config)
-lan_is_olsr=$(uci -q get meshwizard.netconfig.lan_config)
config_load firewall
@@ -34,7 +33,7 @@ handle_fwzone() {
fi
fi
- if [ "$name" == "lan" ] && [ "$lan_is_olsr" == 1 ]; then
+ if [ "$name" == "lan" ] && [ "$lan_is_olsr" == "1" ]; then
uci set firewall.$1.network=' ' && uci_commitverbose "LAN is used for olsr, removed the lan interface from zone lan" firewall
fi
}
diff --git a/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_network.sh b/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_network.sh
index d8aa8a095f..7035e7fb4b 100755
--- a/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_network.sh
+++ b/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_network.sh
@@ -1,6 +1,6 @@
# setup entry in /etc/config/network for a interface
# Argument $1: network interface
-
+
net="$1"
. /lib/functions.sh
. $dir/functions.sh
@@ -24,6 +24,13 @@ uci batch << EOF
set network.$netrenamed.netmask="$netmask"
EOF
+if [ "$netrenamed" = "lan" ]; then
+ # remove the bridge if the interface is used for olsr
+ # since this script is only run in this case, no need
+ # to check for lan_proto = "olsr" currently.
+ uci -q delete network.lan.type
+fi
+
# Setup IPv6 for the interface
local ip6addr
if [ "$ipv6_enabled" = 1 ]; then
@@ -116,9 +123,16 @@ if [ "$net_dhcp" == 1 ]; then
# Setup alias for $net adhoc interface
- if [ "$supports_vap" = 0 ] || [ "$vap" = 0 ] || [ "$supports_vap" = 1 -a "$vap" = 1 -a "$ahdhcp_when_vap" = 1 ]; then
- # vaps are either not supported or enabled or they are supported and enabled
- # but we also want to use DHCP on the adhoc interface
+ if [ "$supports_vap" = 0 ] || \
+ [ "$vap" = 0 ] || \
+ [ "$supports_vap" = 1 -a "$vap" = 1 -a "$ahdhcp_when_vap" = 1 ] || \
+ [ "$lan_is_olsr" = "1" ]; then
+ # setup an alias interface for the main interface to use as a network for clients
+ # when one of the following conditions is met
+ # * vaps are not supported
+ # * or not enabled
+ # * or they are supported and enabled but we also want to use DHCP on the adhoc interface
+ # * or this is the lan interface and it is used for olsrd (and dhcp is enabled)
uci batch <<- EOF
set network.${netrenamed}ahdhcp=interface
set network.${netrenamed}ahdhcp.ifname="@${netrenamed}"
@@ -126,6 +140,6 @@ if [ "$net_dhcp" == 1 ]; then
set network.${netrenamed}ahdhcp.ipaddr="$STARTADHOC"
set network.${netrenamed}ahdhcp.netmask="$NETMASKADHOC"
EOF
+ uci_commitverbose "Setup interface for ${netrenamed}ahdhcp" network
fi
- uci_commitverbose "Setup interface for ${netrenamed}ahdhcp" network
fi
diff --git a/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_splash.sh b/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_splash.sh
index 7cac3d6979..3c3e6a32e2 100755
--- a/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_splash.sh
+++ b/contrib/package/meshwizard/files/usr/bin/meshwizard/helpers/setup_splash.sh
@@ -25,7 +25,7 @@ splash_net_add() {
EOF
}
-if [ "$(uci -q get meshwizard.netconfig.$net\_dhcp)" == 1 ] && [ -n "$dhcprange" ]; then
+if [ "$(uci -q get meshwizard.netconfig.$net\_dhcp)" = 1 ] && [ -n "$dhcprange" ]; then
handle_splash() {
config_get network "$1" network
if [ "$network" == "${netrenamed}dhcp" ]; then
@@ -38,13 +38,15 @@ if [ "$(uci -q get meshwizard.netconfig.$net\_dhcp)" == 1 ] && [ -n "$dhcprange"
config_foreach handle_splash iface
if [ "$supports_vap" = 1 -a "$vap" = 1 ]; then
- splash_net_add ${netrenamed}dhcp
+ splash_net_add ${netrenamed}dhcp
uci_commitverbose "Setup dhcpsplash for ${netrenamed}dhcp" luci_splash
fi
ahdhcp_when_vap="$(uci get profile_$community.profile.adhoc_dhcp_when_vap)"
- if [ "$supports_vap" = 0 ] || [ "$supports_vap" = 1 -a "$vap" = 1 -a "$ahdhcp_when_vap" = 1 ]; then
- splash_net_add ${netrenamed}ahdhcp
+ if [ "$supports_vap" = 0 ] || \
+ [ "$supports_vap" = 1 -a "$vap" = 1 -a "$ahdhcp_when_vap" = 1 ] || \
+ [ "$lan_dhcp" = 1 ]; then
+ splash_net_add ${netrenamed}ahdhcp
uci_commitverbose "Setup dhcpsplash for ${netrenamed}ahdhcp" luci_splash
fi
/etc/init.d/luci_splash enable
diff --git a/contrib/package/meshwizard/files/usr/bin/meshwizard/wizard.sh b/contrib/package/meshwizard/files/usr/bin/meshwizard/wizard.sh
index b666313e46..372148997c 100755
--- a/contrib/package/meshwizard/files/usr/bin/meshwizard/wizard.sh
+++ b/contrib/package/meshwizard/files/usr/bin/meshwizard/wizard.sh
@@ -10,7 +10,7 @@
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
echo "
-/* Meshwizard 0.3.0 */
+/* Meshwizard 0.3.1 */
"
# config
@@ -34,6 +34,8 @@ cleanup=$(uci -q get meshwizard.general.cleanup)
# Rename wifi interfaces
$dir/helpers/rename-wifi.sh
+export lan_is_olsr="$(uci -q get meshwizard.netconfig.lan_config)"
+
# Get community
community="$(uci -q get meshwizard.community.name || uci -q get freifunk.community.name)"
[ -z "$community" ] && echo "Error: Community is not set in /etc/config/freifunk, aborting now." && exit 1
@@ -114,6 +116,13 @@ for net in $networks; do
$dir/helpers/setup_olsrd_interface.sh $net
net_dhcp=$(uci -q get meshwizard.netconfig.${net}_dhcp)
+ export ${net}_dhcp=$net_dhcp
+
+ if [ "$net" = "lan" ] && [ "$lan_is_olsr" = "1" ]; then
+ uci -q set dhcp.lan.ignore="1"
+ uci_commitverbose "Disable DHCP on LAN because it is an olsr interface." dhcp
+ fi
+
if [ "$net_dhcp" == 1 ]; then
$dir/helpers/setup_dhcp.sh $net
fi
diff --git a/documentation/CBI.md b/documentation/CBI.md
new file mode 100644
index 0000000000..0b47c2248b
--- /dev/null
+++ b/documentation/CBI.md
@@ -0,0 +1,248 @@
+CBI models are Lua files describing the structure of an UCI config file and the resulting HTML form to be evaluated by the CBI parser.
+All CBI model files must return an object of type *luci.cbi.Map*. For a commented example of a CBI model, see the [[Documentation/ModulesHowTo#CBImodels|Writing Modules tutorial]].
+
+The scope of a CBI model file is automatically extended by the contents of the module *luci.cbi_' and the '_translate* function from luci.i18n
+
+This Reference covers *the basics* of the CBI system.
+
+
+
+# class Map (_config'', ''title'', ''description_)
+This is the root object of the model.
+* *config*: configuration name to be mapped, see uci documentation and the files in /etc/config
+* *title*: title shown in the UI
+* *description*: description shown in the UI
+
+## :section (_sectionclass_, ...)
+Creates a new section
+* *sectionclass*: a class object of the section
+* _additional parameters passed to the constructor of the section class_
+
+----
+
+# class NamedSection (_name'', ''type'', ''title'', ''description_)
+An object describing an UCI section selected by the name.
+Use [[#A.3Asection.28.27.27sectionclass.27.27.2C....29|Map:section(NamedSection, _name'', ''type'', ''title'', ''description_)]] to instantiate.
+* *name*: section name
+* *type*: section type
+* *title*: The title shown in the UI
+* *description*: description shown in the UI
+
+## .addremove = false
+Allows the user to remove and recreate the configuration section
+
+## .dynamic = false
+Marks this section as dynamic. Dynamic sections can contain an undefinded number of completely userdefined options.
+
+## .optional = true
+Parse optional options
+
+
+## :option (_optionclass_, ...)
+Creates a new option
+* *optionclass*: a class object of the section
+* _additional parameters passed to the constructor of the option class_
+
+----
+
+# class TypedSection (_type'', ''title'', ''description_)
+An object describing a group of UCI sections selected by their type.
+Use [[#A.3Asection.28.27.27sectionclass.27.27.2C....29|Map:section(TypedSection, _type'', ''title'', ''description_)]] to instantiate.
+* *type*: section type
+* *title*: The title shown in the UI
+* *description*: description shown in the UI
+
+## .addremove = false
+Allows the user to remove and recreate the configuration section
+
+## .dynamic = false
+Marks this section as dynamic. Dynamic sections can contain an undefinded number of completely userdefined options.
+
+## .optional = true
+Parse optional options
+
+## .anonymous = false
+Do not show section names
+
+
+## :depends (_key'', ''value_)
+Only select those sections where the option _key'' == ''value_<br />
+If you call this function several times the dependencies will be linked with *or*
+
+## .filter (_self'', ''section_) [abstract]
+You can override this function to filter certain sections that will not be parsed.
+The filter function will be called for every section that should be parsed and returns *nil* for sections that should be filtered. For all other sections it should return the section name as given in the second parameter.
+
+## :option (_optionclass_, ...)
+Creates a new option
+ _optionclass_: a class object of the section
+ additional parameters passed to the constructor of the option class
+
+----
+
+# class Value (_option'', ''title'', ''description_)
+An object describing an option in a section of a UCI File. Creates a standard text field in the formular.
+Use [[#A.3Aoption.28.27.27optionclass.27.27.2C....29|NamedSection:option(Value, _option'', ''title'', ''description'')]] or [[#A.3Aoption.28.27.27optionclass.27.27.2C....29-1|TypedSection:option(Value, ''option'', ''title'', ''description_)]] to instantiate.
+* *option*: section name
+* *title*: The title shown in the UI
+* *description*: description shown in the UI
+
+## .default = nil
+The default value
+
+## .maxlength = nil
+The maximum length of the value
+
+## .optional = false
+Marks this option as optional, implies .rmempty = true
+
+## .rmempty = true
+Removes this option from the configuration file when the user enters an empty value
+
+## .size = nil
+The size of the form field
+
+## :value (_key'', ''value'' = ''key_)
+Convert this text field into a combobox if possible and add a selection option.
+
+
+## :depends (_key'', ''value_)
+Only show this option field if another option _key'' is set to ''value_ in the same section.<br />
+If you call this function several times the dependencies will be linked with *or*
+
+----
+
+# class ListValue (_option'', ''title'', ''description_)
+An object describing an option in a section of a UCI File. Creates a list box in the formular.
+Use [[#A.3Aoption.28.27.27optionclass.27.27.2C....29|NamedSection:option(Value, _option'', ''title'', ''description'')]] or [[#A.3Aoption.28.27.27optionclass.27.27.2C....29-1|TypedSection:option(Value, ''option'', ''title'', ''description_)]] to instantiate.
+* *option*: section name
+* *title*: The title shown in the UI
+* *description*: description shown in the UI
+
+
+## .default = nil
+The default value
+
+## .optional = false
+Marks this option as optional, implies .rmempty = true
+
+## .rmempty = true
+Removes this option from the configuration file when the user enters an empty value
+
+## .size = nil
+The size of the form field
+
+## .widget = "select"
+selects the form widget to be used
+
+
+## :depends (_key'', ''value_)
+Only show this option field if another option _key'' is set to ''value_ in the same section.<br />
+If you call this function several times the dependencies will be linked with *or*
+
+## :value (_key'', ''value'' = ''key_)
+Adds an entry to the selection list
+
+----
+
+# class Flag (_option'', ''title'', ''description_)
+An object describing an option with two possible values in a section of a UCI File. Creates a checkbox field in the formular.
+Use [[#A.3Aoption.28.27.27optionclass.27.27.2C....29|NamedSection:option(Value, _option'', ''title'', ''description'')]] or [[#A.3Aoption.28.27.27optionclass.27.27.2C....29-1|TypedSection:option(Value, ''option'', ''title'', ''description_)]] to instantiate.
+* *option*: section name
+* *title*: The title shown in the UI
+* *description*: description shown in the UI
+
+## .default = nil
+The default value
+
+## .disabled = 0
+the value that shoudl be set if the checkbox is unchecked
+
+## .enabled = 1
+the value that should be set if the checkbox is checked
+
+## .optional = false
+Marks this option as optional, implies .rmempty = true
+
+## .rmempty = true
+Removes this option from the configuration file when the user enters an empty value
+
+## .size = nil
+The size of the form field
+
+
+## :depends (_key'', ''value_)
+Only show this option field if another option _key'' is set to ''value_ in the same section.<br />
+If you call this function several times the dependencies will be linked with *or*
+
+----
+
+# class MultiValue (_option'', ''title'', ''description_)
+An object describing an option in a section of a UCI File. Creates several checkboxed as form fields.
+Use [[#A.3Aoption.28.27.27optionclass.27.27.2C....29|NamedSection:option(Value, _option'', ''title'', ''description'')]] or [[#A.3Aoption.28.27.27optionclass.27.27.2C....29-1|TypedSection:option(Value, ''option'', ''title'', ''description_)]] to instantiate.
+* *option*: section name
+* *title*: The title shown in the UI
+* *description*: description shown in the UI
+
+
+## .default = nil
+The default value
+
+## .delimiter = " "
+The string which will be used to delimit the values
+
+## .optional = false
+Marks this option as optional, implies .rmempty = true
+
+## .rmempty = true
+Removes this option from the configuration file when the user enters an empty value
+
+## .size = nil
+The size of the form field
+
+## .widget = "checkbox"
+selects the form widget to be used
+
+
+## :depends (_key'', ''value_)
+Only show this option field if another option _key'' is set to ''value_ in the same section.<br />
+If you call this function several times the dependencies will be linked with *or*
+
+## :value (_key'', ''value'' = ''key_)
+Adds an entry to the checkbox list
+
+----
+
+# class DummyValue (_option'', ''title'', ''description_)
+An object describing an option in a section of a UCI File. Creates a readonly field in the form.
+Use [[#A.3Aoption.28.27.27optionclass.27.27.2C....29|NamedSection:option(Value, _option'', ''title'', ''description'')]] or [[#A.3Aoption.28.27.27optionclass.27.27.2C....29-1|TypedSection:option(Value, ''option'', ''title'', ''description_)]] to instantiate.
+* *option*: section name
+* *title*: The title shown in the UI
+* *description*: description shown in the UI
+
+
+
+## :depends (_key'', ''value_)
+Only show this option field if another option _key'' is set to ''value_ in the same section.<br />
+If you call this function several times the dependencies will be linked with *or*
+
+----
+
+
+# class TextValue (_option'', ''title'', ''description_)
+An object describing a multi-line textbox in a section in a non-UCI form.
+
+----
+
+# class Button (_option'', ''title'', ''description_)
+An object describing a Button in a section in a non-UCI form.
+
+----
+
+# class StaticList (_option'', ''title'', ''description_)
+Similar to the MultiValue, but stores selected Values into a UCI list instead of a space-separated string.
+
+----
+
+# class DynamicList (_option'', ''title'', ''description_)
+A list of user-defined values.
diff --git a/documentation/JsonRpcHowTo.md b/documentation/JsonRpcHowTo.md
new file mode 100644
index 0000000000..76d61f86e3
--- /dev/null
+++ b/documentation/JsonRpcHowTo.md
@@ -0,0 +1,66 @@
+LuCI provides some of its libraries to external applications through a JSON-RPC API.
+This Howto shows how to use it and provides information about available functions.
+
+
+# Basics
+LuCI comes with an efficient JSON De-/Encoder together with a JSON-RPC-Server which implements the *JSON-RPC 1.0_' and 2.0 (partly) specifications. The LuCI JSON-RPC server offers several independent APIs. Therefore you have to use '_different URLs for every exported library*.
+Assuming your LuCI-Installation can be reached through */cgi-bin/luci_' any exported library can be reached via '''/cgi-bin/luci/rpc/''LIBRARY_*.
+
+
+# Authentication
+Most exported libraries will require a valid authentication to be called with. If you get an *HTTP 403 Forbidden_' status code you are probably missing a valid authentication token. To get such a token you have to call the function '''login''' of the RPC-Library '''auth'''. Following our example from above this login function would be provided at '_/cgi-bin/luci/rpc/auth*. The function accepts 2 parameters: username and password (of a valid user account on the host system) and returns an authentication token.
+
+If you want to call any exported library which requires an authentication token you have to *append it as an URL parameter _auth''''' to the RPC-Server URL. So instead of calling '''/cgi-bin/luci/rpc/''LIBRARY''''' you have to call '''/cgi-bin/luci/rpc/''LIBRARY''?auth=''TOKEN_*.
+
+If your JSON-RPC client is Cookie-aware (like most browsers are) you will receive the authentication token also with a session cookie and probably don't have to append it to the RPC-Server URL.
+
+
+# Exported Libraries
+## uci
+The UCI-Library */rpc/uci* offers functionality to interact with the Universal Configuration Interface.
+*Exported Functions:*
+* [(string) add(config, type)](http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.add)
+* [(integer) apply(config)](http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.apply)
+* [http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.changes (object) changes([config])]
+* [(boolean) commit(config)](http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.commit)
+* [http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.delete (boolean) delete(config, section[, option])]
+* [http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.delete_all (boolean) delete_all(config[, type])]
+* [http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.foreach (array) foreach(config[, type])]
+* [http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.get (mixed) get(config, section[, option])]
+* [http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.get_all (object) get_all(config[, section])]
+* [http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.get (mixed) get_state(config, section[, option])]
+* [(boolean) revert(config)](http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.revert)
+* [(name) section(config, type, name, values)](http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.section)
+* [(boolean) set(config, section, option, value)](http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.set)
+* [(boolean) tset(config, section, values)](http://luci.subsignal.org/api/luci/modules/luci.model.uci.html#Cursor.tset)
+
+## uvl
+The UVL-Library */rpc/uvl* offers functionality to validate UCI files and get schemes describing UCI files.
+*Exported Functions:*
+* [(array) get_scheme(scheme)](http://luci.subsignal.org/api/luci/modules/luci.uvl.html#UVL.get_scheme)
+* [(array) validate(config, section, option)](http://luci.subsignal.org/api/luci/modules/luci.uvl.html#UVL.validate)
+* [(array) validate_config(config)](http://luci.subsignal.org/api/luci/modules/luci.uvl.html#UVL.validate_config)
+* [(array) validate_section(config, section)](http://luci.subsignal.org/api/luci/modules/luci.uvl.html#UVL.validate_section)
+* [(array) validate(config, section, option)](http://luci.subsignal.org/api/luci/modules/luci.uvl.html#UVL.validate_option)
+
+## fs
+The Filesystem library */rpc/fs* offers functionality to interact with the filesystem on the host machine.
+*Exported Functions:*
+
+* [Complete luci.fs library](http://luci.subsignal.org/api/luci/modules/luci.fs.html)
+*Note:* All functions are exported as they are except for _readfile'' which encodes its return value in base64 and ''writefile'' which only accepts base64 encoded data as second argument. Note that both functions will only be available when the ''luasocket_ packet is installed on the hostsystem.
+
+## sys
+The System library */rpc/sys* offers functionality to interact with the operating system on the host machine.
+*Exported Functions:*
+* [Complete luci.sys library](http://luci.subsignal.org/api/luci/modules/luci.sys.html)
+* [Complete luci.sys.group library](http://luci.subsignal.org/api/luci/modules/luci.sys.group.html) with prefix *group.*
+* [Complete luci.sys.net library](http://luci.subsignal.org/api/luci/modules/luci.sys.net.html) with prefix *net.*
+* [Complete luci.sys.process library](http://luci.subsignal.org/api/luci/modules/luci.sys.process.html) with prefix *process.*
+* [Complete luci.sys.user library](http://luci.subsignal.org/api/luci/modules/luci.sys.user.html) with prefix *user.*
+* [Complete luci.sys.wifi library](http://luci.subsignal.org/api/luci/modules/luci.sys.wifi.html) with prefix *wifi.*
+
+## ipkg
+The IPKG library */rpc/ipkg* offers functionality to interact with the package manager (IPKG or OPKG) on the host machine.
+*Exported Functions:*
+* [Complete luci.model.ipkg library](http://luci.subsignal.org/api/luci/modules/luci.model.ipkg.html)
diff --git a/documentation/LAR.md b/documentation/LAR.md
new file mode 100644
index 0000000000..f44d8dc7df
--- /dev/null
+++ b/documentation/LAR.md
@@ -0,0 +1,87 @@
+LAR is a simple archive format to pack multiple lua source files and arbitary other resources into a single file.
+
+
+# Format Specification
+
+A LAR archive file is divided into two parts: the payload and the index lookup table.
+All segments of the archive are 4 Byte aligned to ease reading and processing of the format.
+All integers are stored in network byte order, so an implementation has to use htonl() and htons() to properly read them.
+
+Schema:
+
+ <payload:
+ <member:
+ <N*4 bytes: path of file #1>
+ <N*4 bytes: data of file #1>
+ >
+
+ <member:
+ <N*4 bytes: path of file #2>
+ <N*4 bytes: data of file #2>
+ >
+
+ ...
+
+ <member:
+ <N*4 bytes: path of file #N>
+ <N*4 bytes: data of file #N>
+ >
+ >
+
+ <index table:
+ <entry:
+ <uint32: offset for path of file #1> <uint32: length for path of file #1>
+ <uint32: offset for data of file #1> <uint32: length for data of file #1>
+ <uint16: type of file #1> <uint16: flags of file #1>
+ >
+
+ <entry:
+ <uint32: offset for path of file #2> <uint32: length for path of file #2>
+ <uint32: offset for data of file #2> <uint32: length for data of file #2>
+ <uint16: type of file #2> <uint16: flags of file #2>
+ >
+
+ ...
+
+ <entry:
+ <uint32: offset for path of file #N> <uint32: length for path of file #N>
+ <uint32: offset for data of file #N> <uint32: length for data of file #N>
+ <uint16: type of file #N> <uint16: flags of file #N>
+ >
+ >
+
+ <uint32: offset for begin of index table>
+
+
+
+# Processing
+
+In order to process an LAR archive, an implementation would have to do the following steps:
+
+## Read Index
+
+1. Locate and open the archive file
+1. Seek to end of file - 4 bytes
+1. Read 32bit index offset and swap from network to native byte order
+1. Seek to index offset, calculate index length: filesize - index offset - 4
+1. Initialize a linked list for index table entries
+1. Read each index entry until the index length is reached, read and byteswap 4 * 32bit int and 2 * 16bit int
+1. Seek to begin of file
+
+## Read Member
+
+1. Read the archive index
+1. Iterate through the linked index list, perform the following steps for each entry
+1. Seek to the specified file path offset
+1. Read as much bytes as specified in the file path length into a buffer
+1. Compare the contents of the buffer against the path of the searched member
+1. If buffer and searched path are equal, seek to the specified file data offset
+1. Read data until the file data length is reached, return
+1. Select the next index table entry and repeat from step 3, if there is no next entry then return
+
+# Reference implementation
+
+A reference implementation can be found here:
+http://luci.subsignal.org/trac/browser/luci/trunk/contrib/lar
+
+The lar.pl script is a simple packer for LAR archives and cli.c provides a utility to list and dump packed LAR archives.
diff --git a/documentation/LMO.md b/documentation/LMO.md
new file mode 100644
index 0000000000..961a45ba84
--- /dev/null
+++ b/documentation/LMO.md
@@ -0,0 +1,144 @@
+LMO is a simple binary format to pack language strings into a more efficient form. Although it's suitable to store any kind of key-value table, it's only used for the LuCI *.po based translation system at the moment. The abbreviation "LMO" stands for "Lua Machine Objects" in the style of the GNU gettext *.mo format.
+
+
+# Format Specification
+
+A LMO file is divided into two parts: the payload and the index lookup table.
+All segments of the file are 4 Byte aligned to ease reading and processing of the format.
+Only unsigned 32bit integers are used and stored in network byte order, so an implementation has to use htonl() to properly read them.
+
+Schema:
+
+ <file:
+ <payload:
+ <entry #1: 4 byte aligned data>
+
+ <entry #2: 4 byte aligned data>
+
+ ...
+
+ <entry #N: 4 byte aligned data>
+ >
+
+ <index table:
+ <entry #1:
+ <uint32_t: hash of the first key>
+ <uint32_t: hash of the first value>
+ <uint32_t: file offset of the first value>
+ <uint32_t: length of the first value>
+ >
+
+ <entry #2:
+ <uint32_t: hash of the second key>
+ <uint32_t: hash of the second value>
+ <uint32_t: file offset of the second value>
+ <uint32_t: length of the second value>
+ >
+
+ ...
+
+ <entry #N:
+ <uint32_t: hash of the Nth key>
+ <uint32_t: hash of the Nth value>
+ <uint32_t: file offset of the Nth value>
+ <uint32_t: length of the Nth value>
+ >
+ >
+
+ <uint32_t: offset of the begin of index table>
+ >
+
+
+
+# Processing
+
+In order to process a LMO file, an implementation would have to do the following steps:
+
+## Read Index
+
+1. Locate and open the archive file
+1. Seek to end of file - 4 bytes (sizeof(uint32_t))
+1. Read 32bit index offset and swap from network to native byte order
+1. Seek to index offset, calculate index length: filesize - index offset - 4
+1. Initialize a linked list for index table entries
+1. Read each index entry until the index length is reached, read and byteswap 4 * uint32_t for each step
+1. Seek to begin of file
+
+## Read Entry
+
+1. Calculate the unsigned 32bit hash of the entries key value (see "Hash Function" section below)
+1. Obtain the archive index
+1. Iterate through the linked index list, perform the following steps for each entry:
+ 1. Compare the entry hash value with the calculated hash from step 1
+ 2. If the hash values are equal proceed with step 4
+ 3. Select the next entry and repeat from step 3.1
+1. Seek to the file offset specified in the selected entry
+1. Read as much bytes as specified in the entry length into a buffer
+1. Return the buffer value
+
+# Hash Function
+
+The current LuCI-LMO implementation uses the "Super Fast Hash" function which was kindly put in the public domain by it's original author. See http://www.azillionmonkeys.com/qed/hash.html for details. Below is the C-Implementation of this function:
+
+
+ #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
+
+ uint32_t sfh_hash(const char * data, int len)
+ {
+ uint32_t hash = len, tmp;
+ int rem;
+
+ if (len <= 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;
+ }
+
+
+# Reference Implementation
+
+A reference implementation can be found here:
+http://luci.subsignal.org/trac/browser/luci/trunk/libs/lmo/src
+
+The lmo_po2lmo.c executable implements a *.po to *.lmo conversation utility and lmo_lookup.c is a simple *.lmo test utility.
+Lua bindings for lmo are defined in lmo_lualib.c and associated headers.
diff --git a/documentation/LuCI-0.10.md b/documentation/LuCI-0.10.md
new file mode 100644
index 0000000000..5db9895e58
--- /dev/null
+++ b/documentation/LuCI-0.10.md
@@ -0,0 +1,202 @@
+[[PageOutline(2-5, Table of Contents, floated)]]
+
+
+This document describes new features and incompatibilities to LuCI 0.9.x.
+It is targeted at module authors developing external addons to LuCI.
+
+# I18N Changes
+
+## API
+
+The call conventions for the i18n api changed, there is no dedicated translation
+key anymore and the english text is used for lookup instead. This was done to
+ease the maintenance of language files.
+
+Code that uses _translate()'' or ''i18n()_ must be changed as follows:
+
+
+ -- old style:
+ translate("some_text", "Some Text")
+ translatef("some_format_text", "Some formatted Text: %d", 123)
+
+ -- new style:
+ translate("Some Text")
+ translatef("Some formatted Text: %d", 123)
+
+
+Likewise for templates:
+
+
+ <!-- old style: -->
+ <%:some_text Some Text%>
+
+ <!-- new style: -->
+ <%:Some Text%>
+
+
+If code must support both LuCI 0.9.x and 0.10.x versions, it is suggested to write the calls as follows:
+
+ translate("Some Text", "Some Text")
+
+
+An alternative is wrapping translate() calls into a helper function:
+
+ function tr(key, alt)
+ return translate(key) or translate(alt) or alt
+ end
+
+
+... which is used as follows:
+
+ tr("some_key", "Some Text")
+
+
+## Translation File Format
+
+Translation catalogs are now maintained in *.po format files. During build those get translated
+into [*.lmo archives](http://luci.subsignal.org/trac/wiki/Documentation/LMO).
+
+LuCI ships a [utility script](http://luci.subsignal.org/trac/browser/luci/branches/luci-0.10/build/i18n-lua2po.pl)
+in the build/ directory to convert old Lua translation files to the *.po format. The generated *.po files should
+be placed in the appropriate subdirectories within the top po/ file in the LuCI source tree.
+
+### Components built within the LuCI tree
+
+If components using translations are built along with the LuCI tree, the newly added *.po file are automatically
+compiled into *.lmo archives during the build process. In order to bundle the appropriate *.lmo files into the
+corresponding *.ipk packages, component Makefiles must include a "PO" variable specifying the files to include.
+
+Given a module _applications/example/'' which uses ''po/en/example.po'' and ''po/en/example-extra.po_,
+the _applications/example/Makefile_ must be changed as follows:
+
+
+ PO = example example-extra
+
+ include ../../build/config.mk
+ include ../../build/module.mk
+
+
+### Standalone components
+
+Authors who externally package LuCI components must prepare required *.lmo archives themselves.
+To convert existing Lua based message catalogs to the *.po format, the build/i18n-lua2po.pl helper script can be used.
+In order to convert *.po files into *.lmo files, the standalone "po2lmo" utility must be compiled as follows:
+
+
+ $ svn co http://svn.luci.subsignal.org/luci/branches/luci-0.10/libs/lmo
+ $ cd lmo/
+ $ make
+ $ ./src/po2lmo translations.po translations.lmo
+
+
+Note that at the time of writing, the utility program needs Lua headers installed on the system in order to compile properly.
+
+# CBI
+
+## Datatypes
+
+The server side UVL validation has been dropped to reduce space requirements on the target.
+Instead it is possible to define datatypes for CBI widgets now:
+
+
+ opt = section:option(Value, "optname", "Title Text")
+ opt.datatype = "ip4addr"
+
+
+User provided data is validated once on the frontend via JavaScript and on the server side prior to saving it.
+A list of possible datatypes can be found in the [luci.cbi.datatypes](http://luci.subsignal.org/trac/browser/luci/branches/luci-0.10/libs/web/luasrc/cbi/datatypes.lua#L26) class.
+
+## Validation
+
+Server-sided validator function can now return custom error messages to provide better feedback on invalid input.
+
+
+ opt = section:option(Value, "optname", "Title Text")
+
+ function opt.validate(self, value, section)
+ if input_is_valid(value) then
+ return value
+ else
+ return nil, "The value is invalid because ..."
+ end
+ end
+
+
+## Tabs
+
+It is now possible to break up CBI sections into multiple tabs to better organize longer forms.
+The TypedSection and NamedSection classes gained two new functions to define tabs, _tab()'' and ''taboption()_.
+
+
+ sct = map:section(TypedSection, "name", "type", "Title Text")
+
+ sct:tab("general", "General Tab Title", "General Tab Description")
+ sct:tab("advanced", "Advanced Tab Title", "Advanced Tab Description")
+
+ opt = sct:taboption("general", Value, "optname", "Title Text")
+ ...
+
+
+The _tab()_ function is declares a new tab and takes up to three arguments:
+ * Internal name of the tab, must be unique within the section
+ * Title text of the tab
+ * Optional description text for the tab
+
+The _taboption()'' function wraps ''option()_ and assigns the option object to the given tab.
+It takes up to five arguments:
+
+ * Name of the tab to assign the option to
+ * Option type, e.g. Value or DynamicList
+ * Option name
+ * Title text of the option
+ * Optional description text of the option
+
+If tabs are used within a particular section, the _option()_ function must not be used,
+doing so results in undefined behaviour.
+
+## Hooks
+
+The CBI gained support for _hooks_ which can be used to trigger additional actions during the
+life-cycle of a map:
+
+
+ map = Map("config", "Title Text")
+
+ function map.on_commit(self)
+ -- do something if the UCI configuration got committed
+ end
+
+
+The following hooks are defined:
+
+|| on_cancel || The user pressed cancel within a multi-step Delegator or a SimpleForm instance ||
+|| on_init || The CBI is about to render the Map object ||
+|| on_parse || The CBI is about to read received HTTP form values ||
+|| on_save, on_before_save || The CBI is about to save modified UCI configuration files ||
+|| on_after_save || Modified UCI configuration files just got saved
+|| on_before_commit || The CBI is about to commit the changes ||
+|| on_commit, on_after_commit, on_before_apply || Modified configurations got committed and the CBI is about to restart associated services ||
+|| on_apply, on_after_apply || All changes where completely applied (only works on Map instances with the apply_on_parse attribute set) ||
+
+## Sortable Tables
+
+TypedSection instances which use the "cbi/tblsection" template may now use a new attribute _sortable_ to allow the user to reorder table rows.
+
+
+ sct = map:section(TypedSection, "name", "type", "Title Text")
+ sct.template = "cbi/tblsection"
+ sct.sortable = true
+
+ ...
+
+
+# JavaScript
+
+The LuCI 0.10 branch introduced a new JavaScript file _xhr.js_ which provides support routines for XMLHttpRequest operations.
+Each theme must include this file in the <head> area of the document for forms to work correctly.
+
+It should be included like this:
+
+
+ <script type="text/javascript" src="<%=resource%>/xhr.js"></script>
+ \ No newline at end of file
diff --git a/documentation/Modules.md b/documentation/Modules.md
new file mode 100644
index 0000000000..2897df9488
--- /dev/null
+++ b/documentation/Modules.md
@@ -0,0 +1,94 @@
+# Categories
+
+The LuCI modules are divided into several category directories, namely:
+* applications (Single applications or plugins for other modules or applications)
+* i18n (Translation files)
+* libs (Independent libraries)
+* modules (Collections of applications)
+* themes (Frontend themes)
+
+Each module goes into a subdirectory of any of this category-directories.
+
+# Module directory
+The contents of a module directory are as follows:
+
+## Makefile
+This is the module's makefile. If the module just contains Lua sourcecode or resources then the following Makefile should suffice.
+
+ include ../../build/config.mk
+ include ../../build/module.mk
+
+
+If you have C(++) code in your module your Makefile should at least contain the following things.
+
+ include ../../build/config.mk
+ include ../../build/gccconfig.mk
+ include ../../build/module.mk
+
+ compile:
+ # Commands to compile and link your C-code
+ # and to install them under the dist/ hierarchy
+
+ clean: luaclean
+ # Commands to clean your compiled objects
+
+
+
+## src
+The *src* directory is reserved for C sourcecode.
+
+## luasrc
+*luasrc* contains all Lua sourcecode files. These will automatically be stripped or compiled depending on the Make target and are installed in the LuCI installation directory.
+
+## lua
+*lua* is equivalent to _luasrc_ but containing Lua files will be installed in the Lua document root.
+
+## htdocs
+All files under *htdocs* will be copied to the document root of the target webserver.
+
+## root
+All directories and files under *root* will be copied to the installation target as they are.
+
+## dist
+*dist* is reserved for the builder to create a working installation tree that will represent the filesystem on the target machine.
+*DO NOT* put any files there as they will get deleted.
+
+## ipkg
+*ipkg* contains IPKG package control files, like _preinst'', ''posinst'', ''prerm'', ''postrm''. ''conffiles_.
+See IPKG documentation for details.
+
+
+# OpenWRT feed integration
+If you want to add your module to the LuCI OpenWRT feed you have to add several sections to the contrib/package/luci/Makefile.
+
+For a Web UI applications this is:
+
+A package description:
+
+ define Package/luci-app-YOURMODULE
+ $(call Package/luci/webtemplate)
+ DEPENDS+=+some-package +some-other-package
+ TITLE:=SHORT DESCRIPTION OF YOURMODULE
+ endef
+
+
+
+A package installation target:
+
+ define Package/luci-app-YOURMODULE/install
+ $(call Package/luci/install/template,$(1),applications/YOURMODULE)
+ endef
+
+
+A module build instruction:
+
+ ifneq ($(CONFIG_PACKAGE_luci-app-YOURMODULE),)
+ PKG_SELECTED_MODULES+=applications/YOURMODULE
+ endif
+
+
+
+A build package call:
+
+ $(eval $(call BuildPackage,luci-app-YOURMODULE))
+
diff --git a/documentation/ModulesHowTo.md b/documentation/ModulesHowTo.md
new file mode 100644
index 0000000000..3f70b788c5
--- /dev/null
+++ b/documentation/ModulesHowTo.md
@@ -0,0 +1,153 @@
+*Note:* If you plan to integrate your module into LuCI, you should read the [wiki:Documentation/Modules Module Reference] before.
+
+This tutorial describes how to write your own modules for the LuCI WebUI.
+For this tutorial we refer to your LuCI installation direcotry as *lucidir_' (/usr/lib/lua/luci if you are working with an installed version) and assume your LuCI installation is reachable through your webserver via '_/cgi-bin/luci*.
+
+If you are working with the development environment replace *lucidir_' with '''''/path/to/your/luci/checkout''/applications/myapplication/luasrc''' (this is a default empty module you can use for your experiments) and your LuCI installation can probably be reached via http://localhost:8080/luci/ after you ran '_make runhttpd*.
+
+
+
+# Show me the way (The dispatching process)
+To write a module you need to understand the basics of the dispatching process in LuCI.
+LuCI uses a dispatching tree that will be built by executing the index-Function of every available controller.
+The CGI-environment variable *PATH_INFO* will be used as the path in this dispatching tree, e.g.: /cgi-bin/luci/foo/bar/baz
+will be resolved to foo.bar.baz
+
+To register a function in the dispatching tree, you can use the *entry*-function of _luci.dispatcher_. entry takes 4 arguments (2 are optional):
+
+ entry(path, target, title=nil, order=nil)
+
+
+* *path* is a table that describes the position in the dispatching tree: For example a path of {"foo", "bar", "baz"} would insert your node in foo.bar.baz.
+* *target* describes the action that will be taken when a user requests the node. There are several predefined ones of which the 3 most important (call, template, cbi) are described later on on this page
+* *title* defines the title that will be visible to the user in the menu (optional)
+* *order* is a number with which nodes on the same level will be sorted in the menu (optional)
+
+You can assign more attributes by manipulating the node table returned by the entry-function. A few example attributes:
+
+* *i18n* defines which translation file should be automatically loaded when the page gets requested
+* *dependent* protects plugins to be called out of their context if a parent node is missing
+* *leaf* stops parsing the request at this node and goes no further in the dispatching tree
+* *sysauth* requires the user to authenticate with a given system user account
+
+
+# It's all about names (Naming and the module file)
+Now that you know the basics about dispatching, we can start writing modules. But before you have to choose the category and name of your new digital child.
+
+We assume you want to create a new application "myapp" with a module "mymodule".
+
+So you have to create a new subdirectory *_lucidir''/controller/myapp''' with a file '_mymodule.lua* with the following content:
+
+ module("luci.controller.myapp.mymodule", package.seeall)
+
+ function index()
+
+ end
+
+
+The first line is required for Lua to correctly identify the module and create its scope.
+The index-Function will be used to register actions in the dispatching tree.
+
+
+
+# Teaching your new child (Actions)
+So it is there and has a name but it has no actions.
+
+We assume you want to reuse your module myapp.mymodule that you begun in the last step.
+
+
+## Actions
+Reopen *_lucidir_/controller/myapp/mymodule.lua* and just add a function to it so that its content looks like this example:
+
+
+ module("luci.controller.myapp.mymodule", package.seeall)
+
+ function index()
+ entry({"click", "here", "now"}, call("action_tryme"), "Click here", 10).dependent=false
+ end
+
+ function action_tryme()
+ luci.http.prepare_content("text/plain")
+ luci.http.write("Haha, rebooting now...")
+ luci.sys.reboot()
+ end
+
+
+And now type */cgi-bin/luci/click/here/now_' ('_[http://localhost:8080/luci/click/here/now]* if you are using the development environment) in your browser.
+
+You see these action functions simple have to be added to a dispatching entry.
+
+As you might or might not know: CGI specification requires you to send a Content-Type header before you can send your content. You will find several shortcuts (like the one used above) as well as redirecting functions in the module *luci.http*
+
+## Views
+If you only want to show the user a text or some interesting familiy photos it may be enough to use a HTML-template. These templates can also include some Lua code but be aware that writing whole office suites by only using these templates might be called "dirty" by other developers.
+
+Now let's create a little template *_lucidir_/view/myapp-mymodule/helloworld.htm* with the content:
+
+
+ <%+header%>
+ <h1><%:Hello World%></h1>
+ <%+footer%>
+
+
+
+and add the following line to the index-Function of your module file.
+
+ entry({"my", "new", "template"}, template("myapp-mymodule/helloworld"), "Hello world", 20).dependent=false
+
+
+Now type */cgi-bin/luci/my/new/template_' ('_[http://localhost:8080/luci/my/new/template]* if you are using the development environment) in your browser.
+
+You may notice those fancy <% %>-Tags, these are [wiki:Documentation/Templates|template markups] used by the LuCI template processor.
+It is always good to include header and footer at the beginning and end of a template as those create the default design and menu.
+
+## CBI models
+The CBI is one of the uber coolest features of LuCI. It creates a formular based user interface and saves its contents to a specific UCI config file. You only have to describe the structure of the configuration file in a CBI model file and Luci does the rest of the work. This includes generating, parsing and validating a XHTML form and reading and writing the UCI file.
+
+So let's be serious at least for this paragraph and create a real pratical example *_lucidir_/model/cbi/myapp-mymodule/netifaces.lua* with the following contents:
+
+
+ m = Map("network", "Network") -- We want to edit the uci config file /etc/config/network
+
+ s = m:section(TypedSection, "interface", "Interfaces") -- Especially the "interface"-sections
+ s.addremove = true -- Allow the user to create and remove the interfaces
+ function s:filter(value)
+ return value ~= "loopback" and value -- Don't touch loopback
+ end
+ s:depends("proto", "static") -- Only show those with "static"
+ s:depends("proto", "dhcp") -- or "dhcp" as protocol and leave PPPoE and PPTP alone
+
+ p = s:option(ListValue, "proto", "Protocol") -- Creates an element list (select box)
+ p:value("static", "static") -- Key and value pairs
+ p:value("dhcp", "DHCP")
+ p.default = "static"
+
+ s:option(Value, "ifname", "interface", "the physical interface to be used") -- This will give a simple textbox
+
+ s:option(Value, "ipaddr", translate("ip", "IP Address")) -- Ja, das ist eine i18n-Funktion ;-)
+
+ s:option(Value, "netmask", "Netmask"):depends("proto", "static") -- You may remember this "depends" function from above
+
+ mtu = s:option(Value, "mtu", "MTU")
+ mtu.optional = true -- This one is very optional
+
+ dns = s:option(Value, "dns", "DNS-Server")
+ dns:depends("proto", "static")
+ dns.optional = true
+ function dns:validate(value) -- Now, that's nifty, eh?
+ return value:match("[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") -- Returns nil if it doesn't match otherwise returns match
+ end
+
+ gw = s:option(Value, "gateway", "Gateway")
+ gw:depends("proto", "static")
+ gw.rmempty = true -- Remove entry if it is empty
+
+ return m -- Returns the map
+
+
+and of course don't forget to add something like this to your module's index-Function.
+
+ entry({"admin", "network", "interfaces"}, cbi("myapp-mymodule/netifaces"), "Network interfaces", 30).dependent=false
+
+
+There are many more features, see [wiki:Documentation/CBI the CBI reference] and the modules shipped with LuCI.
diff --git a/documentation/SubmitPatchesHowTo:.md b/documentation/SubmitPatchesHowTo:.md
new file mode 100644
index 0000000000..cdd15524a5
--- /dev/null
+++ b/documentation/SubmitPatchesHowTo:.md
@@ -0,0 +1,33 @@
+# Checkout svn
+
+ svn co http://svn.luci.subsignal.org/luci/trunk
+
+and change to that directory:
+
+ cd trunk
+
+# Make your changes
+
+Edit the files you want to change. If you add some new files you need to add them to the svn tree:
+
+ svn add <dir/files>
+
+Where <dir/files> are the directories/files you have added. Its possible to specify multiple files/directories here.
+
+# Use svn diff to generate a patch with your changes
+
+To check if your changes look ok first do:
+
+ svn diff <dir/files>
+
+and check the output. Again you can specify multiple dirs/directories here.
+
+If everything looks like expected save the patch:
+
+ svn diff <dir/files> > ./mypatch.patch
+
+
+# Submit patches
+
+Use the [Ticket system](http://luci.subsignal.org/trac/newticket) to submit your patch.
+
diff --git a/documentation/Templates.md b/documentation/Templates.md
new file mode 100644
index 0000000000..dc42c28ab7
--- /dev/null
+++ b/documentation/Templates.md
@@ -0,0 +1,65 @@
+LuCI has a simple regex based template processor which parses HTML-files to Lua functions and allows to store precompiled template files.
+The simplest form of a template is just an ordinary HTML-file. It will be printed out to the user as is.
+
+In LuCI every template is an object with an own scope. It can therefore be instanciated and each instance can has a different scope. As every template processor. LuCI supports several special markups. Those are enclosed in `<% %>`-Tags.
+
+By adding `-` (dash) right after the opening `<%` every whitespace before the markup will be stripped. Adding a `-` right before the closing `%>` will equivalently strip every whitespace behind the markup.
+
+
+# Builtin functions and markups
+## Including Lua code
+*Markup:*
+
+ <% code %>
+
+
+
+## Writing variables and function values
+*Syntax:*
+
+ <% write (value) %>
+
+
+*Short-Markup:*
+
+ <%=value%>
+
+
+## Including templates
+*Syntax:*
+
+ <% include (templatename) %>
+
+
+*Short-Markup:*
+
+ <%+templatename%>
+
+
+
+## Translating
+*Syntax:*
+
+ <%= translate("Text to translate") %>
+
+
+
+*Short-Markup:*
+
+ <%:Text to translate%>
+
+
+
+## Commenting
+*Markup:*
+
+ <%# comment %>
+
+
+# Builtin constants
+| Name | Value |
+---------|---------
+|`REQUEST_URI`|The current URL (without server part)|
+|`controller`|Path to the Luci main dispatcher|
+|`resource`|Path to the resource directory|
+|`media`|Path to the active theme directory|
diff --git a/documentation/ThemesHowTo.md b/documentation/ThemesHowTo.md
new file mode 100644
index 0000000000..32154c724c
--- /dev/null
+++ b/documentation/ThemesHowTo.md
@@ -0,0 +1,76 @@
+# HowTo: Create Themes
+*Note:* You should read the [Module Reference](Modules.md) and the [Template Reference](Templates.md) before.
+
+We assume you want to call your new theme _mytheme_. Make sure you replace this by your module name everytime this is mentionend in this Howto.
+
+
+
+# Creating the structure
+At first create a new theme directory *themes/_mytheme_*.
+
+Create a _Makefile_ inside your theme directory with the following content:
+
+ include ../../build/config.mk
+ include ../../build/module.mk
+
+
+Create the following directory structure inside your theme directory.
+* ipkg
+* htdocs
+ * luci-static
+ * _mytheme_
+* luasrc
+ * view
+ * themes
+ * _mytheme_
+* root
+ * etc
+ * uci-defaults
+
+
+
+# Designing
+Create two LuCI HTML-Templates named _header.htm'' and ''footer.htm'' under *luasrc/view/themes/''mytheme_*.
+The _header.htm'' will be included at the beginning of each rendered page and the ''footer.htm_ at the end.
+So your _header.htm'' will probably contain a DOCTYPE description, headers, the menu and layout of the page and the ''footer.htm_ will close all remaining open tags and may add a footer bar but hey that's your choice you are the designer ;-).
+
+Just make sure your _header.htm_ *begins* with the following lines:
+
+ <%
+ require("luci.http").prepare_content("text/html")
+ -%>
+
+
+This makes sure your content will be sent to the client with the right content type. Of course you can adapt _text/html_ to your needs.
+
+
+Put any stylesheets, Javascripts, images, ... into *htdocs/luci-static/_mytheme_*.
+You should refer to this directory in your header and footer templates as: _<%=media%>''. That means for a stylesheet *htdocs/luci-static/''mytheme_/cascade.css* you would write:
+
+ <link rel="stylesheet" type="text/css" href="<%=media%>/cascade.css" />
+
+
+
+
+# Making the theme selectable
+If you are done with your work there are two last steps to do.
+To make your theme OpenWRT-capable and selectable on the settings page you should now create a file *root/etc/uci-defaults/luci-theme-_mytheme_* with the following contents:
+
+ #!/bin/sh
+ uci batch <<-EOF
+ set luci.themes.MyTheme=/luci-static/mytheme
+ commit luci
+ EOF
+
+
+and another file *ipkg/postinst* with the following content:
+
+ #!/bin/sh
+ [ -n "${IPKG_INSTROOT}" ] || {
+ ( . /etc/uci-defaults/luci-theme-mytheme ) && rm -f /etc/uci-defaults/luci-theme-mytheme
+ }
+
+
+This is some OpenWRT magic to correctly register the template with LuCI when it gets installed.
+
+That's all. Now send your theme to the LuCI developers to get it into the development repository - if you like.
diff --git a/documentation/i18n.md b/documentation/i18n.md
new file mode 100644
index 0000000000..fdacb0853a
--- /dev/null
+++ b/documentation/i18n.md
@@ -0,0 +1,17 @@
+# General
+Translations are saved in the folder po/. You find the reference in po/templates/<package>.pot. The actual translation files can be found at po/<lang>/<package>.po .
+
+In order to use the commands below you need to have the _gettext'' utilities (''msgcat'', ''msgfmt'', ''msgmerge_) installed on your system.
+
+# Rebuild po files
+If you want to rebuild the translations after you made changes to a package this is an easy way:
+
+
+ ./build/i18n-scan.pl applications/[package] > po/templates/[application].pot
+ ./build/i18n-update.pl po [application].po
+
+*Note:* Some packages share translation files, in this case you need to scan through all their folders. The first command from above should then be:
+
+
+ ./build/i18n-scan.pl applications/[package-1] applications/[package-2] applications/[package-n] > po/templates/[application].pot
+
diff --git a/libs/luci-lib-jsonc/src/jsonc.c b/libs/luci-lib-jsonc/src/jsonc.c
index 49cb21f5bc..971fb122f7 100644
--- a/libs/luci-lib-jsonc/src/jsonc.c
+++ b/libs/luci-lib-jsonc/src/jsonc.c
@@ -222,7 +222,7 @@ static int _lua_test_array(lua_State *L, int index)
out:
lua_pop(L, 2);
- return 0;
+ return -1;
}
/* check for holes */
@@ -254,7 +254,7 @@ static struct json_object * _lua_to_json(lua_State *L, int index)
case LUA_TTABLE:
max = _lua_test_array(L, index);
- if (max > 0)
+ if (max >= 0)
{
obj = json_object_new_array();
@@ -286,8 +286,9 @@ static struct json_object * _lua_to_json(lua_State *L, int index)
lua_pushvalue(L, -2);
key = lua_tostring(L, -1);
- json_object_object_add(obj, key,
- _lua_to_json(L, lua_gettop(L) - 1));
+ if (key)
+ json_object_object_add(obj, key,
+ _lua_to_json(L, lua_gettop(L) - 1));
lua_pop(L, 2);
}
diff --git a/libs/luci-lib-nixio/src/address.c b/libs/luci-lib-nixio/src/address.c
index 4fd557d6a7..8ab4fa89c9 100644
--- a/libs/luci-lib-nixio/src/address.c
+++ b/libs/luci-lib-nixio/src/address.c
@@ -331,7 +331,9 @@ static int nixio_getnameinfo(lua_State *L) {
nixio__addr_write(&addr, (struct sockaddr *)&saddr);
- int res = getnameinfo((struct sockaddr *)&saddr, sizeof(saddr),
+ int res = getnameinfo((struct sockaddr *)&saddr,
+ (saddr.ss_family == AF_INET)
+ ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6),
host, sizeof(host), NULL, 0, NI_NAMEREQD);
#ifdef __linux__
diff --git a/modules/luci-base/luasrc/cbi.lua b/modules/luci-base/luasrc/cbi.lua
index 45c91890a9..f3d4618b65 100644
--- a/modules/luci-base/luasrc/cbi.lua
+++ b/modules/luci-base/luasrc/cbi.lua
@@ -1533,13 +1533,16 @@ function Flag.parse(self, section)
if fexists then
local fvalue = self:formvalue(section) and self.enabled or self.disabled
+ local cvalue = self:cfgvalue(section)
if fvalue ~= self.default or (not self.optional and not self.rmempty) then
self:write(section, fvalue)
else
self:remove(section)
end
+ if (fvalue ~= cvalue) then self.section.changed = true end
else
self:remove(section)
+ self.section.changed = true
end
end
diff --git a/modules/luci-base/luasrc/http/protocol.lua b/modules/luci-base/luasrc/http/protocol.lua
index 61d7b802fe..859272679f 100644
--- a/modules/luci-base/luasrc/http/protocol.lua
+++ b/modules/luci-base/luasrc/http/protocol.lua
@@ -559,14 +559,23 @@ function parse_message_body( src, msg, filecb )
-- If we have a file callback then feed it
if type(filecb) == "function" then
- sink = filecb
-
+ local meta = {
+ name = "raw",
+ encoding = msg.env.CONTENT_TYPE
+ }
+ sink = function( chunk )
+ if chunk then
+ return filecb(meta, chunk, false)
+ else
+ return filecb(meta, nil, true)
+ end
+ end
-- ... else append to .content
else
msg.content = ""
msg.content_length = 0
- sink = function( chunk, err )
+ sink = function( chunk )
if chunk then
if ( msg.content_length + #chunk ) <= HTTP_MAX_CONTENT then
msg.content = msg.content .. chunk
diff --git a/modules/luci-base/luasrc/model/ipkg.lua b/modules/luci-base/luasrc/model/ipkg.lua
index 587637272d..2e26bd7a16 100644
--- a/modules/luci-base/luasrc/model/ipkg.lua
+++ b/modules/luci-base/luasrc/model/ipkg.lua
@@ -122,7 +122,7 @@ function upgrade()
end
-- List helper
-function _list(action, pat, cb)
+local function _list(action, pat, cb)
local fd = io.popen(ipkg .. " " .. action ..
(pat and (" '%s'" % pat:gsub("'", "")) or ""))
@@ -189,3 +189,48 @@ function overlay_root()
return od
end
+
+function compare_versions(ver1, comp, ver2)
+ if not ver1 or not ver2
+ or not comp or not (#comp > 0) then
+ error("Invalid parameters")
+ return nil
+ end
+ -- correct compare string
+ if comp == "<>" or comp == "><" or comp == "!=" or comp == "~=" then comp = "~="
+ elseif comp == "<=" or comp == "<" or comp == "=<" then comp = "<="
+ elseif comp == ">=" or comp == ">" or comp == "=>" then comp = ">="
+ elseif comp == "=" or comp == "==" then comp = "=="
+ elseif comp == "<<" then comp = "<"
+ elseif comp == ">>" then comp = ">"
+ else
+ error("Invalid compare string")
+ return nil
+ end
+
+ local av1 = util.split(ver1, "[%.%-]", nil, true)
+ local av2 = util.split(ver2, "[%.%-]", nil, true)
+
+ local max = table.getn(av1)
+ if (table.getn(av1) < table.getn(av2)) then
+ max = table.getn(av2)
+ end
+
+ for i = 1, max, 1 do
+ local s1 = av1[i] or ""
+ local s2 = av2[i] or ""
+
+ -- first "not equal" found return true
+ if comp == "~=" and (s1 ~= s2) then return true end
+ -- first "lower" found return true
+ if (comp == "<" or comp == "<=") and (s1 < s2) then return true end
+ -- first "greater" found return true
+ if (comp == ">" or comp == ">=") and (s1 > s2) then return true end
+ -- not equal then return false
+ if (s1 ~= s2) then return false end
+ end
+
+ -- all equal and not compare greater or lower then true
+ return not (comp == "<" or comp == ">")
+end
+
diff --git a/modules/luci-base/luasrc/model/ipkg.luadoc b/modules/luci-base/luasrc/model/ipkg.luadoc
index cf0985f94a..0dbab7a68f 100644
--- a/modules/luci-base/luasrc/model/ipkg.luadoc
+++ b/modules/luci-base/luasrc/model/ipkg.luadoc
@@ -107,3 +107,20 @@ Determines the overlay root used by opkg.
@return String containing the directory path of the overlay root.
]]
+---[[
+lua version of opkg compare-versions
+
+@class function
+@name compare_versions
+@param ver1 string version 1
+@param ver2 string version 2
+@param comp string compare versions using
+ "<=" or "<" lower-equal
+ ">" or ">=" greater-equal
+ "=" equal
+ "<<" lower
+ ">>" greater
+ "~=" not equal
+@return Boolean indicating the status of the compare
+]]
+
diff --git a/modules/luci-base/luasrc/model/network.lua b/modules/luci-base/luasrc/model/network.lua
index b6e390e818..20e1032760 100644
--- a/modules/luci-base/luasrc/model/network.lua
+++ b/modules/luci-base/luasrc/model/network.lua
@@ -1421,7 +1421,7 @@ function wifinet.is_up(self)
end
function wifinet.active_mode(self)
- local m = _stror(self.iwinfo.mode, self.iwdata.mode) or "ap"
+ local m = _stror(self.iwdata.mode, self.iwinfo.mode) or "ap"
if m == "ap" then m = "Master"
elseif m == "sta" then m = "Client"
@@ -1438,11 +1438,11 @@ function wifinet.active_mode_i18n(self)
end
function wifinet.active_ssid(self)
- return _stror(self.iwinfo.ssid, self.iwdata.ssid)
+ return _stror(self.iwdata.ssid, self.iwinfo.ssid)
end
function wifinet.active_bssid(self)
- return _stror(self.iwinfo.bssid, self.iwdata.bssid) or "00:00:00:00:00:00"
+ return _stror(self.iwdata.bssid, self.iwinfo.bssid) or "00:00:00:00:00:00"
end
function wifinet.active_encryption(self)
diff --git a/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua b/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
index b604f6b65e..b109c712ec 100644
--- a/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
+++ b/modules/luci-base/luasrc/sys/zoneinfo/tzdata.lua
@@ -89,7 +89,7 @@ TZ = {
{ 'America/Cancun', 'EST5' },
{ 'America/Caracas', 'VET4:30' },
{ 'America/Cayenne', 'GFT3' },
- { 'America/Cayman', 'EST5' },
+ { 'America/Cayman', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/Chicago', 'CST6CDT,M3.2.0,M11.1.0' },
{ 'America/Chihuahua', 'MST7MDT,M4.1.0,M10.5.0' },
{ 'America/Costa Rica', 'CST6' },
@@ -151,7 +151,7 @@ TZ = {
{ '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/Montevideo', 'UYT3' },
{ 'America/Montserrat', 'AST4' },
{ 'America/Nassau', 'EST5EDT,M3.2.0,M11.1.0' },
{ 'America/New York', 'EST5EDT,M3.2.0,M11.1.0' },
@@ -266,7 +266,7 @@ TZ = {
{ 'Asia/Oral', 'ORAT-5' },
{ 'Asia/Phnom Penh', 'ICT-7' },
{ 'Asia/Pontianak', 'WIB-7' },
- { 'Asia/Pyongyang', 'KST-9' },
+ { 'Asia/Pyongyang', 'KST-8:30' },
{ 'Asia/Qatar', 'AST-3' },
{ 'Asia/Qyzylorda', 'QYZT-6' },
{ 'Asia/Rangoon', 'MMT-6:30' },
@@ -322,7 +322,7 @@ TZ = {
{ 'Europe/Bucharest', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
{ 'Europe/Budapest', 'CET-1CEST,M3.5.0,M10.5.0/3' },
{ 'Europe/Busingen', 'CET-1CEST,M3.5.0,M10.5.0/3' },
- { 'Europe/Chisinau', 'EET-2EEST,M3.5.0/3,M10.5.0/4' },
+ { 'Europe/Chisinau', 'EET-2EEST,M3.5.0,M10.5.0/3' },
{ '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' },
diff --git a/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua b/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
index 24429ac36b..f156f3663a 100644
--- a/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
+++ b/modules/luci-base/luasrc/sys/zoneinfo/tzoffset.lua
@@ -41,7 +41,6 @@ OFFSET = {
pmst = -10800, -- PMST
pmdt = -7200, -- PMDT
uyt = -10800, -- UYT
- uyst = -7200, -- UYST
fnt = -7200, -- FNT
srt = -10800, -- SRT
clt = -10800, -- CLT
@@ -95,7 +94,7 @@ OFFSET = {
novt = 21600, -- NOVT
omst = 21600, -- OMST
orat = 18000, -- ORAT
- kst = 32400, -- KST
+ kst = 30600, -- KST
qyzt = 21600, -- QYZT
mmt = 23400, -- MMT
sakt = 36000, -- SAKT
diff --git a/modules/luci-base/luasrc/tools/status.lua b/modules/luci-base/luasrc/tools/status.lua
index 6e588fe71d..0dd092c6df 100644
--- a/modules/luci-base/luasrc/tools/status.lua
+++ b/modules/luci-base/luasrc/tools/status.lua
@@ -120,7 +120,9 @@ function wifi_networks()
assoclist = net:assoclist(),
country = net:country(),
txpower = net:txpower(),
- txpoweroff = net:txpower_offset()
+ txpoweroff = net:txpower_offset(),
+ disabled = (dev:get("disabled") == "1" or
+ net:get("disabled") == "1")
}
end
diff --git a/modules/luci-base/luasrc/view/cbi/network_netlist.htm b/modules/luci-base/luasrc/view/cbi/network_netlist.htm
index 7e23d149a8..4f186ca8ea 100644
--- a/modules/luci-base/luasrc/view/cbi/network_netlist.htm
+++ b/modules/luci-base/luasrc/view/cbi/network_netlist.htm
@@ -59,6 +59,7 @@
<%- else -%>
<%:unspecified -or- create:%>
<%- end -%>&#160;</em></label>
+ <input style="display:none" type="password" />
<input style="width:6em" type="text"<%=attr("name", cbid .. ".newnet")%> onfocus="document.getElementById('<%=cbid%>_new').checked=true" />
</div>
</li>
diff --git a/modules/luci-mod-admin-full/luasrc/controller/admin/status.lua b/modules/luci-mod-admin-full/luasrc/controller/admin/status.lua
index 2d81caf242..1ceb24d16a 100644
--- a/modules/luci-mod-admin-full/luasrc/controller/admin/status.lua
+++ b/modules/luci-mod-admin-full/luasrc/controller/admin/status.lua
@@ -51,7 +51,7 @@ function action_iptables()
luci.dispatcher.build_url("admin", "status", "iptables")
)
elseif luci.http.formvalue("restart") == "1" then
- luci.util.exec("/etc/init.d/firewall reload")
+ luci.util.exec("/etc/init.d/firewall restart")
luci.http.redirect(
luci.dispatcher.build_url("admin", "status", "iptables")
)
diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua
index 997a9274d2..49103a8113 100644
--- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua
+++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua
@@ -89,6 +89,11 @@ s:taboption("advanced", Flag, "nonegcache",
translate("No negative cache"),
translate("Do not cache negative replies, e.g. for not existing domains"))
+s:taboption("advanced", Value, "serversfile",
+ translate("Additional servers file"),
+ translate("This file may contain lines like 'server=/domain/1.2.3.4' or 'server=1.2.3.4' for"..
+ "domain-specific or full upstream <abbr title=\"Domain Name System\">DNS</abbr> servers."))
+
s:taboption("advanced", Flag, "strictorder",
translate("Strict order"),
translate("<abbr title=\"Domain Name System\">DNS</abbr> servers will be queried in the " ..
diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua
index dd619b3143..9a2bd5d201 100644
--- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua
+++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua
@@ -143,7 +143,7 @@ local found_sta = nil
local _, net
if wnet:mode() ~= "sta" then
for _, net in ipairs(wdev:get_wifinets()) do
- if net:mode() == "sta" then
+ if net:mode() == "sta" and net:get("disabled") ~= "1" then
if not found_sta then
found_sta = {}
found_sta.channel = net:channel()
diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm
index b7c44f9073..4fc268e66c 100644
--- a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm
+++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_overview.htm
@@ -183,7 +183,7 @@
for( var i = 0; i < st.length; i++ )
{
var iw = st[i];
- var is_assoc = (iw.bssid && iw.bssid != '00:00:00:00:00:00' && iw.channel && iw.mode != 'Unknown');
+ var is_assoc = (iw.bssid && iw.bssid != '00:00:00:00:00:00' && iw.channel && iw.mode != 'Unknown' && !iw.disabled);
var p = iw.quality;
var q = is_assoc ? p : -1;
diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_status.htm b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_status.htm
index 2484fd3c6b..fa0a97b707 100644
--- a/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_status.htm
+++ b/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_status.htm
@@ -6,7 +6,7 @@
{
if (iw && (iw = iw[0]))
{
- var is_assoc = (iw.bssid && iw.bssid != '00:00:00:00:00:00' && iw.channel);
+ var is_assoc = (iw.bssid && iw.bssid != '00:00:00:00:00:00' && iw.channel && !iw.disabled);
var p = iw.quality;
var q = is_assoc ? p : -1;
diff --git a/modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm b/modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm
index 548b22d167..07a96b2bf0 100644
--- a/modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm
+++ b/modules/luci-mod-admin-full/luasrc/view/admin_status/index.htm
@@ -352,7 +352,7 @@
for (var nidx = 0; nidx < dev.networks.length; nidx++)
{
var net = dev.networks[nidx];
- var is_assoc = (net.bssid != '00:00:00:00:00:00' && net.channel);
+ var is_assoc = (net.bssid != '00:00:00:00:00:00' && net.channel && !net.disabled);
var icon;
if (!is_assoc)
diff --git a/modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm b/modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm
index 42a58f9dd3..fc3948ecc1 100644
--- a/modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm
+++ b/modules/luci-mod-freifunk/luasrc/view/freifunk/public_status.htm
@@ -49,6 +49,32 @@ for _, dev in ipairs(devices) do
end
local has_iwinfo = pcall(require, "iwinfo")
+
+-- Find default routes
+
+local _, r, def4, def6
+
+for _, r in ipairs(ip.routes({ type = 1, dest_exact = "0.0.0.0/0" })) do
+ def4 = {
+ gateway = r.gw:string(),
+ dest = r.dest:string(),
+ dev = r.dev,
+ metr = r.metric or 0
+ }
+ break
+end
+
+for _, r in ipairs(ip.routes({ type = 1, dest_exact = "::/0" })) do
+ def6 = {
+ gateway = r.gw:string(),
+ dest = r.dest:string(),
+ dev = r.dev,
+ metr = r.metric or 0
+ }
+ break
+end
+
+
if luci.http.formvalue("status") == "1" then
local rv = { }
for dev in pairs(netdevs) do
@@ -67,30 +93,6 @@ if luci.http.formvalue("status") == "1" then
end
- -- Find default routes
-
- local _, r, def4, def6
-
- for _, r in ipairs(ip.routes({ type = 1, dest_exact = "0.0.0.0/0" })) do
- def4 = {
- gateway = r.gw:string(),
- dest = r.dest:string(),
- dev = r.dev,
- metr = r.metric or 0
- }
- break
- end
-
- for _, r in ipairs(ip.routes({ type = 1, dest_exact = "::/0" })) do
- def6 = {
- gateway = r.gw:string(),
- dest = r.dest:string(),
- dev = r.dev,
- metr = r.metric or 0
- }
- break
- end
-
rv[#rv+1] = {
time = time,
uptime = uptime,
@@ -297,7 +299,7 @@ end
if bitrate ~= "N/A" then
bitrate = ( bitrate / 1000 ).."Mb/s"
end
- local interface = net.iwdata.ifname or "N/A"
+ local interface = net.iwinfo.ifname or "N/A"
%>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td class="cbi-value-field" id="<%=net:ifname()%>-signal"><%=signal_string%></td>
@@ -323,7 +325,7 @@ end
<div class="cbi-section">
<div class="cbi-section-node">
-<% if not defroutev4 and not defroutev6 then %>
+<% if not def4 and not def6 then %>
<%:No default routes known.%>
<%else%>
<table class="cbi-section-table">
@@ -334,23 +336,22 @@ end
<th class="cbi-section-table-cell"><%:Metric%></th>
</tr>
- <% if defroutev4 then %>
-
+ <% if def4 then %>
<tr class="cbi-section-table-row cbi-rowstyle-1">
- <td class="cbi-value-field" id="v4dst"><%=defroutev4.dest%></td>
- <td class="cbi-value-field" id="v4dev"><%=defroutev4.device%></td>
- <td class="cbi-value-field" id="v4gw"><%=defroutev4.gateway%></td>
- <td class="cbi-value-field" id="v4metr"><%=defroutev4.metric%></td>
+ <td class="cbi-value-field" id="v4dst"><%=def4.dest%></td>
+ <td class="cbi-value-field" id="v4dev"><%=def4.dev%></td>
+ <td class="cbi-value-field" id="v4gw"><%=def4.gateway%></td>
+ <td class="cbi-value-field" id="v4metr"><%=def4.metr%></td>
</tr>
<% end
- if defroutev6 then %>
+ if def6 then %>
<tr class="cbi-section-table-row cbi-rowstyle-2">
- <td class="cbi-value-field" id="v6dst"><%=defroutev6.dest%></td>
- <td class="cbi-value-field" id="v6dev"><%=defroutev6.device%></td>
- <td class="cbi-value-field" id="v6gw"><%=defroutev6.nexthop%></td>
- <td class="cbi-value-field" id="v6metr"><%=defroutev6.metric%></td>
+ <td class="cbi-value-field" id="v6dst"><%=def6.dest%></td>
+ <td class="cbi-value-field" id="v6dev"><%=def6.dev%></td>
+ <td class="cbi-value-field" id="v6gw"><%=def6.gateway%></td>
+ <td class="cbi-value-field" id="v6metr"><%=def6.metr%></td>
</tr>
<% end %>
diff --git a/modules/luci-mod-rpc/luasrc/controller/rpc.lua b/modules/luci-mod-rpc/luasrc/controller/rpc.lua
index 862e5839f2..129ca43b51 100644
--- a/modules/luci-mod-rpc/luasrc/controller/rpc.lua
+++ b/modules/luci-mod-rpc/luasrc/controller/rpc.lua
@@ -49,6 +49,8 @@ function rpc_auth()
server.challenge = function(user, pass)
local sid, token, secret
+ require "luci.config"
+
if sys.user.checkpasswd(user, pass) then
local sdat = util.ubus("session", "create", { timeout = luci.config.sauth.sessiontime })
if sdat then