Merge pull request #1718 from dibdot/travelmate
authorDirk Brenken <dev@brenken.org>
Thu, 5 Apr 2018 12:43:53 +0000 (14:43 +0200)
committerGitHub <noreply@github.com>
Thu, 5 Apr 2018 12:43:53 +0000 (14:43 +0200)
luci-app-travelmate: sync with travelmate 1.2.0

82 files changed:
applications/luci-app-adblock/luasrc/controller/adblock.lua
applications/luci-app-adblock/po/it/adblock.po
applications/luci-app-adblock/po/ja/adblock.po
applications/luci-app-adblock/po/pt-br/adblock.po
applications/luci-app-adblock/po/ru/adblock.po
applications/luci-app-adblock/po/templates/adblock.pot
applications/luci-app-commands/luasrc/view/commands.htm
applications/luci-app-cshark/luasrc/controller/cshark.lua
applications/luci-app-ddns/luasrc/controller/ddns.lua
applications/luci-app-freifunk-diagnostics/luasrc/controller/freifunk/diag.lua
applications/luci-app-freifunk-diagnostics/luasrc/view/freifunk/diagnostics.htm
applications/luci-app-mwan3/luasrc/controller/mwan3.lua
applications/luci-app-mwan3/luasrc/model/cbi/mwan/interface.lua
applications/luci-app-mwan3/luasrc/model/cbi/mwan/notify.lua
applications/luci-app-mwan3/luasrc/model/cbi/mwan/policy.lua
applications/luci-app-mwan3/luasrc/model/cbi/mwan/rule.lua
applications/luci-app-mwan3/luasrc/view/mwan/overview_status_interface.htm
applications/luci-app-mwan3/luasrc/view/mwan/status_detail.htm
applications/luci-app-mwan3/luasrc/view/mwan/status_diagnostics.htm
applications/luci-app-mwan3/luasrc/view/mwan/status_interface.htm
applications/luci-app-mwan3/luasrc/view/mwan/status_troubleshooting.htm
applications/luci-app-mwan3/po/ja/mwan3.po
applications/luci-app-mwan3/po/ru/mwan3.po
applications/luci-app-mwan3/po/templates/mwan3.pot
applications/luci-app-mwan3/po/zh-cn/mwan3.po
applications/luci-app-mwan3/po/zh-tw/mwan3.po
applications/luci-app-olsr/luasrc/controller/olsr.lua
applications/luci-app-openvpn/luasrc/model/cbi/openvpn.lua
applications/luci-app-splash/luasrc/controller/splash/splash.lua
applications/luci-app-splash/root/usr/sbin/luci-splash
applications/luci-app-statistics/luasrc/statistics/rrdtool.lua
applications/luci-app-tinyproxy/luasrc/view/tinyproxy_status.htm
applications/luci-app-travelmate/po/ja/travelmate.po
applications/luci-app-travelmate/po/pt-br/travelmate.po
applications/luci-app-travelmate/po/ru/travelmate.po
applications/luci-app-travelmate/po/templates/travelmate.pot
applications/luci-app-upnp/luasrc/controller/upnp.lua
applications/luci-app-vnstat/luasrc/view/vnstat.htm
applications/luci-app-wol/luasrc/model/cbi/wol.lua
modules/luci-base/htdocs/luci-static/resources/cbi.js
modules/luci-base/luasrc/cbi/datatypes.lua
modules/luci-base/luasrc/dispatcher.lua
modules/luci-base/luasrc/model/ipkg.lua
modules/luci-base/luasrc/model/network.lua
modules/luci-base/luasrc/model/uci.lua
modules/luci-base/luasrc/sys.lua
modules/luci-base/luasrc/tools/status.lua
modules/luci-base/luasrc/util.lua
modules/luci-base/luasrc/util.luadoc
modules/luci-base/luasrc/view/sysauth.htm
modules/luci-base/po/ca/base.po
modules/luci-base/po/cs/base.po
modules/luci-base/po/de/base.po
modules/luci-base/po/el/base.po
modules/luci-base/po/en/base.po
modules/luci-base/po/es/base.po
modules/luci-base/po/fr/base.po
modules/luci-base/po/he/base.po
modules/luci-base/po/hu/base.po
modules/luci-base/po/it/base.po
modules/luci-base/po/ja/base.po
modules/luci-base/po/ko/base.po
modules/luci-base/po/ms/base.po
modules/luci-base/po/no/base.po
modules/luci-base/po/pl/base.po
modules/luci-base/po/pt-br/base.po
modules/luci-base/po/pt/base.po
modules/luci-base/po/ro/base.po
modules/luci-base/po/ru/base.po
modules/luci-base/po/sk/base.po
modules/luci-base/po/sv/base.po
modules/luci-base/po/templates/base.pot
modules/luci-base/po/tr/base.po
modules/luci-base/po/uk/base.po
modules/luci-base/po/vi/base.po
modules/luci-base/po/zh-cn/base.po
modules/luci-base/po/zh-tw/base.po
modules/luci-mod-admin-full/luasrc/controller/admin/network.lua
modules/luci-mod-admin-full/luasrc/controller/admin/status.lua
modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/dhcp.lua
modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/vlan.lua
modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua

index 700f187..763c0b4 100644 (file)
@@ -36,8 +36,8 @@ end
 function queryData(domain)
        if domain then
                luci.http.prepare_content("text/plain")
-               local cmd = "/etc/init.d/adblock query %q 2>&1"
-               local util = io.popen(cmd % domain)
+               local cmd = "/etc/init.d/adblock query %s 2>&1"
+               local util = io.popen(cmd % util.shellquote(domain))
                if util then
                        while true do
                                local line = util:read("*l")
index 88adcc8..0a1b65a 100644 (file)
@@ -275,8 +275,8 @@ msgid ""
 msgstr ""
 
 msgid ""
-"Size of the download queue to handle downloads &amp; list processing in parallel "
-"(default '4').<br />"
+"Size of the download queue to handle downloads &amp; list processing in "
+"parallel (default '4').<br />"
 msgstr ""
 
 msgid "Startup Trigger"
index 60c5a9a..dfd72cb 100644 (file)
@@ -301,8 +301,8 @@ msgstr ""
 "処理エラーまたはドメイン カウントが0以下の場合、メールを送信します。<br />"
 
 msgid ""
-"Size of the download queue to handle downloads &amp; list processing in parallel "
-"(default '4').<br />"
+"Size of the download queue to handle downloads &amp; list processing in "
+"parallel (default '4').<br />"
 msgstr ""
 "ダウンロードの制御とリストの処理を同時並行的に行うダウンロード キューのサイズ"
 "です(既定値: '4')。<br />"
index 7eb6e3e..c0d9d81 100644 (file)
@@ -267,8 +267,8 @@ msgid ""
 msgstr ""
 
 msgid ""
-"Size of the download queue to handle downloads &amp; list processing in parallel "
-"(default '4').<br />"
+"Size of the download queue to handle downloads &amp; list processing in "
+"parallel (default '4').<br />"
 msgstr ""
 
 msgid "Startup Trigger"
index 6e80e80..17f39fd 100644 (file)
@@ -303,8 +303,8 @@ msgstr ""
 "&le; 0.<br />"
 
 msgid ""
-"Size of the download queue to handle downloads &amp; list processing in parallel "
-"(default '4').<br />"
+"Size of the download queue to handle downloads &amp; list processing in "
+"parallel (default '4').<br />"
 msgstr ""
 "Значение очереди загрузки для выполнения параллельных загрузок (по умолчанию "
 "'4').<br />"
index 5a93f8f..6fbaa65 100644 (file)
@@ -248,8 +248,8 @@ msgid ""
 msgstr ""
 
 msgid ""
-"Size of the download queue to handle downloads &amp; list processing in parallel "
-"(default '4').<br />"
+"Size of the download queue to handle downloads &amp; list processing in "
+"parallel (default '4').<br />"
 msgstr ""
 
 msgid "Startup Trigger"
index f094e18..3b36155 100644 (file)
        uci:foreach("luci", "command", function(s) commands[#commands+1] = s end)
 %>
 
-<form method="get" action="<%=pcdata(luci.http.getenv("REQUEST_URI"))%>">
+<form method="get" action="<%=pcdata(FULL_REQUEST_URI)%>">
        <div class="cbi-map">
                <h2 name="content"><%:Custom Commands%></h2>
 
index 4d9bbba..43410a0 100644 (file)
@@ -53,7 +53,13 @@ function cshark_iface_dump_start(ifname, value, flag, filter)
 
        luci.http.prepare_content("text/plain")
 
-       local res = os.execute("(/sbin/cshark -i " .. ifname .. " -" .. flag .. " " .. value .. " -p /tmp/cshark-luci.pid " .. filter .. " > /tmp/cshark-luci.out 2>&1) &")
+       local res = os.execute("(/sbin/cshark -i %s -%s %s -p /tmp/cshark-luci.pid %s > /tmp/cshark-luci.out 2>&1) &" %{
+               luci.util.shellquote(ifname),
+               luci.util.shellquote(flag),
+               luci.util.shellquote(value),
+               luci.util.shellquote(filter)
+       })
+
        luci.http.write(tostring(res))
 end
 
index 3d31e4e..5f4a511 100755 (executable)
@@ -301,7 +301,7 @@ function startstop(section, enabled)
        uci:unload("ddns")
 
        -- start ddns-updater for section
-       local command = luci_helper .. [[ -S ]] .. section .. [[ -- start]]
+       local command = "%s -S %s -- start" %{ luci_helper, UTIL.shellquote(section) }
        os.execute(command)
        NX.nanosleep(3) -- 3 seconds "show time"
 
index 7bb4761..92b3afc 100644 (file)
@@ -33,7 +33,7 @@ function diag_command(cmd, addr)
        if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
                luci.http.prepare_content("text/plain")
 
-               local util = io.popen(cmd % addr)
+               local util = io.popen(cmd % luci.util.shellquote(addr))
                if util then
                        while true do
                                local ln = util:read("*l")
@@ -52,21 +52,21 @@ function diag_command(cmd, addr)
 end
 
 function diag_ping(addr)
-       diag_command("ping -c 5 -W 1 %q 2>&1", addr)
+       diag_command("ping -c 5 -W 1 %s 2>&1", addr)
 end
 
 function diag_traceroute(addr)
-       diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr)
+       diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
 end
 
 function diag_nslookup(addr)
-       diag_command("nslookup %q 2>&1", addr)
+       diag_command("nslookup %s 2>&1", addr)
 end
 
 function diag_ping6(addr)
-       diag_command("ping6 -c 5 %q 2>&1", addr)
+       diag_command("ping6 -c 5 %s 2>&1", addr)
 end
 
 function diag_traceroute6(addr)
-       diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr)
+       diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)
 end
index fe205d0..eac1ecd 100644 (file)
@@ -53,7 +53,7 @@ local has_traceroute6 = fs.access("/usr/bin/traceroute6")
        }
 //]]></script>
 
-<form method="post" action="<%=pcdata(luci.http.getenv("REQUEST_URI"))%>">
+<form method="post" action="<%=pcdata(FULL_REQUEST_URI)%>">
        <div class="cbi-map">
                <h2 name="content"><%:Diagnostics%></h2>
 
index 64ee9f5..27dc984 100644 (file)
@@ -98,7 +98,7 @@ function diagnosticsData(interface, task)
 
        function diag_command(cmd, addr)
                if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
-                       local util = io.popen(cmd % addr)
+                       local util = io.popen(cmd % ut.shellquote(addr))
                        if util then
                                while true do
                                        local ln = util:read("*l")
@@ -138,7 +138,7 @@ function diagnosticsData(interface, task)
                if task == "ping_gateway" then
                        local gateway = get_gateway(interface)
                        if gateway ~= nil then
-                               diag_command("ping -c 5 -W 1 %q 2>&1", gateway)
+                               diag_command("ping -c 5 -W 1 %s 2>&1", gateway)
                        else
                                luci.http.prepare_content("text/plain")
                                luci.http.write(string.format("No gateway for interface %s found.", interface))
@@ -147,7 +147,7 @@ function diagnosticsData(interface, task)
                        local trackips = uci:get("mwan3", interface, "track_ip")
                        if #trackips > 0 then
                                for i in pairs(trackips) do
-                                       diag_command("ping -c 5 -W 1 %q 2>&1", trackips[i])
+                                       diag_command("ping -c 5 -W 1 %s 2>&1", trackips[i])
                                end
                        else
                                luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface))
@@ -185,10 +185,10 @@ function diagnosticsData(interface, task)
                                luci.http.write(string.format("Routing table %s for interface %s not found", number, interface))
                        end
                elseif task == "hotplug_ifup" then
-                       os.execute(string.format("/usr/sbin/mwan3 ifup %s", interface))
+                       os.execute(string.format("/usr/sbin/mwan3 ifup %s", ut.shellquote(interface)))
                        luci.http.write(string.format("Hotplug ifup sent to interface %s", interface))
                elseif task == "hotplug_ifdown" then
-                       os.execute(string.format("/usr/sbin/mwan3 ifdown %s", interface))
+                       os.execute(string.format("/usr/sbin/mwan3 ifdown %s", ut.shellquote(interface)))
                        luci.http.write(string.format("Hotplug ifdown sent to interface %s", interface))
                else
                        luci.http.write("Unknown task")
index 4b1a070..556a4f7 100644 (file)
@@ -5,40 +5,40 @@
 dsp = require "luci.dispatcher"
 
 
-function interfaceWarnings(overview, count)
+function interfaceWarnings(overview, count, iface_max)
        local warnings = ""
-       if count <= 250 then
-               warnings = string.format("<strong>%s</strong></br>",
-                       translatef("There are currently %d of 250 supported interfaces configured", count)
+       if count <= iface_max then
+               warnings = string.format("<strong>%s</strong><br />",
+                       translatef("There are currently %d of %d supported interfaces configured", count, iface_max)
                        )
        else
-               warnings = string.format("<strong>%s</strong></br>",
-                       translatef("WARNING: %d interfaces are configured exceeding the maximum of 250!", count)
+               warnings = string.format("<strong>%s</strong><br />",
+                       translatef("WARNING: %d interfaces are configured exceeding the maximum of %d!", count, iface_max)
                        )
        end
 
        for i, k in pairs(overview) do
                if overview[i]["network"] == false then
-                       warnings = warnings .. string.format("<strong>%s</strong></br>",
+                       warnings = warnings .. string.format("<strong>%s</strong><br />",
                                        translatef("WARNING: Interface %s are not found in /etc/config/network", i)
                                        )
                end
 
                if overview[i]["default_route"] == false then
-                       warnings = warnings .. string.format("<strong>%s</strong></br>",
+                       warnings = warnings .. string.format("<strong>%s</strong><br />",
                                translatef("WARNING: Interface %s has no default route in the main routing table", i)
                                )
                end
 
                if overview[i]["reliability"] == false then
-                       warnings = warnings .. string.format("<strong>%s</strong></br>",
+                       warnings = warnings .. string.format("<strong>%s</strong><br />",
                                translatef("WARNING: Interface %s has a higher reliability " ..
                                "requirement than tracking hosts (%d)", i, overview[i]["tracking"])
                                )
                end
 
                if overview[i]["duplicate_metric"] == true then
-                       warnings = warnings .. string.format("<strong>%s</strong></br>",
+                       warnings = warnings .. string.format("<strong>%s</strong><br />",
                                translatef("WARNING: Interface %s has a duplicate metric %s configured", i, overview[i]["metric"])
                                )
                end
@@ -103,7 +103,34 @@ function configCheck()
                        end
                end
        )
-       return overview, count
+
+       -- calculate iface_max usage from firewall mmx_mask
+       function bit(p)
+               return 2 ^ (p - 1)
+       end
+       function hasbit(x, p)
+               return x % (p + p) >= p
+       end
+       function setbit(x, p)
+               return hasbit(x, p) and x or x + p
+       end
+
+       local uci = require("uci").cursor(nil, "/var/state")
+       local mmx_mask = uci:get("mwan3", "globals", "mmx_mask") or "0x3F00"
+       local number = tonumber(mmx_mask, 16)
+       local bits = 0
+       local iface_max = 0
+       for i=1,16 do
+               if hasbit(number, bit(i)) then
+                       bits = bits + 1
+                       iface_max = setbit( iface_max, bit(bits))
+               end
+       end
+
+       -- subtract blackhole, unreachable and default table from iface_max
+       iface_max = iface_max - 3
+
+       return overview, count, iface_max
 end
 
 m5 = Map("mwan3", translate("MWAN - Interfaces"),
index 6f87a3d..4c6e210 100644 (file)
@@ -23,7 +23,11 @@ f = m5:section(SimpleSection, nil,
        "<br />" ..
        "There are three main environment variables that are passed to this script.<br />" ..
        "<br />" ..
-       "$ACTION Either \"ifup\" or \"ifdown\"<br />" ..
+       "$ACTION <br />" ..
+       "* \"ifup\" Is called by netifd and mwan3track <br />" ..
+       "* \"ifdown\" Is called by netifd and mwan3track <br />" ..
+       "* \"connected\" Is only called by mwan3track if tracking was successful <br />" ..
+       "* \"disconnected\" Is only called by mwan3track if tracking has failed <br />" ..
        "$INTERFACE Name of the interface which went up or down (e.g. \"wan\" or \"wwan\")<br />" ..
        "$DEVICE Physical device name which interface went up or down (e.g. \"eth0\" or \"wwan0\")<br />" ..
        "<br />"))
index 7f12782..c4567f7 100644 (file)
@@ -24,7 +24,7 @@ function policyError(policy_error)
        local warnings = ""
        for i, k in pairs(policy_error) do
                if policy_error[i] == true then
-                       warnings = warnings .. string.format("<strong>%s</strong></br>",
+                       warnings = warnings .. string.format("<strong>%s</strong><br />",
                                translatef("WARNING: Policie %s has exceeding the maximum name of 15 characters", i)
                                )
                end
index cb2a995..fb885f8 100644 (file)
@@ -28,7 +28,7 @@ function ruleWarn(rule_error)
        local warnings = ""
        for i, k in pairs(rule_error) do
                if rule_error[i] == true then
-                       warnings = warnings .. string.format("<strong>%s</strong></br>",
+                       warnings = warnings .. string.format("<strong>%s</strong><br />",
                                translatef("WARNING: Rule %s have a port configured with no or improper protocol specified!", i)
                                )
                end
index 4ec0edf..49d120c 100644 (file)
@@ -19,7 +19,7 @@ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "status", "mwan", "interface_
                                        switch (status.interfaces[iface].status)
                                        {
                                                case 'online':
-                                                       state = '<%:Online (tracking active)%>';
+                                                       state = '<%:Online%>';
                                                        css = 'success';
                                                        break;
                                                case 'offline':
@@ -69,6 +69,7 @@ XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "status", "mwan", "interface_
 <fieldset id="interface_field" class="cbi-section">
        <legend><%:MWAN Interfaces%></legend>
        <div id="mwan_status_text">
-               <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" /><%:Collecting data...%>
+               <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align:middle" />
+               <%:Collecting data...%>
        </div>
 </fieldset>
index 70eac72..bcc23be 100644 (file)
@@ -18,9 +18,7 @@
        XHR.poll(5, '<%=luci.dispatcher.build_url("admin", "status", "mwan", "detailed_status")%>', null,
                function(x)
                {
-                       var legend = document.getElementById('diag-rc-legend');
                        var output = document.getElementById('diag-rc-output');
-                       legend.style.display = 'none';
                        output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
                }
        );
@@ -32,9 +30,9 @@
        <div><strong><%:INFO: MWAN not running%></strong></div>
        <%end%>
        <fieldset class="cbi-section">
-               <legend id="diag-rc-legend"><%:Collecting data...%></legend>
                <span id="diag-rc-output">
                        <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align: middle;" />
+                       <%:Collecting data...%>
                </span>
        </fieldset>
 </div>
index f1c5d8f..22f4734 100644 (file)
@@ -31,7 +31,6 @@
 
        function update_status(iface, task)
        {
-               var legend = document.getElementById('diag-rc-legend');
                var output = document.getElementById('diag-rc-output');
 
                output.innerHTML =
@@ -45,7 +44,6 @@
                stxhr.post('<%=url('admin/status/mwan')%>/diagnostics_display' + '/' + iface + '/' + task, { token: '<%=token%>' },
                        function(x)
                        {
-                               legend.style.display = 'none';
                                output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
                        }
                );
@@ -86,7 +84,6 @@
                </fieldset>
        </div>
        <fieldset class="cbi-section" style="display:none">
-               <legend id="diag-rc-legend"><%:Collecting data...%></legend>
                <span id="diag-rc-output"></span>
        </fieldset>
 </form>
index cb47696..4518bd6 100644 (file)
@@ -15,6 +15,7 @@
 
 <script type="text/javascript" src="<%=resource%>/cbi.js"></script>
 
-<%+mwan/overview_status_interface%>
-
+<div class="cbi-map">
+       <%+mwan/overview_status_interface%>
+</div>
 <%+footer%>
index 77d0092..f60e0da 100644 (file)
@@ -18,9 +18,7 @@
        XHR.poll(15, '<%=luci.dispatcher.build_url("admin", "status", "mwan", "troubleshooting_display")%>', null,
                function(x)
                {
-                       var legend = document.getElementById('diag-rc-legend');
                        var output = document.getElementById('diag-rc-output');
-                       legend.style.display = 'none';
                        output.innerHTML = String.format('<pre>%h</pre>', x.responseText);
                }
        );
@@ -32,9 +30,9 @@
        <div><strong><%:INFO: MWAN not running%></strong></div>
        <%end%>
        <fieldset class="cbi-section">
-               <legend id="diag-rc-legend"><%:Collecting data...%></legend>
                <span id="diag-rc-output">
                        <img src="<%=resource%>/icons/loading.gif" alt="<%:Loading%>" style="vertical-align: middle;" />
+                       <%:Collecting data...%>
                </span>
        </fieldset>
 </div>
index 4b3662a..e8fe0d6 100644 (file)
@@ -103,6 +103,9 @@ msgstr "ホットプラグ ifdown"
 msgid "Hotplug ifup"
 msgstr "ホットプラグ ifup"
 
+msgid "INFO: MWAN not running"
+msgstr ""
+
 msgid "IPset"
 msgstr "IPset"
 
@@ -174,8 +177,8 @@ msgstr ""
 msgid "MWAN Interface Configuration - %s"
 msgstr "MWAN インターフェース設定 - %s"
 
-msgid "MWAN Interface Live Status"
-msgstr "MWAN インターフェース Live ステータス"
+msgid "MWAN Interfaces"
+msgstr ""
 
 msgid "MWAN Member Configuration - %s"
 msgstr "MWAN メンバー設定 - %s"
@@ -195,9 +198,6 @@ msgstr ""
 msgid "MWAN Status - Troubleshooting"
 msgstr ""
 
-msgid "MWAN status - Interface Live Status"
-msgstr ""
-
 msgid ""
 "MWAN supports up to 250 physical and/or logical interfaces<br />MWAN "
 "requires that all interfaces have a unique metric configured in /etc/config/"
@@ -271,9 +271,6 @@ msgstr "オンライン"
 msgid "Online (tracking active)"
 msgstr "オンライン(追跡実行中)"
 
-msgid "Online (tracking off)"
-msgstr "オンライン(追跡オフ)"
-
 msgid "Ping count"
 msgstr "Ping 回数"
 
@@ -395,21 +392,14 @@ msgid ""
 "will<br />be executed with each netifd hotplug interface event<br />on "
 "interfaces for which mwan3 is enabled.<br /><br />There are three main "
 "environment variables that are passed to this script.<br /><br />$ACTION "
-"Either \"ifup\" or \"ifdown\"<br />$INTERFACE Name of the interface which "
-"went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE Physical device name "
-"which interface went up or down (e.g. \"eth0\" or \"wwan0\")<br /><br />"
-msgstr ""
-"このセクションでは、 \"/etc/mwan3.user\" の内容を変更することができます。"
-"<br />このファイルは、 sysupgrade 時に保持されます。<br /><br />注意: <br />"
-"このファイルは、シェルスクリプトとして解釈されます。<br />スクリプトの1行目"
-"は、&#34;#!bin/sh&#34; である必要があります(クォーテーション不要)。<br /># "
-"で始まる行はコメントであり、実行されません。<br />mwan3 のカスタム動作をここ"
-"に入力してください。これらは、 mwan3 が有効なインターフェースの<br />netifd "
-"ホットプラグ インターフェース イベント毎に実行されます。<br /><br />主に3つの"
-"環境変数が利用可能です。<br /><br />$ACTION - \"ifup\" および \"ifdown\"<br /"
-">$INTERFACE - Up または Down が行われたインターフェース名(例: \"wan\" や "
-"\"wwan\")<br />$DEVICE - Up または Down が行われた物理デバイス名(例: "
-"\"eth0\" や \"wwan0\")<br /><br />"
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
+msgstr ""
 
 msgid "Tracking hostname or IP address"
 msgstr "追跡ホスト名または IP アドレス"
@@ -503,6 +493,38 @@ msgstr "never"
 msgid "unreachable (reject)"
 msgstr "unreachable (reject)"
 
+#~ msgid "MWAN Interface Live Status"
+#~ msgstr "MWAN インターフェース Live ステータス"
+
+#~ msgid "Online (tracking off)"
+#~ msgstr "オンライン(追跡オフ)"
+
+#~ msgid ""
+#~ "This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+#~ ">The file is also preserved during sysupgrade.<br /><br />Notes:<br /"
+#~ ">This file is interpreted as a shell script.<br />The first line of the "
+#~ "script must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning "
+#~ "with # are comments and are not executed.<br />Put your custom mwan3 "
+#~ "action here, they will<br />be executed with each netifd hotplug "
+#~ "interface event<br />on interfaces for which mwan3 is enabled.<br /><br /"
+#~ ">There are three main environment variables that are passed to this "
+#~ "script.<br /><br />$ACTION Either \"ifup\" or \"ifdown\"<br />$INTERFACE "
+#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan"
+#~ "\")<br />$DEVICE Physical device name which interface went up or down (e."
+#~ "g. \"eth0\" or \"wwan0\")<br /><br />"
+#~ msgstr ""
+#~ "このセクションでは、 \"/etc/mwan3.user\" の内容を変更することができます。"
+#~ "<br />このファイルは、 sysupgrade 時に保持されます。<br /><br />注意: "
+#~ "<br />このファイルは、シェルスクリプトとして解釈されます。<br />スクリプト"
+#~ "の1行目は、&#34;#!bin/sh&#34; である必要があります(クォーテーション不"
+#~ "要)。<br /># で始まる行はコメントであり、実行されません。<br />mwan3 のカ"
+#~ "スタム動作をここに入力してください。これらは、 mwan3 が有効なインター"
+#~ "フェースの<br />netifd ホットプラグ インターフェース イベント毎に実行され"
+#~ "ます。<br /><br />主に3つの環境変数が利用可能です。<br /><br />$ACTION - "
+#~ "\"ifup\" および \"ifdown\"<br />$INTERFACE - Up または Down が行われたイン"
+#~ "ターフェース名(例: \"wan\" や \"wwan\")<br />$DEVICE - Up または Down が"
+#~ "行われた物理デバイス名(例: \"eth0\" や \"wwan0\")<br /><br />"
+
 #~ msgid "Currently Configured Interfaces"
 #~ msgstr "設定済みインターフェース"
 
index 8d5742c..069335d 100644 (file)
@@ -107,6 +107,9 @@ msgstr "Hotplug ifdown"
 msgid "Hotplug ifup"
 msgstr "Hotplug ifup"
 
+msgid "INFO: MWAN not running"
+msgstr ""
+
 msgid "IPset"
 msgstr "IPset"
 
@@ -177,8 +180,8 @@ msgstr "MWAN - Правила"
 msgid "MWAN Interface Configuration - %s"
 msgstr "Настройка интерфейсов MWAN  - %s"
 
-msgid "MWAN Interface Live Status"
-msgstr "Состояние интерфейса MWAN в настоящее время"
+msgid "MWAN Interfaces"
+msgstr ""
 
 msgid "MWAN Member Configuration - %s"
 msgstr "MWAN настройка узлов - %s"
@@ -198,9 +201,6 @@ msgstr "Состояние MWAN - Диагностика"
 msgid "MWAN Status - Troubleshooting"
 msgstr "Состояние MWAN - Устранение неполадок"
 
-msgid "MWAN status - Interface Live Status"
-msgstr "Состояние MWAN - Интерфейс в настоящее время"
-
 msgid ""
 "MWAN supports up to 250 physical and/or logical interfaces<br />MWAN "
 "requires that all interfaces have a unique metric configured in /etc/config/"
@@ -273,9 +273,6 @@ msgstr "Онлайн"
 msgid "Online (tracking active)"
 msgstr "Онлайн (отслеживание активно)"
 
-msgid "Online (tracking off)"
-msgstr "Онлайн  (отслеживание отключено)"
-
 msgid "Ping count"
 msgstr "Кол-во пинг-запросов"
 
@@ -411,23 +408,14 @@ msgid ""
 "will<br />be executed with each netifd hotplug interface event<br />on "
 "interfaces for which mwan3 is enabled.<br /><br />There are three main "
 "environment variables that are passed to this script.<br /><br />$ACTION "
-"Either \"ifup\" or \"ifdown\"<br />$INTERFACE Name of the interface which "
-"went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE Physical device name "
-"which interface went up or down (e.g. \"eth0\" or \"wwan0\")<br /><br />"
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
 msgstr ""
-"Страница позволяет изменять содержимое файла mwan3.user (/etc/mwan3.user)."
-"<br />Файл также сохраняется во время перепрошивки sysupgrade-совместимым "
-"образом.<br /><br />Примечание:<br />Этот файл интерпретируется как shell "
-"скрипт.<br />Первая строка скрипта должна быть &#34;#!/bin/sh&#34; без "
-"кавычек.<br />Строки начинающиеся с #, являются комментариями и не "
-"исполняются.<br />Поместите свои пользовательские действия mwan3 здесь, они "
-"будут<br />выполняться с каждым событием netifd hotplug интерфейса<br />на "
-"интерфейсах, для которых включен mwan3.<br /><br />В этот сценарий "
-"передаются три основные переменные среды.<br /><br />$ACTION либо \"ifup\" "
-"или \"ifdown\"<br />$INTERFACE - имя интерфейса, который включили или "
-"отключили (например, 'wan' или 'wwan') <br />$DEVICE - имя физического "
-"устройства, чей интерфейс включили или отключили  (например, 'eth0' или "
-"'wwan0')<br /><br />."
 
 msgid "Tracking hostname or IP address"
 msgstr "Отслеживание имени хоста или IP-адреса"
@@ -527,3 +515,40 @@ msgstr "никогда"
 
 msgid "unreachable (reject)"
 msgstr "недоступен (отклонить)"
+
+#~ msgid "MWAN Interface Live Status"
+#~ msgstr "Состояние интерфейса MWAN в настоящее время"
+
+#~ msgid "MWAN status - Interface Live Status"
+#~ msgstr "Состояние MWAN - Интерфейс в настоящее время"
+
+#~ msgid "Online (tracking off)"
+#~ msgstr "Онлайн  (отслеживание отключено)"
+
+#~ msgid ""
+#~ "This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+#~ ">The file is also preserved during sysupgrade.<br /><br />Notes:<br /"
+#~ ">This file is interpreted as a shell script.<br />The first line of the "
+#~ "script must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning "
+#~ "with # are comments and are not executed.<br />Put your custom mwan3 "
+#~ "action here, they will<br />be executed with each netifd hotplug "
+#~ "interface event<br />on interfaces for which mwan3 is enabled.<br /><br /"
+#~ ">There are three main environment variables that are passed to this "
+#~ "script.<br /><br />$ACTION Either \"ifup\" or \"ifdown\"<br />$INTERFACE "
+#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan"
+#~ "\")<br />$DEVICE Physical device name which interface went up or down (e."
+#~ "g. \"eth0\" or \"wwan0\")<br /><br />"
+#~ msgstr ""
+#~ "Страница позволяет изменять содержимое файла mwan3.user (/etc/mwan3.user)."
+#~ "<br />Файл также сохраняется во время перепрошивки sysupgrade-совместимым "
+#~ "образом.<br /><br />Примечание:<br />Этот файл интерпретируется как shell "
+#~ "скрипт.<br />Первая строка скрипта должна быть &#34;#!/bin/sh&#34; без "
+#~ "кавычек.<br />Строки начинающиеся с #, являются комментариями и не "
+#~ "исполняются.<br />Поместите свои пользовательские действия mwan3 здесь, "
+#~ "они будут<br />выполняться с каждым событием netifd hotplug "
+#~ "интерфейса<br />на интерфейсах, для которых включен mwan3.<br /><br />В "
+#~ "этот сценарий передаются три основные переменные среды.<br /><br />"
+#~ "$ACTION либо \"ifup\" или \"ifdown\"<br />$INTERFACE - имя интерфейса, "
+#~ "который включили или отключили (например, 'wan' или 'wwan') <br />$DEVICE "
+#~ "- имя физического устройства, чей интерфейс включили или отключили  "
+#~ "(например, 'eth0' или 'wwan0')<br /><br />."
index b726624..4aaaa5d 100644 (file)
@@ -88,6 +88,9 @@ msgstr ""
 msgid "Hotplug ifup"
 msgstr ""
 
+msgid "INFO: MWAN not running"
+msgstr ""
+
 msgid "IPset"
 msgstr ""
 
@@ -157,7 +160,7 @@ msgstr ""
 msgid "MWAN Interface Configuration - %s"
 msgstr ""
 
-msgid "MWAN Interface Live Status"
+msgid "MWAN Interfaces"
 msgstr ""
 
 msgid "MWAN Member Configuration - %s"
@@ -178,9 +181,6 @@ msgstr ""
 msgid "MWAN Status - Troubleshooting"
 msgstr ""
 
-msgid "MWAN status - Interface Live Status"
-msgstr ""
-
 msgid ""
 "MWAN supports up to 250 physical and/or logical interfaces<br />MWAN "
 "requires that all interfaces have a unique metric configured in /etc/config/"
@@ -239,9 +239,6 @@ msgstr ""
 msgid "Online (tracking active)"
 msgstr ""
 
-msgid "Online (tracking off)"
-msgstr ""
-
 msgid "Ping count"
 msgstr ""
 
@@ -351,9 +348,13 @@ msgid ""
 "will<br />be executed with each netifd hotplug interface event<br />on "
 "interfaces for which mwan3 is enabled.<br /><br />There are three main "
 "environment variables that are passed to this script.<br /><br />$ACTION "
-"Either \"ifup\" or \"ifdown\"<br />$INTERFACE Name of the interface which "
-"went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE Physical device name "
-"which interface went up or down (e.g. \"eth0\" or \"wwan0\")<br /><br />"
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
 msgstr ""
 
 msgid "Tracking hostname or IP address"
index c838bdb..dd2843e 100644 (file)
@@ -99,6 +99,9 @@ msgstr "Hotplug ifdown"
 msgid "Hotplug ifup"
 msgstr "Hotplug ifup"
 
+msgid "INFO: MWAN not running"
+msgstr ""
+
 msgid "IPset"
 msgstr "IPset"
 
@@ -168,8 +171,8 @@ msgstr ""
 msgid "MWAN Interface Configuration - %s"
 msgstr "MWAN 接口配置 - %s"
 
-msgid "MWAN Interface Live Status"
-msgstr "MWAN 接口实时状态"
+msgid "MWAN Interfaces"
+msgstr ""
 
 msgid "MWAN Member Configuration - %s"
 msgstr "MWAN 成员配置 - %s"
@@ -189,9 +192,6 @@ msgstr ""
 msgid "MWAN Status - Troubleshooting"
 msgstr ""
 
-msgid "MWAN status - Interface Live Status"
-msgstr ""
-
 msgid ""
 "MWAN supports up to 250 physical and/or logical interfaces<br />MWAN "
 "requires that all interfaces have a unique metric configured in /etc/config/"
@@ -262,9 +262,6 @@ msgstr "在线"
 msgid "Online (tracking active)"
 msgstr "在线(跟踪启用中)"
 
-msgid "Online (tracking off)"
-msgstr "在线(跟踪已关闭)"
-
 msgid "Ping count"
 msgstr "Ping 计数"
 
@@ -379,18 +376,14 @@ msgid ""
 "will<br />be executed with each netifd hotplug interface event<br />on "
 "interfaces for which mwan3 is enabled.<br /><br />There are three main "
 "environment variables that are passed to this script.<br /><br />$ACTION "
-"Either \"ifup\" or \"ifdown\"<br />$INTERFACE Name of the interface which "
-"went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE Physical device name "
-"which interface went up or down (e.g. \"eth0\" or \"wwan0\")<br /><br />"
-msgstr ""
-"这里允许您修改“/etc/mwan3.user”的内容。<br />该文件在 sysupgrade 期间也会保"
-"留。<br /><br />注意:<br />该文件会作为 shell 脚本解释。<br />脚本的第一行必"
-"须是&#34;#!/bin/sh&#34;,不带引号。<br />以#开头的行是注释,不会执行。<br />"
-"将您的自定义 mwan3 动作放在这里,他们将<br />在启用 mwan3 的接口上<br />在 "
-"netifd hotplug 接口事件时执行。<br /><br />有三个主要的环境变量传递给这个脚"
-"本。<br /><br />$ACTION “ifup”或“ifdown”<br />$INTERFACE 启动或停止的接口名"
-"(例如“wan”或“wwan”)<br />$DEVICE 启动或停止接口的物理设备名(例"
-"如“eth0”或“wwan0”)<br /><br />"
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
+msgstr ""
 
 msgid "Tracking hostname or IP address"
 msgstr "跟踪的主机或 IP 地址"
@@ -478,6 +471,35 @@ msgstr "从不"
 msgid "unreachable (reject)"
 msgstr "不可达(拒绝)"
 
+#~ msgid "MWAN Interface Live Status"
+#~ msgstr "MWAN 接口实时状态"
+
+#~ msgid "Online (tracking off)"
+#~ msgstr "在线(跟踪已关闭)"
+
+#~ msgid ""
+#~ "This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+#~ ">The file is also preserved during sysupgrade.<br /><br />Notes:<br /"
+#~ ">This file is interpreted as a shell script.<br />The first line of the "
+#~ "script must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning "
+#~ "with # are comments and are not executed.<br />Put your custom mwan3 "
+#~ "action here, they will<br />be executed with each netifd hotplug "
+#~ "interface event<br />on interfaces for which mwan3 is enabled.<br /><br /"
+#~ ">There are three main environment variables that are passed to this "
+#~ "script.<br /><br />$ACTION Either \"ifup\" or \"ifdown\"<br />$INTERFACE "
+#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan"
+#~ "\")<br />$DEVICE Physical device name which interface went up or down (e."
+#~ "g. \"eth0\" or \"wwan0\")<br /><br />"
+#~ msgstr ""
+#~ "这里允许您修改“/etc/mwan3.user”的内容。<br />该文件在 sysupgrade 期间也会"
+#~ "保留。<br /><br />注意:<br />该文件会作为 shell 脚本解释。<br />脚本的第"
+#~ "一行必须是&#34;#!/bin/sh&#34;,不带引号。<br />以#开头的行是注释,不会执"
+#~ "行。<br />将您的自定义 mwan3 动作放在这里,他们将<br />在启用 mwan3 的接口"
+#~ "上<br />在 netifd hotplug 接口事件时执行。<br /><br />有三个主要的环境变量"
+#~ "传递给这个脚本。<br /><br />$ACTION “ifup”或“ifdown”<br />$INTERFACE 启动"
+#~ "或停止的接口名(例如“wan”或“wwan”)<br />$DEVICE 启动或停止接口的物理设备"
+#~ "名(例如“eth0”或“wwan0”)<br /><br />"
+
 #~ msgid "Currently Configured Interfaces"
 #~ msgstr "当前配置的接口"
 
index d28bd82..114a001 100644 (file)
@@ -99,6 +99,9 @@ msgstr "Hotplug ifdown"
 msgid "Hotplug ifup"
 msgstr "Hotplug ifup"
 
+msgid "INFO: MWAN not running"
+msgstr ""
+
 msgid "IPset"
 msgstr "IPset"
 
@@ -168,8 +171,8 @@ msgstr ""
 msgid "MWAN Interface Configuration - %s"
 msgstr "MWAN 介面配置 - %s"
 
-msgid "MWAN Interface Live Status"
-msgstr "MWAN 介面實時狀態"
+msgid "MWAN Interfaces"
+msgstr ""
 
 msgid "MWAN Member Configuration - %s"
 msgstr "MWAN 成員配置 - %s"
@@ -189,9 +192,6 @@ msgstr ""
 msgid "MWAN Status - Troubleshooting"
 msgstr ""
 
-msgid "MWAN status - Interface Live Status"
-msgstr ""
-
 msgid ""
 "MWAN supports up to 250 physical and/or logical interfaces<br />MWAN "
 "requires that all interfaces have a unique metric configured in /etc/config/"
@@ -262,9 +262,6 @@ msgstr "線上"
 msgid "Online (tracking active)"
 msgstr "線上(跟蹤啟用中)"
 
-msgid "Online (tracking off)"
-msgstr "線上(跟蹤已關閉)"
-
 msgid "Ping count"
 msgstr "Ping 計數"
 
@@ -379,18 +376,14 @@ msgid ""
 "will<br />be executed with each netifd hotplug interface event<br />on "
 "interfaces for which mwan3 is enabled.<br /><br />There are three main "
 "environment variables that are passed to this script.<br /><br />$ACTION "
-"Either \"ifup\" or \"ifdown\"<br />$INTERFACE Name of the interface which "
-"went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE Physical device name "
-"which interface went up or down (e.g. \"eth0\" or \"wwan0\")<br /><br />"
-msgstr ""
-"這裡允許您修改“/etc/mwan3.user”的內容。<br />該檔案在 sysupgrade 期間也會保"
-"留。<br /><br />注意:<br />該檔案會作為 shell 指令碼解釋。<br />指令碼的第一"
-"行必須是&#34;#!/bin/sh&#34;,不帶引號。<br />以#開頭的行是註釋,不會執行。"
-"<br />將您的自定義 mwan3 動作放在這裡,他們將<br />在啟用 mwan3 的介面上<br /"
-">在 netifd hotplug 介面事件時執行。<br /><br />有三個主要的環境變數傳遞給這個"
-"腳本。<br /><br />$ACTION “ifup”或“ifdown”<br />$INTERFACE 啟動或停止的介面名"
-"(例如“wan”或“wwan”)<br />$DEVICE 啟動或停止介面的物理裝置名(例"
-"如“eth0”或“wwan0”)<br /><br />"
+"<br />* \"ifup\" Is called by netifd and mwan3track <br />* \"ifdown\" Is "
+"called by netifd and mwan3track <br />* \"connected\" Is only called by "
+"mwan3track if tracking was successful <br />* \"disconnected\" Is only "
+"called by mwan3track if tracking has failed <br />$INTERFACE Name of the "
+"interface which went up or down (e.g. \"wan\" or \"wwan\")<br />$DEVICE "
+"Physical device name which interface went up or down (e.g. \"eth0\" or "
+"\"wwan0\")<br /><br />"
+msgstr ""
 
 msgid "Tracking hostname or IP address"
 msgstr "跟蹤的主機或 IP 位址"
@@ -478,6 +471,35 @@ msgstr "從不"
 msgid "unreachable (reject)"
 msgstr "不可達(拒絕)"
 
+#~ msgid "MWAN Interface Live Status"
+#~ msgstr "MWAN 介面實時狀態"
+
+#~ msgid "Online (tracking off)"
+#~ msgstr "線上(跟蹤已關閉)"
+
+#~ msgid ""
+#~ "This section allows you to modify the content of \"/etc/mwan3.user\".<br /"
+#~ ">The file is also preserved during sysupgrade.<br /><br />Notes:<br /"
+#~ ">This file is interpreted as a shell script.<br />The first line of the "
+#~ "script must be &#34;#!/bin/sh&#34; without quotes.<br />Lines beginning "
+#~ "with # are comments and are not executed.<br />Put your custom mwan3 "
+#~ "action here, they will<br />be executed with each netifd hotplug "
+#~ "interface event<br />on interfaces for which mwan3 is enabled.<br /><br /"
+#~ ">There are three main environment variables that are passed to this "
+#~ "script.<br /><br />$ACTION Either \"ifup\" or \"ifdown\"<br />$INTERFACE "
+#~ "Name of the interface which went up or down (e.g. \"wan\" or \"wwan"
+#~ "\")<br />$DEVICE Physical device name which interface went up or down (e."
+#~ "g. \"eth0\" or \"wwan0\")<br /><br />"
+#~ msgstr ""
+#~ "這裡允許您修改“/etc/mwan3.user”的內容。<br />該檔案在 sysupgrade 期間也會"
+#~ "保留。<br /><br />注意:<br />該檔案會作為 shell 指令碼解釋。<br />指令碼"
+#~ "的第一行必須是&#34;#!/bin/sh&#34;,不帶引號。<br />以#開頭的行是註釋,不會"
+#~ "執行。<br />將您的自定義 mwan3 動作放在這裡,他們將<br />在啟用 mwan3 的介"
+#~ "面上<br />在 netifd hotplug 介面事件時執行。<br /><br />有三個主要的環境變"
+#~ "數傳遞給這個腳本。<br /><br />$ACTION “ifup”或“ifdown”<br />$INTERFACE 啟"
+#~ "動或停止的介面名(例如“wan”或“wwan”)<br />$DEVICE 啟動或停止介面的物理裝"
+#~ "置名(例如“eth0”或“wwan0”)<br /><br />"
+
 #~ msgid "Currently Configured Interfaces"
 #~ msgstr "當前配置的介面"
 
index 229f3d6..c5fb2b2 100644 (file)
@@ -84,11 +84,11 @@ function action_json()
        local jsonreq4
        local jsonreq6
 
-       local v4_port = uci:get("olsrd", "olsrd_jsoninfo", "port") or 9090
-       local v6_port = uci:get("olsrd6", "olsrd_jsoninfo", "port") or 9090
+       local v4_port = tonumber(uci:get("olsrd", "olsrd_jsoninfo", "port") or "") or 9090
+       local v6_port = tonumber(uci:get("olsrd6", "olsrd_jsoninfo", "port") or "") or 9090
 
-       jsonreq4 = utl.exec("(echo /status | nc 127.0.0.1 " .. v4_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null" )
-       jsonreq6 = utl.exec("(echo /status | nc ::1 " .. v6_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null")
+       jsonreq4 = utl.exec("(echo /status | nc 127.0.0.1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" % v4_port)
+       jsonreq6 = utl.exec("(echo /status | nc ::1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" % v6_port)
        http.prepare_content("application/json")
        if not jsonreq4 or jsonreq4 == "" then
                jsonreq4 = "{}"
@@ -150,7 +150,7 @@ function action_neigh(json)
        for _, dev in ipairs(devices) do
                for _, net in ipairs(dev:get_wifinets()) do
                        local radio = net:get_device()
-                       assoclist[#assoclist+1] = {} 
+                       assoclist[#assoclist+1] = {}
                        assoclist[#assoclist]['ifname'] = net:ifname()
                        assoclist[#assoclist]['network'] = net:network()[1]
                        assoclist[#assoclist]['device'] = radio and radio:name() or nil
@@ -165,7 +165,7 @@ function action_neigh(json)
                local mac = ""
                local ip
                local neihgt = {}
-               
+
                if resolve == "1" then
                        hostname = nixio.getnameinfo(v.remoteIP, nil, 100)
                        if hostname then
@@ -350,11 +350,11 @@ function fetch_jsoninfo(otable)
        local IpVersion = uci:get_first("olsrd", "olsrd","IpVersion")
        local jsonreq4 = ""
        local jsonreq6 = ""
-       local v4_port = uci:get("olsrd", "olsrd_jsoninfo", "port") or 9090
-       local v6_port = uci:get("olsrd6", "olsrd_jsoninfo", "port") or 9090
+       local v4_port = tonumber(uci:get("olsrd", "olsrd_jsoninfo", "port") or "") or 9090
+       local v6_port = tonumber(uci:get("olsrd6", "olsrd_jsoninfo", "port") or "") or 9090
 
-       jsonreq4 = utl.exec("(echo /" .. otable .. " | nc 127.0.0.1 " .. v4_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null")
-       jsonreq6 = utl.exec("(echo /" .. otable .. " | nc ::1 " .. v6_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null")
+       jsonreq4 = utl.exec("(echo /%s | nc 127.0.0.1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" %{ otable, v4_port })
+       jsonreq6 = utl.exec("(echo /%s | nc ::1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" %{ otable, v6_port })
        local jsondata4 = {}
        local jsondata6 = {}
        local data4 = {}
index 719145b..ccad531 100644 (file)
@@ -26,9 +26,9 @@ uci:foreach( "openvpn_recipes", "openvpn_recipe",
 )
 
 function s.getPID(section) -- Universal function which returns valid pid # or nil
-       local pid = sys.exec("%s | grep -w %s | grep openvpn | grep -v grep | awk '{print $1}'" % { psstring,section} )
-       if pid and #pid > 0 and tonumber(pid) ~= nil then
-               return tonumber(pid)
+       local pid = sys.exec("%s | grep -w [o]penvpn(%s)" % { psstring, section })
+       if pid and #pid > 0 then
+               return tonumber(pid:match("^%d+"))
        else
                return nil
        end
index b4fdbd5..af7a3a3 100644 (file)
@@ -9,7 +9,7 @@ function index()
        entry({"admin", "services", "splash", "splashtext" }, form("splash/splashtext"), _("Splashtext"), 10)
 
        local e
-       
+
        e = node("splash")
        e.target = call("action_dispatch")
 
@@ -82,7 +82,7 @@ function action_activate()
                        end
                end)
 
-               if blacklisted then     
+               if blacklisted then
                        luci.http.redirect(luci.dispatcher.build_url("splash" ,"blocked"))
                else
                        local id = tostring(mac):gsub(':', ''):lower()
@@ -106,7 +106,7 @@ function action_status_admin()
        local uci = luci.model.uci.cursor_state()
        local macs = luci.http.formvaluetable("save")
 
-       local changes = { 
+       local changes = {
                whitelist = { },
                blacklist = { },
                lease     = { },
@@ -129,22 +129,22 @@ function action_status_admin()
 
        if #changes.whitelist > 0 then
                os.execute("luci-splash whitelist %s >/dev/null"
-                       % table.concat(changes.whitelist))
+                       % util.shellquote(table.concat(changes.whitelist)))
        end
 
        if #changes.blacklist > 0 then
                os.execute("luci-splash blacklist %s >/dev/null"
-                       % table.concat(changes.blacklist))
+                       % util.shellquote(table.concat(changes.blacklist)))
        end
 
        if #changes.lease > 0 then
                os.execute("luci-splash lease %s >/dev/null"
-                       % table.concat(changes.lease))
+                       % util.shellquote(table.concat(changes.lease)))
        end
 
        if #changes.remove > 0 then
                os.execute("luci-splash remove %s >/dev/null"
-                       % table.concat(changes.remove))
+                       % util.shellquote(table.concat(changes.remove)))
        end
 
        luci.template.render("admin_status/splash", { is_admin = true })
index 2870dbe..9ec9f3a 100755 (executable)
@@ -36,6 +36,10 @@ function call(cmd)
        os.execute(cmd)
 end
 
+function esc(str)
+       return utl.shellquote(str)
+end
+
 
 function lock()
        call("lock /var/run/luci_splash.lock")
@@ -84,14 +88,14 @@ end
 
 function get_physdev(interface)
        local dev
-       dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME '" ..  interface .. "'; echo $IFNAME"))
+       dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME %s; echo $IFNAME" % esc(interface)))
        return dev
 end
 
 
 
 function get_filter_handle(parent, direction, device, mac)
-       local input = utl.split(sys.exec('/usr/sbin/tc filter show dev ' .. device .. ' parent ' .. parent) or {})
+       local input = utl.split(sys.exec('/usr/sbin/tc filter show dev %s parent %s' %{ esc(device), esc(parent) }) or {})
        local tbl = {}
        local handle
        for k, v in pairs(input) do
@@ -264,7 +268,7 @@ function main(argv)
                                elseif whitelist_macs[mac] then
                                        print("Removing %s from whitelist" % mac)
                                        remove_whitelist(mac)
-                                       whitelist_macs[mac] = nil                                       
+                                       whitelist_macs[mac] = nil
                                elseif blacklist_macs[mac] then
                                        print("Removing %s from blacklist" % mac)
                                        remove_blacklist(mac)
@@ -295,7 +299,7 @@ function main(argv)
                print("\n  luci-splash remove <MAC-or-IP>\n    Remove given address from the lease-, black- or whitelist")
                print("")
 
-               os.exit(1)      
+               os.exit(1)
        end
 end
 
@@ -338,8 +342,8 @@ function ipt_delete_all(args, comp, off)
                        off[r.table] = off[r.table] or { }
                        off[r.table][r.chain] = off[r.table][r.chain] or 0
 
-                       exec("iptables -t %q -D %q %d 2>/dev/null"
-                               %{ r.table, r.chain, r.index - off[r.table][r.chain] })
+                       exec("iptables -t %s -D %s %d 2>/dev/null"
+                               %{ esc(r.table), esc(r.chain), r.index - off[r.table][r.chain] })
 
                        off[r.table][r.chain] = off[r.table][r.chain] + 1
                end
@@ -353,8 +357,8 @@ function ipt6_delete_all(args, comp, off)
                        off[r.table] = off[r.table] or { }
                        off[r.table][r.chain] = off[r.table][r.chain] or 0
 
-                       exec("ip6tables -t %q -D %q %d 2>/dev/null"
-                               %{ r.table, r.chain, r.index - off[r.table][r.chain] })
+                       exec("ip6tables -t %s -D %s %d 2>/dev/null"
+                               %{ esc(r.table), esc(r.chain), r.index - off[r.table][r.chain] })
 
                        off[r.table][r.chain] = off[r.table][r.chain] + 1
                end
@@ -460,13 +464,13 @@ function remove_whitelist_tc(mac)
                        end
                        local handle = get_filter_handle('ffff:', 'src', device, mac)
                        if handle then
-                               exec('tc filter del dev "%s" parent ffff: protocol ip prio 1 handle %s u32' % { device, handle })
+                               exec('tc filter del dev %s parent ffff: protocol ip prio 1 handle %s u32' % { esc(device), esc(handle) })
                        else
                                print('Warning! Could not get a handle for %s parent :ffff on interface %s' % { mac, device })
                        end
                        local handle = get_filter_handle('1:', 'dest', device, mac)
                        if handle then
-                               exec('tc filter del dev "%s" parent 1:0 protocol ip prio 1 handle %s u32' % { device, handle })
+                               exec('tc filter del dev %s parent 1:0 protocol ip prio 1 handle %s u32' % { esc(device), esc(handle) })
                        else
                                print('Warning! Could not get a handle for %s parent 1:0 on interface %s' % { mac, device })
                        end
@@ -492,37 +496,37 @@ function add_lease_rule(mac, ipaddr, device)
                id = get_id(ipaddr)
        end
 
-       exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j RETURN" % mac)
+       exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %s -j RETURN" % esc(mac))
 
        -- Mark incoming packets to a splashed host
        -- for ipv4 - by iptables and destination
        if id and device then
-               exec("iptables -t mangle -I luci_splash_mark_in -d %q -j MARK --set-mark 0x1%s -m comment --comment %s" % {ipaddr, id, mac:upper()})
+               exec("iptables -t mangle -I luci_splash_mark_in -d %s -j MARK --set-mark 0x1%s -m comment --comment %s" % { esc(ipaddr), esc(id), esc(mac:upper())})
        end
 
        --for ipv6: need to use the mac here
 
        if has_ipv6 then
-               exec("ip6tables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j MARK --set-mark 79" % mac)
+               exec("ip6tables -t mangle -I luci_splash_mark_out -m mac --mac-source %s -j MARK --set-mark 79" % esc(mac))
                if id and device and tonumber(limit_down) then
-                       exec("tc filter add dev %s parent 1:0 protocol ipv6 prio 1 u32 match ether dst %s classid 1:%s" % {device, mac:lower(), id})
+                       exec("tc filter add dev %s parent 1:0 protocol ipv6 prio 1 u32 match ether dst %s classid 1:%s" % { esc(device), esc(mac:lower()), esc(id) })
                end
        end
 
 
        if device and tonumber(limit_up) > 0 then
-               exec('tc filter add dev "%s" parent ffff: protocol all prio 2 u32 match ether src %s police rate %skbit mtu 6k burst 6k drop' % {device, mac, limit_up})
+               exec('tc filter add dev %s parent ffff: protocol all prio 2 u32 match ether src %s police rate %skbit mtu 6k burst 6k drop' % { esc(device), esc(mac), esc(limit_up) })
        end
 
        if id and device and tonumber(limit_down) > 0 then
-               exec("tc class add dev %s parent 1: classid 1:0x%s htb rate %skbit" % { device, id, limit_down })
-               exec("tc qdisc add dev %s parent 1:%s sfq perturb 10" % { device, id })
+               exec("tc class add dev %s parent 1: classid 1:0x%s htb rate %skbit" % { esc(device), esc(id), esc(limit_down) })
+               exec("tc qdisc add dev %s parent 1:%s sfq perturb 10" % { esc(device), esc(id) })
        end
 
-       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
-       exec("iptables -t nat    -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac)
+       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
+       exec("iptables -t nat    -I luci_splash_leases -m mac --mac-source %s -j RETURN" % esc(mac))
        if has_ipv6 then
-               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
+               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
        end
 end
 
@@ -548,32 +552,32 @@ function remove_lease_rule(mac, ipaddr, device, limit_up, limit_down)
        if device and tonumber(limit_up) > 0 then
                local handle = get_filter_handle('ffff:', 'src', device, mac)
                if handle then
-                       exec('tc filter del dev "%s" parent ffff: protocol all prio 2 handle %s u32 police rate %skbit mtu 6k burst 6k drop' % {device, handle, limit_up})
+                       exec('tc filter del dev %s parent ffff: protocol all prio 2 handle %s u32 police rate %skbit mtu 6k burst 6k drop' % { esc(device), esc(handle), esc(limit_up) })
                else
                        print('Warning! Could not get a handle for %s parent :ffff on interface %s' % { mac, device })
                end
        end
        -- remove clients class
        if device and id then
-               exec('tc class del dev "%s" classid 1:%s' % {device, id})
-               exec('tc filter del dev "%s" parent 1:0 prio 1' % device) -- ipv6 rule
-               --exec('tc qdisc del dev "%s" parent 1:%s sfq perturb 10' % { device, id })
+               exec('tc class del dev %s classid 1:%s' % { esc(device), esc(id) })
+               exec('tc filter del dev %s parent 1:0 prio 1' % esc(device)) -- ipv6 rule
+               --exec('tc qdisc del dev %s parent 1:%s sfq perturb 10' % { esc(device), esc(id) })
        end
 end
 
 
 -- Add whitelist rules
 function add_whitelist_rule(mac)
-       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
-       exec("iptables -t nat    -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac)
+       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
+       exec("iptables -t nat    -I luci_splash_leases -m mac --mac-source %s -j RETURN" % esc(mac))
        if has_ipv6 then
-               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac)
+               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac))
        end
         uci:foreach("luci_splash", "iface", function(s)
                local device = get_physdev(s['.name'])
                if device and device ~= "" then
-                       exec('tc filter add dev "%s" parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { device, mac })
-                       exec('tc filter add dev "%s" parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { device, mac })
+                       exec('tc filter add dev %s parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { esc(device), esc(mac) })
+                       exec('tc filter add dev %s parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { esc(device), esc(mac) })
                end
         end)
 end
@@ -581,9 +585,9 @@ end
 
 -- Add blacklist rules
 function add_blacklist_rule(mac)
-       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac)
+       exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j DROP" % esc(mac))
        if has_ipv6 then
-               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac)
+               exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j DROP" % esc(mac))
        end
 end
 
@@ -596,15 +600,15 @@ function sync()
 
        -- Current leases in state files
        local leases = uci:get_all("luci_splash_leases")
-       
+
        -- Convert leasetime to seconds
        local leasetime = tonumber(uci:get("luci_splash", "general", "leasetime")) * 3600
-       
+
        -- Clean state file
        uci:load("luci_splash_leases")
        uci:revert("luci_splash_leases")
 
-        
+
        local blackwhitelist = uci:get_all("luci_splash")
        local whitelist_total = 0
        local whitelist_online = 0
@@ -628,7 +632,7 @@ function sync()
                                 end
 
                                -- Rewrite state
-                               uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), {             
+                               uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), {
                                        mac    = v.mac,
                                        ipaddr = v.ipaddr,
                                        device = v.device,
@@ -639,7 +643,7 @@ function sync()
                        end
                end
        end
-       
+
        -- Whitelist, Blacklist
        for _, s in utl.spairs(blackwhitelist,
                function(a,b) return blackwhitelist[a][".type"] > blackwhitelist[b][".type"] end
@@ -666,7 +670,7 @@ function sync()
 
        -- ToDo:
         -- include a new field "leases_online" in stats to differ between active clients and leases:
-        -- update_stats(leasecount, leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) later: 
+        -- update_stats(leasecount, leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) later:
         update_stats(leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total)
 
        uci:save("luci_splash_leases")
index e29a2e1..47e1696 100644 (file)
@@ -87,7 +87,7 @@ function Graph._rrdtool( self, def, rrd )
        fs.mkdirr( dir )
 
        -- construct commandline
-       local cmdline = "rrdtool graph"
+       local cmdline = { "rrdtool", "graph" }
 
        -- copy default arguments to def stack
        for i, opt in ipairs(self.args) do
@@ -102,15 +102,11 @@ function Graph._rrdtool( self, def, rrd )
                        opt = opt:gsub( "{file}", rrd )
                end
 
-               if opt:match("[^%w]") then
-                       cmdline = cmdline .. " '" .. opt .. "'"
-               else
-                       cmdline = cmdline .. " " .. opt
-               end
+               cmdline[#cmdline+1] = luci.util.shellquote(opt)
        end
 
        -- execute rrdtool
-       local rrdtool = io.popen( cmdline )
+       local rrdtool = io.popen(table.concat(cmdline, " "))
        rrdtool:close()
 end
 
index d43a887..2ba9ddd 100644 (file)
@@ -13,7 +13,11 @@ if luci.http.formvalue("frame") == "1" then
                end)
 
        local data = false
-       local wget = io.popen("wget -qO- http://%s:%s" % { addr, port })
+       local wget = io.popen("wget -qO- http://%s:%s" %{
+               luci.util.shellquote(addr),
+               luci.util.shellquote(port)
+       })
+
        if wget then
                while true do
                        local l = wget:read("*l")
@@ -30,7 +34,10 @@ if luci.http.formvalue("frame") == "1" then
 
        if not data then
                luci.http.write(translate("Failed to retrieve statistics from url:"))
-               luci.http.write(" http://%s:%s" % { addr, port })
+               luci.http.write(" http://%s:%s" %{
+                       luci.util.pcdata(addr),
+                       luci.util.pcdata(port)
+               })
        end
 
        return
@@ -43,7 +50,7 @@ end
 <div class="cbi-map">
        <h2 name="content"><%:Tinyproxy Status%></h2>
        <div class="cbi-section">
-               <iframe src="<%=REQUESTURL%>?frame=1" style="width:100%; height:350px; border:none"></iframe>
+               <iframe src="<%=REQUEST_URI%>?frame=1" style="width:100%; height:350px; border:none"></iframe>
        </div>
 </div>
 
index 30f34ef..83cf97f 100644 (file)
@@ -12,9 +12,6 @@ msgstr ""
 "Plural-Forms: nplurals=1; plural=0;\n"
 "Language: ja\n"
 
-msgid "AP QR-Codes"
-msgstr "AP QR-コード"
-
 msgid "Actions"
 msgstr "操作"
 
@@ -65,6 +62,12 @@ msgid ""
 msgstr ""
 "トラベル ルーター機能を有効化するための、 Travelmate パッケージの設定です。"
 
+msgid ""
+"Connect your Android or iOS devices to your router's WiFi using the shown QR "
+"code."
+msgstr ""
+"Android や iOS デバイスを、表示される QR コードを使用して WiFi に接続します。"
+
 msgid "Connection Limit"
 msgstr "接続制限"
 
@@ -246,6 +249,9 @@ msgstr ""
 "ンクを追加することができます。現在使用されているアップリンクは、青色で強調さ"
 "れます。"
 
+msgid "QR-Codes"
+msgstr "QR-コード"
+
 msgid "Radio selection"
 msgstr "無線の選択"
 
@@ -359,6 +365,9 @@ msgstr "アップリンク SSID"
 msgid "Uplink interface"
 msgstr "アップリンク インターフェース"
 
+msgid "View AP QR-Codes"
+msgstr "AP QR-コードを確認"
+
 msgid "View Logfile"
 msgstr "ログファイルの確認"
 
index 7cb6ac0..843340b 100644 (file)
@@ -12,9 +12,6 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
 "Language: pt_BR\n"
 
-msgid "AP QR-Codes"
-msgstr ""
-
 msgid "Actions"
 msgstr ""
 
@@ -62,6 +59,11 @@ msgid ""
 "functionality."
 msgstr ""
 
+msgid ""
+"Connect your Android or iOS devices to your router's WiFi using the shown QR "
+"code."
+msgstr ""
+
 msgid "Connection Limit"
 msgstr ""
 
@@ -227,6 +229,9 @@ msgid ""
 "one. The currently used uplink is emphasized in blue."
 msgstr ""
 
+msgid "QR-Codes"
+msgstr ""
+
 msgid "Radio selection"
 msgstr ""
 
@@ -330,6 +335,9 @@ msgstr ""
 msgid "Uplink interface"
 msgstr ""
 
+msgid "View AP QR-Codes"
+msgstr ""
+
 msgid "View Logfile"
 msgstr ""
 
index 0b04e27..202f5c8 100644 (file)
@@ -15,9 +15,6 @@ msgstr ""
 "Project-Info: Это технический перевод, не дословный. Главное-удобный русский "
 "интерфейс, все проверялось в графическом режиме, совместим с другими apps\n"
 
-msgid "AP QR-Codes"
-msgstr ""
-
 msgid "Actions"
 msgstr "Действия"
 
@@ -65,6 +62,11 @@ msgid ""
 "functionality."
 msgstr "Настройка утилиты TravelMate - помощника путешественника. "
 
+msgid ""
+"Connect your Android or iOS devices to your router's WiFi using the shown QR "
+"code."
+msgstr ""
+
 msgid "Connection Limit"
 msgstr "Ограничение соединений"
 
@@ -244,6 +246,9 @@ msgstr ""
 "упорядочивать существующий список внешних сетей или выполнять их поиск.<br /"
 ">Используемое сетевое соединение выделено синим цветом."
 
+msgid "QR-Codes"
+msgstr ""
+
 msgid "Radio selection"
 msgstr "Выбор Wi-Fi устройства"
 
@@ -359,6 +364,9 @@ msgstr "SSID внешней сети"
 msgid "Uplink interface"
 msgstr "Интерфейс внешней сети"
 
+msgid "View AP QR-Codes"
+msgstr ""
+
 msgid "View Logfile"
 msgstr "Показать системный журнал"
 
index e27c61a..32ba788 100644 (file)
@@ -1,9 +1,6 @@
 msgid ""
 msgstr "Content-Type: text/plain; charset=UTF-8"
 
-msgid "AP QR-Codes"
-msgstr ""
-
 msgid "Actions"
 msgstr ""
 
@@ -51,6 +48,11 @@ msgid ""
 "functionality."
 msgstr ""
 
+msgid ""
+"Connect your Android or iOS devices to your router's WiFi using the shown QR "
+"code."
+msgstr ""
+
 msgid "Connection Limit"
 msgstr ""
 
@@ -216,6 +218,9 @@ msgid ""
 "one. The currently used uplink is emphasized in blue."
 msgstr ""
 
+msgid "QR-Codes"
+msgstr ""
+
 msgid "Radio selection"
 msgstr ""
 
@@ -319,6 +324,9 @@ msgstr ""
 msgid "Uplink interface"
 msgstr ""
 
+msgid "View AP QR-Codes"
+msgstr ""
+
 msgid "View Logfile"
 msgstr ""
 
index e485708..95a0ef4 100644 (file)
@@ -21,7 +21,7 @@ end
 function act_status()
        local uci = luci.model.uci.cursor()
        local lease_file = uci:get("upnpd", "config", "upnp_lease_file")
-       
+
        local ipt = io.popen("iptables --line-numbers -t nat -xnvL MINIUPNPD 2>/dev/null")
        if ipt then
                local upnpf = lease_file and io.open(lease_file, "r")
@@ -39,7 +39,7 @@ function act_status()
                                        num     = tonumber(num)
                                        extport = tonumber(extport)
                                        intport = tonumber(intport)
-                                       
+
                                        if upnpf then
                                                local uln = upnpf:read("*l")
                                                if uln then descr = uln:match(string.format("^%s:%d:%s:%d:%%d*:(.*)$", proto:upper(), extport, intaddr, intport)) end
@@ -76,7 +76,7 @@ function act_delete(num)
 
                local lease_file = uci:get("upnpd", "config", "upnp_lease_file")
                if lease_file and nixio.fs.access(lease_file) then
-                       luci.sys.call("sed -i -e '%dd' %q" %{ idx, lease_file })
+                       luci.sys.call("sed -i -e '%dd' %s" %{ idx, luci.util.shellquote(lease_file) })
                end
 
                luci.http.status(200, "OK")
index 2b8d9ff..42d7d24 100644 (file)
@@ -21,12 +21,13 @@ style = (style and #style > 0) and style or "s"
 -- render image
 --
 if iface then
-       style = style:gsub("[^%w]", "")
-       iface = iface:gsub("[^%w%.%-%_]", "")
-
        luci.http.prepare_content("image/png")
 
-       local png = io.popen("vnstati -i '%s' '-%s' -o -" % { iface, style })
+       local png = io.popen("vnstati -i %s -%s -o -" %{
+               utl.shellquote(iface),
+               utl.shellquote(style)
+       })
+
        luci.http.write(png:read("*a"))
        png:close()
 
@@ -89,7 +90,7 @@ dbdir = dbdir or "/var/lib/vnstat"
 <%
        end
      end
-   end 
+   end
 %>
 
 <% if empty then %>
index d40dde0..43b87dd 100644 (file)
@@ -1,6 +1,7 @@
 -- Copyright 2010 Jo-Philipp Wich <jow@openwrt.org>
 -- Licensed to the public under the Apache License 2.0.
 
+local utl = require "luci.util"
 local sys = require "luci.sys"
 local ipc = require "luci.ip"
 local fs  = require "nixio.fs"
@@ -69,8 +70,8 @@ function host.write(self, s, val)
                if util == "/usr/bin/etherwake" then
                        local iface = luci.http.formvalue("cbid.wol.1.iface")
                        local broadcast = luci.http.formvalue("cbid.wol.1.broadcast")
-                       cmd = "%s -D%s %s %q" %{
-                               util, (iface ~= "" and " -i %q" % iface or ""),
+                       cmd = "%s -D%s %s %q 2>&1" %{
+                               util, (iface ~= "" and " -i %s" % utl.shellquote(iface) or ""),
                                (broadcast == "1" and " -b" or ""), mac
                        }
                else
@@ -78,7 +79,7 @@ function host.write(self, s, val)
                end
 
                local msg = "<p><strong>%s</strong><br /><br /><code>%s<br /><br />" %{
-                       translate("Starting WoL utility:"), cmd
+                       translate("Starting WoL utility:"), utl.pcdata(cmd)
                }
 
                local p = io.popen(cmd .. " 2>&1")
index d40ec34..6c35372 100644 (file)
@@ -218,12 +218,13 @@ var cbi_validators = {
                        ((ipv4only == 1) && cbi_validators.ip4addr.apply(this));
        },
 
-       'hostname': function()
+       'hostname': function(strict)
        {
                if (this.length <= 253)
-                       return (this.match(/^[a-zA-Z0-9]+$/) != null ||
+                       return (this.match(/^[a-zA-Z0-9_]+$/) != null ||
                                (this.match(/^[a-zA-Z0-9_][a-zA-Z0-9_\-.]*[a-zA-Z0-9]$/) &&
-                                this.match(/[^0-9.]/)));
+                                this.match(/[^0-9.]/))) &&
+                              (!strict || !this.match(/^_/));
 
                return false;
        },
index 55cdf8a..99113e0 100644 (file)
@@ -199,13 +199,13 @@ function macaddr(val)
        return ip.checkmac(val) and true or false
 end
 
-function hostname(val)
+function hostname(val, strict)
        if val and (#val < 254) and (
           val:match("^[a-zA-Z_]+$") or
           (val:match("^[a-zA-Z0-9_][a-zA-Z0-9_%-%.]*[a-zA-Z0-9]$") and
            val:match("[^0-9%.]"))
        ) then
-               return true
+               return (not strict or not val:match("^_"))
        end
        return false
 end
index 16b3254..c93fd78 100644 (file)
@@ -346,15 +346,23 @@ function dispatch(request)
                   ifattr      = function(...) return _ifattr(...) end;
                   attr        = function(...) return _ifattr(true, ...) end;
                   url         = build_url;
-               }, {__index=function(table, key)
+               }, {__index=function(tbl, key)
                        if key == "controller" then
                                return build_url()
                        elseif key == "REQUEST_URI" then
                                return build_url(unpack(ctx.requestpath))
+                       elseif key == "FULL_REQUEST_URI" then
+                               local url = { http.getenv("SCRIPT_NAME"), http.getenv("PATH_INFO") }
+                               local query = http.getenv("QUERY_STRING")
+                               if query and #query > 0 then
+                                       url[#url+1] = "?"
+                                       url[#url+1] = query
+                               end
+                               return table.concat(url, "")
                        elseif key == "token" then
                                return ctx.authtoken
                        else
-                               return rawget(table, key) or _G[key]
+                               return rawget(tbl, key) or _G[key]
                        end
                end})
        end
@@ -884,7 +892,7 @@ end
 function cbi(model, config)
        return {
                type = "cbi",
-               post = { ["cbi.submit"] = "1" },
+               post = { ["cbi.submit"] = true },
                config = config,
                model = model,
                target = _cbi
@@ -930,7 +938,7 @@ end
 function form(model)
        return {
                type = "cbi",
-               post = { ["cbi.submit"] = "1" },
+               post = { ["cbi.submit"] = true },
                model = model,
                target = _form
        }
index e653b03..e27ea52 100644 (file)
@@ -20,12 +20,14 @@ module "luci.model.ipkg"
 
 -- Internal action function
 local function _action(cmd, ...)
-       local pkg = ""
+       local cmdline = { ipkg, cmd }
+
+       local k, v
        for k, v in pairs({...}) do
-               pkg = pkg .. " '" .. v:gsub("'", "") .. "'"
+               cmdline[#cmdline+1] = util.shellquote(v)
        end
 
-       local c = "%s %s %s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" %{ ipkg, cmd, pkg }
+       local c = "%s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" % table.concat(cmdline, " ")
        local r = os.execute(c)
        local e = fs.readfile("/tmp/opkg.stderr")
        local o = fs.readfile("/tmp/opkg.stdout")
@@ -74,17 +76,17 @@ local function _parselist(rawdata)
 end
 
 -- Internal lookup function
-local function _lookup(act, pkg)
-       local cmd = ipkg .. " " .. act
+local function _lookup(cmd, pkg)
+       local cmdline = { ipkg, cmd }
        if pkg then
-               cmd = cmd .. " '" .. pkg:gsub("'", "") .. "'"
+               cmdline[#cmdline+1] = util.shellquote(pkg)
        end
 
        -- OPKG sometimes kills the whole machine because it sucks
        -- Therefore we have to use a sucky approach too and use
        -- tmpfiles instead of directly reading the output
        local tmpfile = os.tmpname()
-       os.execute(cmd .. (" >%s 2>/dev/null" % tmpfile))
+       os.execute("%s >%s 2>/dev/null" %{ table.concat(cmdline, " "), tmpfile })
 
        local data = _parselist(io.lines(tmpfile))
        os.remove(tmpfile)
@@ -123,9 +125,12 @@ end
 
 -- List helper
 local function _list(action, pat, cb)
-       local fd = io.popen(ipkg .. " " .. action ..
-               (pat and (" '%s'" % pat:gsub("'", "")) or ""))
+       local cmdline = { ipkg, action }
+       if pat then
+               cmdline[#cmdline+1] = util.shellquote(pat)
+       end
 
+       local fd = io.popen(table.concat(cmdline, " "))
        if fd then
                local name, version, sz, desc
                while true do
index 056fc67..dfe818b 100644 (file)
@@ -629,7 +629,7 @@ function get_interface(self, i)
        if _interfaces[i] or _wifi_iface(i) then
                return interface(i)
        else
-               local netid = _wifi_netid_by_netname(i)
+               local netid = _wifi_netid_by_sid(i)
                return netid and interface(netid)
        end
 end
index 577c6cd..bbd9b4c 100644 (file)
@@ -2,13 +2,12 @@
 -- Licensed to the public under the Apache License 2.0.
 
 local os    = require "os"
-local uci   = require "uci"
 local util  = require "luci.util"
 local table = require "table"
 
 
 local setmetatable, rawget, rawset = setmetatable, rawget, rawset
-local require, getmetatable = require, getmetatable
+local require, getmetatable, assert = require, getmetatable, assert
 local error, pairs, ipairs = error, pairs, ipairs
 local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack
 
@@ -20,151 +19,410 @@ local type, tostring, tonumber, unpack = type, tostring, tonumber, unpack
 -- reloaded.
 module "luci.model.uci"
 
-cursor = uci.cursor
-
-APIVERSION = uci.APIVERSION
+local ERRSTR = {
+       "Invalid command",
+       "Invalid argument",
+       "Method not found",
+       "Entry not found",
+       "No data",
+       "Permission denied",
+       "Timeout",
+       "Not supported",
+       "Unknown error",
+       "Connection failed"
+}
+
+
+function cursor()
+       return _M
+end
 
 function cursor_state()
-       return cursor(nil, "/var/state")
+       return _M
 end
 
+function substate(self)
+       return self
+end
 
-inst = cursor()
-inst_state = cursor_state()
 
-local Cursor = getmetatable(inst)
+function get_confdir(self)
+       return "/etc/config"
+end
 
-function Cursor.apply(self, configlist, command)
-       configlist = self:_affected(configlist)
-       if command then
-               return { "/sbin/luci-reload", unpack(configlist) }
-       else
-               return os.execute("/sbin/luci-reload %s >/dev/null 2>&1"
-                       % table.concat(configlist, " "))
-       end
+function get_savedir(self)
+       return "/tmp/.uci"
+end
+
+function set_confdir(self, directory)
+       return false
 end
 
+function set_savedir(self, directory)
+       return false
+end
 
--- returns a boolean whether to delete the current section (optional)
-function Cursor.delete_all(self, config, stype, comparator)
-       local del = {}
 
-       if type(comparator) == "table" then
-               local tbl = comparator
-               comparator = function(section)
-                       for k, v in pairs(tbl) do
-                               if section[k] ~= v then
-                                       return false
+function load(self, config)
+       return true
+end
+
+function save(self, config)
+       return true
+end
+
+function unload(self, config)
+       return true
+end
+
+
+function changes(self, config)
+       local rv = util.ubus("uci", "changes", { config = config })
+       local res = {}
+
+       if type(rv) == "table" and type(rv.changes) == "table" then
+               local package, changes
+               for package, changes in pairs(rv.changes) do
+                       res[package] = {}
+
+                       local _, change
+                       for _, change in ipairs(changes) do
+                               local operation, section, option, value = unpack(change)
+                               if option and value and operation ~= "add" then
+                                       res[package][section] = res[package][section] or { }
+
+                                       if operation == "list-add" then
+                                               local v = res[package][section][option]
+                                               if type(v) == "table" then
+                                                       v[#v+1] = value or ""
+                                               elseif v ~= nil then
+                                                       res[package][section][option] = { v, value }
+                                               else
+                                                       res[package][section][option] = { value }
+                                               end
+                                       else
+                                               res[package][section][option] = value or ""
+                                       end
+                               else
+                                       res[package][section] = res[package][section] or {}
+                                       res[package][section][".type"] = option or ""
                                end
                        end
-                       return true
                end
        end
 
-       local function helper (section)
+       return res
+end
+
+
+function revert(self, config)
+       local _, err = util.ubus("uci", "revert", { config = config })
+       return (err == nil), ERRSTR[err]
+end
+
+function commit(self, config)
+       local _, err = util.ubus("uci", "commit", { config = config })
+       return (err == nil), ERRSTR[err]
+end
+
+--[[
+function apply(self, configs, command)
+       local _, config
 
-               if not comparator or comparator(section) then
-                       del[#del+1] = section[".name"]
+       assert(not command, "Apply command not supported anymore")
+
+       if type(configs) == "table" then
+               for _, config in ipairs(configs) do
+                       util.ubus("service", "event", {
+                               type = "config.change",
+                               data = { package = config }
+                       })
                end
        end
+end
+]]
+
+
+function foreach(self, config, stype, callback)
+       if type(callback) == "function" then
+               local rv, err = util.ubus("uci", "get", {
+                       config = config,
+                       type   = stype
+               })
+
+               if type(rv) == "table" and type(rv.values) == "table" then
+                       local sections = { }
+                       local res = false
+                       local index = 1
+
+                       local _, section
+                       for _, section in pairs(rv.values) do
+                               section[".index"] = section[".index"] or index
+                               sections[index] = section
+                               index = index + 1
+                       end
 
-       self:foreach(config, stype, helper)
+                       table.sort(sections, function(a, b)
+                               return a[".index"] < b[".index"]
+                       end)
 
-       for i, j in ipairs(del) do
-               self:delete(config, j)
+                       for _, section in ipairs(sections) do
+                               local continue = callback(section)
+                               res = true
+                               if continue == false then
+                                       break
+                               end
+                       end
+                       return res
+               else
+                       return false, ERRSTR[err] or "No data"
+               end
+       else
+               return false, "Invalid argument"
        end
 end
 
-function Cursor.section(self, config, type, name, values)
-       local stat = true
-       if name then
-               stat = self:set(config, name, type)
+function get(self, config, section, option)
+       if section == nil then
+               return nil
+       elseif type(option) == "string" and option:byte(1) ~= 46 then
+               local rv, err = util.ubus("uci", "get", {
+                       config  = config,
+                       section = section,
+                       option  = option
+               })
+
+               if type(rv) == "table" then
+                       return rv.value or nil
+               elseif err then
+                       return false, ERRSTR[err]
+               else
+                       return nil
+               end
+       elseif option == nil then
+               local values = self:get_all(config, section)
+               if values then
+                       return values[".type"], values[".name"]
+               else
+                       return nil
+               end
        else
-               name = self:add(config, type)
-               stat = name and true
+               return false, "Invalid argument"
        end
+end
+
+function get_all(self, config, section)
+       local rv, err = util.ubus("uci", "get", {
+               config  = config,
+               section = section
+       })
 
-       if stat and values then
-               stat = self:tset(config, name, values)
+       if type(rv) == "table" and type(rv.values) == "table" then
+               return rv.values
+       elseif err then
+               return false, ERRSTR[err]
+       else
+               return nil
        end
+end
 
-       return stat and name
+function get_bool(self, ...)
+       local val = self:get(...)
+       return (val == "1" or val == "true" or val == "yes" or val == "on")
 end
 
-function Cursor.tset(self, config, section, values)
-       local stat = true
-       for k, v in pairs(values) do
-               if k:sub(1, 1) ~= "." then
-                       stat = stat and self:set(config, section, k, v)
+function get_first(self, config, stype, option, default)
+       local rv = default
+
+       self:foreach(conf, stype, function(s)
+               local val = not option and s[".name"] or s[option]
+
+               if type(default) == "number" then
+                       val = tonumber(val)
+               elseif type(default) == "boolean" then
+                       val = (val == "1" or val == "true" or
+                              val == "yes" or val == "on")
                end
-       end
-       return stat
-end
 
-function Cursor.get_bool(self, ...)
-       local val = self:get(...)
-       return ( val == "1" or val == "true" or val == "yes" or val == "on" )
+               if val ~= nil then
+                       rv = val
+                       return false
+               end
+       end)
+
+       return rv
 end
 
-function Cursor.get_list(self, config, section, option)
+function get_list(self, config, section, option)
        if config and section and option then
                local val = self:get(config, section, option)
-               return ( type(val) == "table" and val or { val } )
+               return (type(val) == "table" and val or { val })
        end
-       return {}
+       return { }
 end
 
-function Cursor.get_first(self, conf, stype, opt, def)
-       local rv = def
 
-       self:foreach(conf, stype,
-               function(s)
-                       local val = not opt and s['.name'] or s[opt]
+function section(self, config, stype, name, values)
+       local rv, err = util.ubus("uci", "add", {
+               config = config,
+               type   = stype,
+               name   = name,
+               values = values
+       })
 
-                       if type(def) == "number" then
-                               val = tonumber(val)
-                       elseif type(def) == "boolean" then
-                               val = (val == "1" or val == "true" or
-                                      val == "yes" or val == "on")
+       if type(rv) == "table" then
+               return rv.section
+       elseif err then
+               return false, ERRSTR[err]
+       else
+               return nil
+       end
+end
+
+
+function add(self, config, stype)
+       return self:section(config, stype)
+end
+
+function set(self, config, section, option, value)
+       if value == nil then
+               local sname, err = self:section(config, option, section)
+               return (not not sname), err
+       else
+               local _, err = util.ubus("uci", "set", {
+                       config  = config,
+                       section = section,
+                       values  = { [option] = value }
+               })
+               return (err == nil), ERRSTR[err]
+       end
+end
+
+function set_list(self, config, section, option, value)
+       if section == nil or option == nil then
+               return false
+       elseif value == nil or (type(value) == "table" and #value == 0) then
+               return self:delete(config, section, option)
+       elseif type(value) == "table" then
+               return self:set(config, section, option, value)
+       else
+               return self:set(config, section, option, { value })
+       end
+end
+
+function tset(self, config, section, values)
+       local _, err = util.ubus("uci", "set", {
+               config  = config,
+               section = section,
+               values  = values
+       })
+       return (err == nil), ERRSTR[err]
+end
+
+function reorder(self, config, section, index)
+       local sections
+
+       if type(section) == "string" and type(index) == "number" then
+               local pos = 0
+
+               sections = { }
+
+               self:foreach(config, nil, function(s)
+                       if pos == index then
+                               pos = pos + 1
                        end
 
-                       if val ~= nil then
-                               rv = val
-                               return false
+                       if s[".name"] ~= section then
+                               pos = pos + 1
+                               sections[pos] = s[".name"]
+                       else
+                               sections[index + 1] = section
                        end
                end)
+       elseif type(section) == "table" then
+               sections = section
+       else
+               return false, "Invalid argument"
+       end
 
-       return rv
+       local _, err = util.ubus("uci", "order", {
+               config   = config,
+               sections = sections
+       })
+
+       return (err == nil), ERRSTR[err]
 end
 
-function Cursor.set_list(self, config, section, option, value)
-       if config and section and option then
-               if not value or #value == 0 then
-                       return self:delete(config, section, option)
+
+function delete(self, config, section, option)
+       local _, err = util.ubus("uci", "delete", {
+               config  = config,
+               section = section,
+               option  = option
+       })
+       return (err == nil), ERRSTR[err]
+end
+
+function delete_all(self, config, stype, comparator)
+       local _, err
+       if type(comparator) == "table" then
+               _, err = util.ubus("uci", "delete", {
+                       config = config,
+                       type   = stype,
+                       match  = comparator
+               })
+       elseif type(comparator) == "function" then
+               local rv = util.ubus("uci", "get", {
+                       config = config,
+                       type   = stype
+               })
+
+               if type(rv) == "table" and type(rv.values) == "table" then
+                       local sname, section
+                       for sname, section in pairs(rv.values) do
+                               if comparator(section) then
+                                       _, err = util.ubus("uci", "delete", {
+                                               config  = config,
+                                               section = sname
+                                       })
+                               end
+                       end
                end
-               return self:set(
-                       config, section, option,
-                       ( type(value) == "table" and value or { value } )
-               )
+       elseif comparator == nil then
+               _, err = util.ubus("uci", "delete", {
+                       config  = config,
+                       type    = stype
+               })
+       else
+               return false, "Invalid argument"
        end
-       return false
+
+       return (err == nil), ERRSTR[err]
 end
 
--- Return a list of initscripts affected by configuration changes.
-function Cursor._affected(self, configlist)
-       configlist = type(configlist) == "table" and configlist or {configlist}
 
-       local c = cursor()
-       c:load("ucitrack")
+function apply(self, configlist, command)
+       configlist = self:_affected(configlist)
+       if command then
+               return { "/sbin/luci-reload", unpack(configlist) }
+       else
+               return os.execute("/sbin/luci-reload %s >/dev/null 2>&1"
+                       % util.shellquote(table.concat(configlist, " ")))
+       end
+end
+
+-- Return a list of initscripts affected by configuration changes.
+function _affected(self, configlist)
+       configlist = type(configlist) == "table" and configlist or { configlist }
 
        -- Resolve dependencies
-       local reloadlist = {}
+       local reloadlist = { }
 
        local function _resolve_deps(name)
-               local reload = {name}
-               local deps = {}
+               local reload = { name }
+               local deps = { }
 
-               c:foreach("ucitrack", name,
+               self:foreach("ucitrack", name,
                        function(section)
                                if section.affects then
                                        for i, aff in ipairs(section.affects) do
@@ -173,7 +431,9 @@ function Cursor._affected(self, configlist)
                                end
                        end)
 
+               local i, dep
                for i, dep in ipairs(deps) do
+                       local j, add
                        for j, add in ipairs(_resolve_deps(dep)) do
                                reload[#reload+1] = add
                        end
@@ -183,7 +443,9 @@ function Cursor._affected(self, configlist)
        end
 
        -- Collect initscripts
+       local j, config
        for j, config in ipairs(configlist) do
+               local i, e
                for i, e in ipairs(_resolve_deps(config)) do
                        if not util.contains(reloadlist, e) then
                                reloadlist[#reloadlist+1] = e
@@ -193,44 +455,3 @@ function Cursor._affected(self, configlist)
 
        return reloadlist
 end
-
--- curser, means it the parent unloads or loads configs, the sub state will
--- do so as well.
-function Cursor.substate(self)
-       Cursor._substates = Cursor._substates or { }
-       Cursor._substates[self] = Cursor._substates[self] or cursor_state()
-       return Cursor._substates[self]
-end
-
-local _load = Cursor.load
-function Cursor.load(self, ...)
-       if Cursor._substates and Cursor._substates[self] then
-               _load(Cursor._substates[self], ...)
-       end
-       return _load(self, ...)
-end
-
-local _unload = Cursor.unload
-function Cursor.unload(self, ...)
-       if Cursor._substates and Cursor._substates[self] then
-               _unload(Cursor._substates[self], ...)
-       end
-       return _unload(self, ...)
-end
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
index 12b20e4..823e207 100644 (file)
@@ -87,10 +87,10 @@ end
 function httpget(url, stream, target)
        if not target then
                local source = stream and io.popen or luci.util.exec
-               return source("wget -qO- '"..url:gsub("'", "").."'")
+               return source("wget -qO- %s" % luci.util.shellquote(url))
        else
-               return os.execute("wget -qO '%s' '%s'" %
-                       {target:gsub("'", ""), url:gsub("'", "")})
+               return os.execute("wget -qO %s %s" %
+                       {luci.util.shellquote(target), luci.util.shellquote(url)})
        end
 end
 
@@ -443,18 +443,11 @@ function user.checkpasswd(username, pass)
 end
 
 function user.setpasswd(username, password)
-       if password then
-               password = password:gsub("'", [['"'"']])
-       end
-
-       if username then
-               username = username:gsub("'", [['"'"']])
-       end
-
-       return os.execute(
-               "(echo '" .. password .. "'; sleep 1; echo '" .. password .. "') | " ..
-               "passwd '" .. username .. "' >/dev/null 2>&1"
-       )
+       return os.execute("(echo %s; sleep 1; echo %s) | passwd %s >/dev/null 2>&1" %{
+               luci.util.shellquote(password),
+               luci.util.shellquote(password),
+               luci.util.shellquote(username)
+       })
 end
 
 
index 5012111..06a9ad4 100644 (file)
@@ -187,7 +187,9 @@ function switch_status(devs)
        local switches = { }
        for dev in devs:gmatch("[^%s,]+") do
                local ports = { }
-               local swc = io.popen("swconfig dev %q show" % dev, "r")
+               local swc = io.popen("swconfig dev %s show"
+                       % luci.util.shellquote(dev), "r")
+
                if swc then
                        local l
                        repeat
index 28c1266..06a889c 100644 (file)
@@ -164,6 +164,10 @@ function striptags(value)
        return value and tparser.striptags(tostring(value))
 end
 
+function shellquote(value)
+       return string.format("'%s'", string.gsub(value or "", "'", "'\\''"))
+end
+
 -- for bash, ash and similar shells single-quoted strings are taken
 -- literally except for single quotes (which terminate the string)
 -- (and the exception noted below for dash (-) at the start of a
@@ -656,7 +660,7 @@ function checklib(fullpathexe, wantedlib)
        if not haveldd or not haveexe then
                return false
        end
-       local libs = exec("/usr/bin/ldd " .. fullpathexe)
+       local libs = exec(string.format("/usr/bin/ldd %s", shellquote(fullpathexe)))
        if not libs then
                return false
        end
index 949aeb2..79a17a2 100644 (file)
@@ -83,6 +83,15 @@ Strip HTML tags from given string.
 ]]
 
 ---[[
+Safely quote value for use in shell commands.
+
+@class function
+@name shellquote
+@param value  String containing the value to quote
+@return Single-quote enclosed string with embedded quotes escaped
+]]
+
+---[[
 Splits given string on a defined separator sequence and return a table
 
 containing the resulting substrings. The optional max parameter specifies
index f6b0f57..b3ec9b7 100644 (file)
@@ -6,7 +6,7 @@
 
 <%+header%>
 
-<form method="post" action="<%=pcdata(luci.http.getenv("REQUEST_URI"))%>">
+<form method="post" action="<%=pcdata(FULL_REQUEST_URI)%>">
        <%- if fuser then %>
        <div class="errorbox"><%:Invalid username and/or password! Please try again.%></div>
        <% end -%>
index a6a8843..5d597cf 100644 (file)
@@ -744,6 +744,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index c69654f..d1cef0c 100644 (file)
@@ -738,6 +738,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 47472a3..414e475 100644 (file)
@@ -764,6 +764,11 @@ msgid "Custom feeds"
 msgstr "Eigene Repositories"
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr "Passt das Verhalten der Geräte-LEDs an - wenn dies möglich ist."
index d0b9e24..86d6a0a 100644 (file)
@@ -747,6 +747,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index fbaa03b..cf6c82f 100644 (file)
@@ -734,6 +734,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index a92bb43..a769a59 100644 (file)
@@ -743,6 +743,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index cba7cac..d0dddc2 100644 (file)
@@ -750,6 +750,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 6d98134..13bc8c8 100644 (file)
@@ -727,6 +727,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index e7b3a79..56aafed 100644 (file)
@@ -745,6 +745,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 414fddf..36aa0cd 100644 (file)
@@ -750,6 +750,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index c069940..df2323c 100644 (file)
@@ -751,6 +751,11 @@ msgid "Custom feeds"
 msgstr "カスタム フィード"
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index c56c05e..d0ad869 100644 (file)
@@ -732,6 +732,11 @@ msgid "Custom feeds"
 msgstr "Custom feed 들"
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index ff33243..cfd5cf6 100644 (file)
@@ -712,6 +712,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr "Mengkustomisasi perilaku peranti LED jika mungkin."
index f8b40c1..1e3b4f9 100644 (file)
@@ -734,6 +734,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 9bc33a4..4fc0dd5 100644 (file)
@@ -752,6 +752,11 @@ msgstr ""
 msgid "Custom feeds"
 msgstr ""
 
+msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
 # Spacji zabrało i napisy się skleiły
 msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
index bf0de75..b0f372c 100644 (file)
@@ -787,6 +787,11 @@ msgid "Custom feeds"
 msgstr "Fontes de pacotes customizadas"
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 3109903..4fad056 100644 (file)
@@ -747,6 +747,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 955cff6..5070449 100644 (file)
@@ -722,6 +722,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index c0b53eb..ea80637 100644 (file)
@@ -778,6 +778,11 @@ msgid "Custom feeds"
 msgstr "Список custom-ных feed-ов"
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index ec72661..3c98dbb 100644 (file)
@@ -705,6 +705,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index a7f906e..d76c751 100644 (file)
@@ -719,6 +719,11 @@ msgid "Custom feeds"
 msgstr "Anpassade flöden"
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index a840921..629278e 100644 (file)
@@ -698,6 +698,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 496d96f..0f8c059 100644 (file)
@@ -718,6 +718,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 520bff4..cbaade8 100644 (file)
@@ -756,6 +756,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 2287dfb..dd5379b 100644 (file)
@@ -712,6 +712,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index c0a5351..188f8cb 100644 (file)
@@ -721,6 +721,11 @@ msgid "Custom feeds"
 msgstr "自定义软件源"
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr "自定义文件(证书、脚本)会保留在系统上。若无需保留,请先执行恢复出厂设置。"
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr "自定义此设备的 <abbr title=\"Light Emitting Diode\">LED</abbr> 行为。"
index d78223f..54efec3 100644 (file)
@@ -723,6 +723,11 @@ msgid "Custom feeds"
 msgstr ""
 
 msgid ""
+"Custom files (certificates, scripts) may remain on the system. To prevent "
+"this, perform a factory-reset first."
+msgstr ""
+
+msgid ""
 "Customizes the behaviour of the device <abbr title=\"Light Emitting Diode"
 "\">LED</abbr>s if possible."
 msgstr ""
index 33f6a67..070a9e6 100644 (file)
@@ -289,7 +289,8 @@ function iface_reconnect(iface)
        local netmd = require "luci.model.network".init()
        local net = netmd:get_network(iface)
        if net then
-               luci.sys.call("env -i /sbin/ifup %q >/dev/null 2>/dev/null" % iface)
+               luci.sys.call("env -i /sbin/ifup %s >/dev/null 2>/dev/null"
+                       % luci.util.shellquote(iface))
                luci.http.status(200, "Reconnected")
                return
        end
@@ -301,7 +302,8 @@ function iface_shutdown(iface)
        local netmd = require "luci.model.network".init()
        local net = netmd:get_network(iface)
        if net then
-               luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
+               luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
+                       % luci.util.shellquote(iface))
                luci.http.status(200, "Shutdown")
                return
        end
@@ -313,7 +315,8 @@ function iface_delete(iface)
        local netmd = require "luci.model.network".init()
        local net = netmd:del_network(iface)
        if net then
-               luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
+               luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null"
+                       % luci.util.shellquote(iface))
                luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
                netmd:commit("network")
                netmd:commit("wireless")
@@ -389,7 +392,7 @@ function diag_command(cmd, addr)
        if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
                luci.http.prepare_content("text/plain")
 
-               local util = io.popen(cmd % addr)
+               local util = io.popen(cmd % luci.util.shellquote(addr))
                if util then
                        while true do
                                local ln = util:read("*l")
@@ -408,21 +411,21 @@ function diag_command(cmd, addr)
 end
 
 function diag_ping(addr)
-       diag_command("ping -c 5 -W 1 %q 2>&1", addr)
+       diag_command("ping -c 5 -W 1 %s 2>&1", addr)
 end
 
 function diag_traceroute(addr)
-       diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr)
+       diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr)
 end
 
 function diag_nslookup(addr)
-       diag_command("nslookup %q 2>&1", addr)
+       diag_command("nslookup %s 2>&1", addr)
 end
 
 function diag_ping6(addr)
-       diag_command("ping6 -c 5 %q 2>&1", addr)
+       diag_command("ping6 -c 5 %s 2>&1", addr)
 end
 
 function diag_traceroute6(addr)
-       diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr)
+       diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr)
 end
index 22e1b7e..3a1c169 100644 (file)
@@ -62,7 +62,9 @@ end
 function action_bandwidth(iface)
        luci.http.prepare_content("application/json")
 
-       local bwc = io.popen("luci-bwc -i %q 2>/dev/null" % iface)
+       local bwc = io.popen("luci-bwc -i %s 2>/dev/null"
+               % luci.util.shellquote(iface))
+
        if bwc then
                luci.http.write("[")
 
@@ -80,7 +82,9 @@ end
 function action_wireless(iface)
        luci.http.prepare_content("application/json")
 
-       local bwc = io.popen("luci-bwc -r %q 2>/dev/null" % iface)
+       local bwc = io.popen("luci-bwc -r %s 2>/dev/null"
+               % luci.util.shellquote(iface))
+
        if bwc then
                luci.http.write("[")
 
index 66d9942..b7b73d7 100644 (file)
@@ -274,7 +274,7 @@ s.anonymous = true
 s.template = "cbi/tblsection"
 
 name = s:option(Value, "name", translate("Hostname"))
-name.datatype = "hostname"
+name.datatype = "hostname('strict')"
 name.rmempty  = true
 
 function name.write(self, section, value)
index 89a73a5..b52dff1 100644 (file)
@@ -5,6 +5,7 @@
 m = Map("network", translate("Switch"), translate("The network ports on this device can be combined to several <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s in which computers can communicate directly with each other. <abbr title=\"Virtual Local Area Network\">VLAN</abbr>s are often used to separate different network segments. Often there is by default one Uplink port for a connection to the next greater network like the internet and other ports for a local network."))
 
 local fs = require "nixio.fs"
+local ut = require "luci.util"
 local nw = require "luci.model.network"
 local switches = { }
 
@@ -74,7 +75,7 @@ m.uci:foreach("network", "switch",
                end
 
                -- Parse some common switch properties from swconfig help output.
-               local swc = io.popen("swconfig dev %q help 2>/dev/null" % switch_name)
+               local swc = io.popen("swconfig dev %s help 2>/dev/null" % ut.shellquote(switch_name))
                if swc then
 
                        local is_port_attr = false
index c0bb380..a574d35 100644 (file)
@@ -63,7 +63,7 @@ function m.parse(map)
        Map.parse(map)
 
        if m:get(wdev:name(), "type") == "mac80211" and new_cc and new_cc ~= old_cc then
-               luci.sys.call("iw reg set %q" % new_cc)
+               luci.sys.call("iw reg set %s" % ut.shellquote(new_cc))
                luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1]))
                return
        end