luci-app-ddns: improve performance
[project/luci.git] / applications / luci-app-ddns / luasrc / model / cbi / ddns / detail.lua
index e38a6060a03e9355c23a4cfc2c100546187a9db2..10d39c7183334ff46d80fcddaecbf919bd9ad158 100644 (file)
@@ -58,7 +58,7 @@ end
 
 -- read services/services_ipv6 files -- ########################################
 local services4 = { }          -- IPv4 --
-local fd4 = io.open("/usr/lib/ddns/services", "r")
+local fd4 = io.open("/etc/ddns/services", "r")
 if fd4 then
        local ln, s, t
        repeat
@@ -72,7 +72,7 @@ if fd4 then
 end
 
 local services6 = { }          -- IPv6 --
-local fd6 = io.open("/usr/lib/ddns/services_ipv6", "r")
+local fd6 = io.open("/etc/ddns/services_ipv6", "r")
 if fd6 then
        local ln, s, t
        repeat
@@ -91,35 +91,38 @@ end
 -- local IP can be read
 local function _verify_ip_source()
        -- section is globally defined here be calling agrument (see above)
-       local _network   = "-"
-       local _url       = "-"
-       local _interface = "-"
-       local _script    = "-"
-       local _proxy     = ""
+       local _arg
 
        local _ipv6   = usev6:formvalue(section)
        local _source = (_ipv6 == "1")
                        and src6:formvalue(section)
                        or  src4:formvalue(section)
+
+       local command = CTRL.luci_helper .. [[ -]]
+       if (_ipv6 == "1")  then command = command .. [[6]] end
+
        if _source == "network" then
-               _network = (_ipv6 == "1")
+               _arg = (_ipv6 == "1")
                        and ipn6:formvalue(section)
                        or  ipn4:formvalue(section)
+               command = command .. [[n ]] .. _arg
        elseif _source == "web" then
-               _url = (_ipv6 == "1")
+               _arg = (_ipv6 == "1")
                        and iurl6:formvalue(section)
                        or  iurl4:formvalue(section)
+               command = command .. [[u ]] .. _arg
+
                -- proxy only needed for checking url
-               _proxy = (pxy) and pxy:formvalue(section) or ""
+               _arg = (pxy) and pxy:formvalue(section) or ""
+               if (_arg and #_arg > 0) then
+                       command = command .. [[ -p ]] .. _arg
+               end
        elseif _source == "interface" then
-               _interface = ipi:formvalue(section)
+               command = command .. [[i ]] .. ipi:formvalue(section)
        elseif _source == "script" then
-               _script = ips:formvalue(section)
+               command = command .. [[s ]] .. ips:formvalue(section)
        end
-
-       local command = [[/usr/lib/ddns/dynamic_dns_lucihelper.sh get_local_ip ]] ..
-               _ipv6 .. [[ ]] .. _source .. [[ ]] .. _network .. [[ ]] ..
-               _url .. [[ ]] .. _interface .. [[ ']] .. _script.. [[' ]] .. _proxy
+       command = command .. [[ -- get_local_ip]]
        return (SYS.call(command) == 0)
 end
 
@@ -248,10 +251,8 @@ if m:formvalue("cbid.ddns.%s._switch" % section) then      -- section == arg[1]
 end
 
 -- read application settings -- ################################################
--- date format; if not set use ISO format
-local date_format = m.uci:get(m.config, "global", "date_format") or "%F %R"
 -- log directory
-local log_dir = m.uci:get(m.config, "global", "log_dir") or "/var/log/ddns"
+local logdir = m.uci:get(m.config, "global", "ddns_logdir") or "/var/log/ddns"
 
 -- cbi-section definition -- ###################################################
 local ns = m:section( NamedSection, section, "service",
@@ -291,6 +292,10 @@ function luh.parse(self, section, novld)
 end
 
 -- use_ipv6 -- ################################################################
+
+--We call it globally as it's called 11 times even outside specific function, saves 11 os.execute slow command!
+local has_ipv6 = DDNS.env_info("has_ipv6") 
+
 usev6 = ns:taboption("basic", ListValue, "use_ipv6",
        translate("IP address version"),
        translate("Defines which IP address 'IPv4/IPv6' is send to the DDNS provider") )
@@ -299,16 +304,16 @@ usev6.default = "0"
 usev6:value("0", translate("IPv4-Address") )
 function usev6.cfgvalue(self, section)
        local value = AbstractValue.cfgvalue(self, section) or "0"
-       if DDNS.has_ipv6 or (value == "1" and not DDNS.has_ipv6) then
+       if has_ipv6 or (value == "1" and not has_ipv6) then
                self:value("1", translate("IPv6-Address") )
        end
-       if value == "1" and not DDNS.has_ipv6 then
+       if value == "1" and not has_ipv6 then
                self.description = err_ipv6_basic
        end
        return value
 end
 function usev6.validate(self, value)
-       if (value == "1" and DDNS.has_ipv6) or value == "0" then
+       if (value == "1" and has_ipv6) or value == "0" then
                return value
        end
        return nil, err_tab_basic(self) .. err_ipv6_plain
@@ -359,7 +364,7 @@ svc6 = ns:taboption("basic", ListValue, "ipv6_service_name",
        translate("DDNS Service provider") .. " [IPv6]" )
 svc6.default   = "-"
 svc6:depends("use_ipv6", "1")  -- only show on IPv6
-if not DDNS.has_ipv6 then
+if not has_ipv6 then
        svc6.description = err_ipv6_basic
 end
 function svc6.cfgvalue(self, section)
@@ -373,7 +378,7 @@ function svc6.cfgvalue(self, section)
 end
 function svc6.validate(self, value)
        if usev6:formvalue(section) == "1" then -- do only on IPv6
-               if DDNS.has_ipv6 then return value end
+               if has_ipv6 then return value end
                return nil, err_tab_basic(self) .. err_ipv6_plain
        else
                return ""       -- suppress validate error
@@ -585,13 +590,17 @@ end
 svc6:value("-", translate("-- custom --") )
 
 -- IPv4/IPv6 - use_https -- ###################################################
-if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
+
+--We call it globally as it's called 4 times outside specific function.
+local has_ssl = DDNS.env_info("has_ssl")
+
+if has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
        https = ns:taboption("basic", Flag, "use_https",
                translate("Use HTTP Secure") )
        https.orientation = "horizontal"
        function https.cfgvalue(self, section)
                local value = AbstractValue.cfgvalue(self, section)
-               if not DDNS.has_ssl and value == "1" then
+               if not has_ssl and value == "1" then
                        self.description = bold_on .. font_red ..
                                translate("HTTPS not supported") .. font_off .. "<br />" ..
                                translate("please disable") .. " !" .. bold_off
@@ -601,7 +610,7 @@ if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
                return value
        end
        function https.validate(self, value)
-               if (value == "1" and DDNS.has_ssl ) or value == "0" then return value end
+               if (value == "1" and has_ssl ) or value == "0" then return value end
                return nil, err_tab_basic(self) .. translate("HTTPS not supported") .. " !"
        end
        function https.write(self, section, value)
@@ -615,7 +624,7 @@ if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
 end
 
 -- IPv4/IPv6 - cacert -- ######################################################
-if DDNS.has_ssl then
+if has_ssl then
        cert = ns:taboption("basic", Value, "cacert",
                translate("Path to CA-Certificate"),
                translate("directory or path/file") .. "<br />" ..
@@ -705,7 +714,7 @@ src6:value("network", translate("Network"))
 src6:value("web", translate("URL"))
 src6:value("interface", translate("Interface"))
 src6:value("script", translate("Script"))
-if not DDNS.has_ipv6 then
+if not has_ipv6 then
        src6.description = err_ipv6_other
 end
 function src6.cfgvalue(self, section)
@@ -714,7 +723,7 @@ end
 function src6.validate(self, value)
        if usev6:formvalue(section) ~= "1" then
                return ""       -- ignore on IPv4 selected
-       elseif not DDNS.has_ipv6 then
+       elseif not has_ipv6 then
                return nil, err_tab_adv(self) .. err_ipv6_plain
        elseif not _verify_ip_source() then
                return nil, err_tab_adv(self) ..
@@ -793,7 +802,7 @@ ipn6 = ns:taboption("advanced", ListValue, "ipv6_network",
 ipn6:depends("ipv6_source", "network")
 ipn6.default = "wan6"
 WADM.cbi_add_networks(ipn6)
-if DDNS.has_ipv6 then
+if has_ipv6 then
        ipn6.description = translate("Defines the network to read systems IPv6-Address from")
 else
        ipn6.description = err_ipv6_other
@@ -807,7 +816,7 @@ function ipn6.validate(self, value)
                -- ignore if IPv4 selected OR
                -- ignore everything except "network"
                return ""
-       elseif DDNS.has_ipv6 then
+       elseif has_ipv6 then
                return value
        else
                return nil, err_tab_adv(self) .. err_ipv6_plain
@@ -880,7 +889,7 @@ iurl6 = ns:taboption("advanced", Value, "ipv6_url",
        translate("URL to detect") .. " [IPv6]" )
 iurl6:depends("ipv6_source", "web")
 iurl6.default = "http://checkipv6.dyndns.com"
-if DDNS.has_ipv6 then
+if has_ipv6 then
        iurl6.description = translate("Defines the Web page to read systems IPv6-Address from")
 else
        iurl6.description = err_ipv6_other
@@ -894,7 +903,7 @@ function iurl6.validate(self, value)
                -- ignore if IPv4 selected OR
                -- ignore everything except "web"
                return ""
-       elseif not DDNS.has_ipv6 then
+       elseif not has_ipv6 then
                return nil, err_tab_adv(self) .. err_ipv6_plain
        elseif not value or #value == 0 then
                return nil, err_tab_adv(self) .. translate("missing / required")
@@ -1050,7 +1059,7 @@ eif6:depends("ipv6_source", "web")
 eif6:depends("ipv6_source", "script")
 eif6.default = "wan6"
 WADM.cbi_add_networks(eif6)
-if not DDNS.has_ipv6 then
+if not has_ipv6 then
        eif6.description = err_ipv6_other
 else
        eif6.description = translate("Network on which the ddns-updater scripts will be started")
@@ -1064,7 +1073,7 @@ function eif6.validate(self, value)
         or fsrc6 == "network"
         or fsrc6 == "interface" then
                return ""       -- ignore IPv4, network, interface
-       elseif not DDNS.has_ipv6 then
+       elseif not has_ipv6 then
                return nil, err_tab_adv(self) .. err_ipv6_plain
        else
                return value
@@ -1083,10 +1092,13 @@ function eif6.write(self, section, value)
 end
 function eif6.parse(self, section, novld)
        DDNS.value_parse(self, section, novld)
-end
+end 
 
 -- IPv4/IPv6 - bind_network -- ################################################
-if DDNS.has_bindnet or ( ( m:get(section, "bind_network") ) ~= "" ) then
+
+local has_bindnet = DDNS.env_info("has_bindnet")
+
+if has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
        bnet = ns:taboption("advanced", ListValue, "bind_network",
                translate("Bind Network") )
        bnet:depends("ipv4_source", "web")
@@ -1096,7 +1108,7 @@ if DDNS.has_bindnet or ( ( m:get(section, "bind_network") ) ~= "" ) then
        WADM.cbi_add_networks(bnet)
        function bnet.cfgvalue(self, section)
                local value = AbstractValue.cfgvalue(self, section)
-               if not DDNS.has_bindnet and value ~= "" then
+               if not has_bindnet and value ~= "" then
                        self.description = bold_on .. font_red ..
                                translate("Binding to a specific network not supported") .. font_off .. "<br />" ..
                                translate("please set to 'default'") .. " !" .. bold_off
@@ -1107,7 +1119,7 @@ if DDNS.has_bindnet or ( ( m:get(section, "bind_network") ) ~= "" ) then
                return value
        end
        function bnet.validate(self, value)
-               if ( (value ~= "") and DDNS.has_bindnet ) or (value == "") then return value end
+               if ( (value ~= "") and has_bindnet ) or (value == "") then return value end
                return nil, err_tab_adv(self) .. translate("Binding to a specific network not supported") .. " !"
        end
        function bnet.parse(self, section, novld)
@@ -1118,13 +1130,16 @@ end
 -- IPv4 + IPv6 - force_ipversion -- ###########################################
 -- optional to force wget/curl and host to use only selected IP version
 -- command parameter "-4" or "-6"
-if DDNS.has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) then
+
+local has_forceip = DDNS.env_info("has_forceip")
+
+if has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) then
        fipv = ns:taboption("advanced", Flag, "force_ipversion",
                translate("Force IP Version") )
        fipv.orientation = "horizontal"
        function fipv.cfgvalue(self, section)
                local value = AbstractValue.cfgvalue(self, section)
-               if not DDNS.has_forceip and value ~= "0" then
+               if not has_forceip and value ~= "0" then
                        self.description = bold_on .. font_red ..
                                translate("Force IP Version not supported") .. font_off .. "<br />" ..
                                translate("please disable") .. " !" .. bold_off
@@ -1134,14 +1149,17 @@ if DDNS.has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) t
                return value
        end
        function fipv.validate(self, value)
-               if (value == "1" and DDNS.has_forceip) or value == "0" then return value end
+               if (value == "1" and has_forceip) or value == "0" then return value end
                return nil, err_tab_adv(self) .. translate("Force IP Version not supported")
        end
 end
 
 -- IPv4 + IPv6 - dns_server -- ################################################
 -- optional DNS Server to use resolving my IP
-if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
+
+local has_dnsserver = DDNS.env_info("has_dnsserver")
+
+if has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
        dns = ns:taboption("advanced", Value, "dns_server",
                translate("DNS-Server"),
                translate("OPTIONAL: Use non-default DNS-Server to detect 'Registered IP'.") .. "<br />" ..
@@ -1151,15 +1169,18 @@ if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
                -- if .datatype is set, then it is checked before calling this function
                if not value or (#value == 0) then
                        return ""       -- ignore on empty
-               elseif not DDNS.has_dnsserver then
+               elseif not has_dnsserver then
                        return nil, err_tab_adv(self) .. translate("Specifying a DNS-Server is not supported")
                elseif not DTYP.host(value) then
                        return nil, err_tab_adv(self) .. translate("use hostname, FQDN, IPv4- or IPv6-Address")
                else
                        local ipv6  = usev6:formvalue(section) or "0"
                        local force = fipv:formvalue(section)  or "0"
-                       local command = [[/usr/lib/ddns/dynamic_dns_lucihelper.sh verify_dns ]] ..
-                               value .. [[ ]] .. ipv6 .. [[ ]] .. force
+                       local command = CTRL.luci_helper .. [[ -]]
+                       if (ipv6 == 1)  then command = command .. [[6]] end
+                       if (force == 1) then command = command .. [[f]] end
+                       command = command .. [[d ]] .. value .. [[ -- verify_dns]]
+
                        local ret = SYS.call(command)
                        if     ret == 0 then return value       -- everything OK
                        elseif ret == 2 then return nil, err_tab_adv(self) .. translate("nslookup can not resolve host")
@@ -1175,13 +1196,16 @@ if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
 end
 
 -- IPv4 + IPv6 - force_dnstcp -- ##############################################
-if DDNS.has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) then
+
+local has_bindhost = DDNS.env_info("has_bindhost")
+
+if has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) then
        tcp = ns:taboption("advanced", Flag, "force_dnstcp",
                translate("Force TCP on DNS") )
        tcp.orientation = "horizontal"
        function tcp.cfgvalue(self, section)
                local value = AbstractValue.cfgvalue(self, section)
-               if not DDNS.has_bindhost and value ~= "0" then
+               if not has_bindhost and value ~= "0" then
                        self.description = bold_on .. font_red ..
                                translate("DNS requests via TCP not supported") .. font_off .. "<br />" ..
                                translate("please disable") .. " !" .. bold_off
@@ -1191,7 +1215,7 @@ if DDNS.has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) the
                return value
        end
        function tcp.validate(self, value)
-               if (value == "1" and DDNS.has_bindhost ) or value == "0" then
+               if (value == "1" and has_bindhost ) or value == "0" then
                        return value
                end
                return nil, err_tab_adv(self) .. translate("DNS requests via TCP not supported")
@@ -1200,13 +1224,16 @@ end
 
 -- IPv4 + IPv6 - proxy -- #####################################################
 -- optional Proxy to use for http/https requests  [user:password@]proxyhost[:port]
-if DDNS.has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
+
+local has_proxy = DDNS.env_info("has_proxy")
+
+if has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
        pxy = ns:taboption("advanced", Value, "proxy",
                translate("PROXY-Server") )
        pxy.placeholder="user:password@myproxy.lan:8080"
        function pxy.cfgvalue(self, section)
                local value = AbstractValue.cfgvalue(self, section)
-               if not DDNS.has_proxy and value ~= "" then
+               if not has_proxy and value ~= "" then
                        self.description = bold_on .. font_red ..
                                translate("PROXY-Server not supported") .. font_off .. "<br />" ..
                                translate("please remove entry") .. "!" .. bold_off
@@ -1222,11 +1249,13 @@ if DDNS.has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
                -- if .datatype is set, then it is checked before calling this function
                if not value or (#value == 0) then
                        return ""       -- ignore on empty
-               elseif DDNS.has_proxy then
+               elseif has_proxy then
                        local ipv6  = usev6:formvalue(section) or "0"
                        local force = fipv:formvalue(section) or "0"
-                       local command = [[/usr/lib/ddns/dynamic_dns_lucihelper.sh verify_proxy ]] ..
-                               value .. [[ ]] .. ipv6 .. [[ ]] .. force
+                       local command = CTRL.luci_helper .. [[ -]]
+                       if (ipv6 == 1)  then command = command .. [[6]] end
+                       if (force == 1) then command = command .. [[f]] end
+                       command = command .. [[p ]] .. value .. [[ -- verify_proxy]]
                        local ret = SYS.call(command)
                        if     ret == 0 then return value
                        elseif ret == 2 then return nil, err_tab_adv(self) .. translate("nslookup can not resolve host")
@@ -1262,7 +1291,7 @@ end
 logf = ns:taboption("advanced", Flag, "use_logfile",
        translate("Log to file"),
        translate("Writes detailed messages to log file. File will be truncated automatically.") .. "<br />" ..
-       translate("File") .. [[: "]] .. log_dir .. [[/]] .. section .. [[.log"]] )
+       translate("File") .. [[: "]] .. logdir .. [[/]] .. section .. [[.log"]] )
 logf.orientation = "horizontal"
 logf.default     = "1"         -- if not defined write to log by default
 
@@ -1464,7 +1493,7 @@ lv.template = "ddns/detail_logview"
 lv.inputtitle = translate("Read / Reread log file")
 lv.rows = 50
 function lv.cfgvalue(self, section)
-       local lfile=log_dir .. "/" .. section .. ".log"
+       local lfile=logdir .. "/" .. section .. ".log"
        if NXFS.access(lfile) then
                return lfile .. "\n" .. translate("Please press [Read] button")
        end