+Version: 2.1.0-2
+Date: 2014-11-15
+ddns-scripts: 2.1.0-2 or greater needed
+
+- moved /usr/lib/ddns/dynamic_dns_lucihelper.sh to ddns-scripts package
+- fixed error message when validating proxy
+- modified validating ip_script to allow the usage of parameters
+- using ipkg/postinst AND ipkg/postinst-pkg as long as LuCI Makefiles did not
+ fullfil requirements of new OpenWrt default_postinst and default_postrm
+ reported in Issue #255
+- cleanup whitespaces at line ends
+
+--------------------------------------------------------------------------------
Version: 2.1.0-1
Date: 2014-11-09
ddns-scripts: 2.1.0-1 or greater needed
#!/bin/sh
[ -n "${IPKG_INSTROOT}" ] || {
+ # luci updates are not in sync with ddns-script updates !!!
+ # needed because luci update might delete helper script
+ # copy dynamic_dns_helper.tmp.sh from ddns-scripts
+ cp -f /usr/lib/ddns/dynamic_dns_lucihelper.tmp.sh /usr/lib/ddns/dynamic_dns_lucihelper.sh
+
( . /etc/uci-defaults/luci-ddns ) && rm -f /etc/uci-defaults/luci-ddns
exit 0
}
--- /dev/null
+#!/bin/sh
+[ -n "${IPKG_INSTROOT}" ] || {
+ # luci updates are not in sync with ddns-script updates !!!
+ # needed because luci update might delete helper script
+ # copy dynamic_dns_helper.tmp.sh from ddns-scripts
+ cp -f /usr/lib/ddns/dynamic_dns_lucihelper.tmp.sh /usr/lib/ddns/dynamic_dns_lucihelper.sh
+
+ ( . /etc/uci-defaults/luci-ddns ) && rm -f /etc/uci-defaults/luci-ddns
+ exit 0
+}
local DDNS = require "luci.tools.ddns" -- ddns multiused functions
local UTIL = require "luci.util"
-local luci_ddns_version = "2.1.0-1" -- luci-app-ddns / openwrt Makefile compatible version
-local ddns_scripts_min = "2.1.0-1" -- minimum version of ddns-scripts required
+local luci_ddns_version = "2.1.0-2" -- luci-app-ddns / openwrt Makefile compatible version
+local ddns_scripts_min = "2.1.0-2" -- minimum version of ddns-scripts required
function index()
- -- above 'require "mod"' definitions are not recognized
+ -- above 'require "mod"' definitions are not recognized
-- inside index() during initialisation
-- no configuration file, don't start
else
entry( {"admin", "services", "ddns"}, cbi("ddns/overview"), _("Dynamic DNS"), 59)
entry( {"admin", "services", "ddns", "detail"}, cbi("ddns/detail"), nil ).leaf = true
- entry( {"admin", "services", "ddns", "hints"}, cbi("ddns/hints",
+ entry( {"admin", "services", "ddns", "hints"}, cbi("ddns/hints",
{hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), nil ).leaf = true
entry( {"admin", "services", "ddns", "logview"}, call("logread") ).leaf = true
entry( {"admin", "services", "ddns", "startstop"}, call("startstop") ).leaf = true
-- and enabled state
local section = s[".name"]
local enabled = tonumber(s["enabled"]) or 0
- local datelast = "_empty_" -- formated date of last update
+ local datelast = "_empty_" -- formated date of last update
local datenext = "_empty_" -- formated date of next update
-- get force seconds
local force_seconds = DDNS.calc_seconds(
tonumber(s["force_interval"]) or 72 ,
s["force_unit"] or "hours" )
- -- get/validate pid and last update
+ -- get/validate pid and last update
local pid = DDNS.get_pid(section)
local uptime = SYS.uptime()
local lasttime = DDNS.get_lastupd(section)
if pid > 0 and ( lasttime + force_seconds - uptime ) <= 0 then
datenext = "_verify_"
- -- run once
+ -- run once
elseif force_seconds == 0 then
datenext = "_runonce_"
elseif pid == 0 and enabled == 0 then
datenext = "_disabled_"
- -- no process running and NOT
+ -- no process running and NOT
elseif pid == 0 and enabled ~= 0 then
datenext = "_stopped_"
end
-
+
-- get/set monitored interface and IP version
local iface = s["interface"] or "_nonet_"
local use_ipv6 = tonumber(s["use_ipv6"]) or 0
local force_ipversion = tonumber(s["force_ipversion"] or 0)
local force_dnstcp = tonumber(s["force_dnstcp"] or 0)
local command = [[/usr/lib/ddns/dynamic_dns_lucihelper.sh]]
- command = command .. [[ get_registered_ip ]] .. domain .. [[ ]] .. use_ipv6 ..
+ command = command .. [[ get_registered_ip ]] .. domain .. [[ ]] .. use_ipv6 ..
[[ ]] .. force_ipversion .. [[ ]] .. force_dnstcp .. [[ ]] .. dnsserver
local reg_ip = SYS.exec(command)
- if reg_ip == "" then
+ if reg_ip == "" then
reg_ip = "_nodata_"
end
local ldata=NXFS.readfile(lfile)
if not ldata or #ldata == 0 then
ldata="_nodata_"
- end
+ end
uci:unload("ddns")
HTTP.write(ldata)
end
end
end
- -- we can not execute because other
+ -- we can not execute because other
-- uncommited changes pending, so exit here
if not exec then
HTTP.write("_uncommited_")
-- save enable state
uci:set("ddns", section, "enabled", ( (enabled == "true") and "1" or "0") )
- uci:save("ddns")
+ uci:save("ddns")
uci:commit("ddns")
uci:unload("ddns")
-- start dynamic_dns_updater.sh script
os.execute ([[/usr/lib/ddns/dynamic_dns_updater.sh %s 0 > /dev/null 2>&1 &]] % section)
NX.nanosleep(3) -- 3 seconds "show time"
-
+
-- status changed so return full status
data = _get_status()
HTTP.prepare_content("application/json")
web.rmempty = true
-local ci = s:option(Value, "check_interval", translate("Check for changed IP every"))
-ci.datatype = "and(uinteger,min(1))"
-ci.default = 10
+local ci = s:option(Value, "check_interval", translate("Check for changed IP every"))
+ci.datatype = "and(uinteger,min(1))"
+ci.default = 10
local unit = s:option(ListValue, "check_unit", translate("Check-time unit"))
unit.default = "minutes"
unit:value("minutes", translate("min"))
unit:value("hours", translate("h"))
-fi = s:option(Value, "force_interval", translate("Force update every"))
-fi.datatype = "and(uinteger,min(1))"
-fi.default = 72
+fi = s:option(Value, "force_interval", translate("Force update every"))
+fi.datatype = "and(uinteger,min(1))"
+fi.default = 72
local unit = s:option(ListValue, "force_unit", translate("Force-time unit"))
unit.default = "hours"
local command = [[/usr/lib/ddns/dynamic_dns_lucihelper.sh get_local_ip ]] ..
_ipv6 .. [[ ]] .. _source .. [[ ]] .. _network .. [[ ]] ..
- _url .. [[ ]] .. _interface .. [[ ]] .. _script.. [[ ]] .. _proxy
+ _url .. [[ ]] .. _interface .. [[ ']] .. _script.. [[' ]] .. _proxy
local ret = SYS.call(command)
if ret == 0 then
m = Map("ddns")
-- first need to close <a> from cbi map template our <a> closed by template
-m.title = [[</a><a href="]] .. DISP.build_url("admin", "services", "ddns") .. [[">]] ..
+m.title = [[</a><a href="]] .. DISP.build_url("admin", "services", "ddns") .. [[">]] ..
translate("Dynamic DNS")
m.description = translate("Dynamic DNS allows that your router can be reached with " ..
translate("If this service section is disabled it could not be started." .. "<br />" ..
"Neither from LuCI interface nor from console") )
en.orientation = "horizontal"
-function en.parse(self, section)
- DDNS.flag_parse(self, section)
+function en.parse(self, section)
+ DDNS.flag_parse(self, section)
end
-- use_ipv6 (NEW) -- ##########################################################
return value
end
function usev6.validate(self, value)
- if (value == "1" and 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
end
function usev6.write(self, section, value)
- if value == "0" then -- force rmempty
+ if value == "0" then -- force rmempty
return self.map:del(section, self.option)
else
return self.map:set(section, self.option, value)
translate("DDNS Service provider") .. " [IPv6]" )
svc6.default = "-"
svc6:depends("use_ipv6", "1") -- only show on IPv6
-if not has_ipv6 then
- svc6.description = err_ipv6_basic
+if not has_ipv6 then
+ svc6.description = err_ipv6_basic
end
local services6 = { }
end
return value
end
- function https.parse(self, section)
- DDNS.flag_parse(self, section)
+ function https.parse(self, section)
+ DDNS.flag_parse(self, section)
end
function https.validate(self, value)
if (value == "1" and has_ssl ) or value == "0" then return value end
cert.rmempty = false -- force validate function
cert.default = "/etc/ssl/certs"
function cert.validate(self, value)
- if https:formvalue(section) == "0" then
+ if https:formvalue(section) == "0" then
return "" -- supress validate error if NOT https
end
if value then -- otherwise errors in datatype check
logf.orientation = "horizontal"
logf.rmempty = false -- we want to save in /etc/config/ddns file on "0" because
logf.default = "1" -- if not defined write to log by default
-function logf.parse(self, section)
- DDNS.flag_parse(self, section)
+function logf.parse(self, section)
+ DDNS.flag_parse(self, section)
end
-- TAB: Advanced ##################################################################################
or src6:formvalue(section) ~= "network" then
-- ignore if IPv4 selected OR
-- ignore everything except "network"
- return ""
- elseif has_ipv6 then
+ return ""
+ elseif has_ipv6 then
return value
else
return nil, err_tab_adv(self) .. err_ipv6_plain
translate("URL to detect") .. " [IPv6]" )
iurl6:depends("ipv6_source", "web")
iurl6.default = "http://checkipv6.dyndns.com"
-if 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
translate("User defined script to read systems IP-Address") )
ips:depends("ipv4_source", "script") -- IPv4
ips:depends("ipv6_source", "script") -- or IPv6
+ips.rmempty = false
ips.placeholder = "/path/to/script.sh"
function ips.validate(self, value)
+ local split
+ if value then split = UTIL.split(value, " ") end
+
if (usev6:formvalue(section) == "0" and src4:formvalue(section) ~= "script")
or (usev6:formvalue(section) == "1" and src6:formvalue(section) ~= "script") then
return ""
- elseif not value or not FS.access(value, "x") then
+ elseif not value or not (#value > 0) or not FS.access(split[1], "x") then
return nil, err_tab_adv(self) ..
translate("not found or not executable - Sample: '/path/to/script.sh'")
else
if (value == "1" and has_force) or value == "0" then return value end
return nil, err_tab_adv(self) .. translate("Force IP Version not supported")
end
- function fipv.parse(self, section)
- DDNS.flag_parse(self, section)
+ function fipv.parse(self, section)
+ DDNS.flag_parse(self, section)
end
function fipv.write(self, section, value)
if value == "1" then
return value
end
function tcp.validate(self, value)
- if (value == "1" and has_dnstcp ) or value == "0" then
+ if (value == "1" and has_dnstcp ) or value == "0" then
return value
end
return nil, err_tab_adv(self) .. translate("DNS requests via TCP not supported")
end
- function tcp.parse(self, section)
- DDNS.flag_parse(self, section)
+ function tcp.parse(self, section)
+ DDNS.flag_parse(self, section)
end
end
else return nil, err_tab_adv(self) .. translate("unspecific error")
end
else
- return nil, err .. translate("PROXY-Server not supported")
+ return nil, err_tab_adv(self) .. translate("PROXY-Server not supported")
end
end
end
fi.default = 72 -- see dynamic_dns_updater.sh script
fi.rmempty = false -- validate ourselves for translatable error messages
function fi.validate(self, value)
- if not DTYP.uinteger(value)
+ if not DTYP.uinteger(value)
or tonumber(value) < 0 then
return nil, err_tab_timer(self) .. translate("minimum value '0'")
end
rc.default = 5
rc.rmempty = false -- validate ourselves for translatable error messages
function rc.validate(self, value)
- if not DTYP.uinteger(value)
+ if not DTYP.uinteger(value)
or tonumber(value) < 1 then
return nil, err_tab_timer(self) .. translate("minimum value '1'")
else
-- check if IPv6 supported by OpenWrt
function check_ipv6()
- return NXFS.access("/proc/net/ipv6_route")
+ return NXFS.access("/proc/net/ipv6_route")
and NXFS.access("/usr/sbin/ip6tables")
end
-- read version information for given package if installed
function ipkg_version(package)
- if not package then
+ if not package then
return nil
end
local info = OPKG.info(package)
local version = ""
local i = 0
for k, v in pairs(info) do
- if v.Package == package and v.Status.installed then
+ if v.Package == package and v.Status.installed then
version = v.Version
i = i + 1
end
if (fvalue ~= cvalue) then self.section.changed = true end
else
self:remove(section)
- self.section.changed = true
+ self.section.changed = true
end
end
function parse_url(url) --, default)
-- initialize default parameters
local parsed = {}
--- for i,v in base.pairs(default or parsed) do
+-- for i,v in base.pairs(default or parsed) do
-- parsed[i] = v
-- end
-- remove whitespace
-- url = string.gsub(url, "%s", "")
-- get fragment
- url = string.gsub(url, "#(.*)$",
+ url = string.gsub(url, "#(.*)$",
function(f)
parsed.fragment = f
return ""
parsed.path = url
local authority = parsed.authority
- if not authority then
+ if not authority then
return parsed
end
authority = string.gsub(authority,"^([^@]*)@",
str += "\n\nluci-app-ddns:";
str += "\n\t<%:Version%>:\t" + luci_version;
str += "\n\t<%:Build%>:\t" + luci_build;
- str += "\n\nddns-scripts <%:installed%>:";
- str += "\n\t<%:Version%>:\t" + ddns_version;
str += "\n\nddns-scripts <%:required%>:";
str += "\n\t<%:Version%>:\t" + ddns_required + " <%:or greater%>";
+ str += "\n\nddns-scripts <%:installed%>:";
+ str += "\n\t<%:Version%>:\t" + ddns_version;
str += "\n\n"
alert(str);
}
if ( !(tbl) ) { return; }
// clear all rows
- while (tbl.rows.length > 1)
+ while (tbl.rows.length > 1)
tbl.deleteRow(1);
// variable for Modulo-Division use to set cbi-rowstyle-? (0 or 1)
if (tbl.rows.length == 1 || (data[0].enabled == 0 && tbl.rows.length == 2) ) {
var br = '<br />';
- if (tbl.rows.length > 1)
+ if (tbl.rows.length > 1)
br = '';
var tr = tbl.insertRow(-1);
tr.className = "cbi-section-table-row";
+++ /dev/null
-#!/bin/sh
-# /usr/lib/ddns/luci_dns_helper.sh
-#
-# Written in August 2014
-# by Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
-# This script is used by luci-app-ddns
-# - getting registered IP
-# - check if possible to get local IP
-# - verifing given DNS- or Proxy-Server
-#
-# variables in small chars are read from /etc/config/ddns as parameter given here
-# variables in big chars are defined inside these scripts as gloval vars
-# variables in big chars beginning with "__" are local defined inside functions only
-# set -vx #script debugger
-
-[ $# -lt 2 ] && exit 1
-
-. /usr/lib/ddns/dynamic_dns_functions.sh # global vars are also defined here
-
-# set -vx #script debugger
-
-# preset some variables, wrong or not set in dynamic_dns_functions.sh
-SECTION_ID="lucihelper"
-LOGFILE="$LOGDIR/$SECTION_ID.log"
-VERBOSE_MODE=0 # no console logging
-# global variables normally set by reading DDNS UCI configuration
-use_syslog=0 # no syslog
-use_logfile=0 # by default no logfile, can be changed here
-
-case "$1" in
- get_registered_ip)
- local IP
- domain=$2 # Hostname/Domain
- use_ipv6=${3:-"0"} # Use IPv6 - default IPv4
- force_ipversion=${4:-"0"} # Force IP Version - default 0 - No
- force_dnstcp=${5:-"0"} # Force TCP on DNS - default 0 - No
- dns_server=${6:-""} # DNS server - default No DNS
- write_log 7 "-----> get_registered_ip IP"
- get_registered_ip IP
- [ $? -ne 0 ] && IP=""
- echo -n "$IP" # suppress LF
- ;;
- verify_dns)
- # $2 : dns-server to verify # no need for force_dnstcp because
- # verify with nc (netcat) uses tcp anyway
- use_ipv6=${3:-"0"} # Use IPv6 - default IPv4
- force_ipversion=${4:-"0"} # Force IP Version - default 0 - No
- write_log 7 "-----> verify_dns '$2'"
- verify_dns "$2"
- ;;
- verify_proxy)
- # $2 : proxy string to verify
- use_ipv6=${3:-"0"} # Use IPv6 - default IPv4
- force_ipversion=${4:-"0"} # Force IP Version - default 0 - No
- write_log 7 "-----> verify_proxy '$2'"
- verify_proxy "$2"
- ;;
- get_local_ip)
- local IP
- use_ipv6="$2" # Use IPv6
- ip_source="$3" # IP source
- ip_network="$4" # set if source = "network" otherwise "-"
- ip_url="$5" # set if source = "web" otherwise "-"
- ip_interface="$6" # set if source = "interface" itherwiase "-"
- ip_script="$7" # set if source = "script" otherwise "-"
- proxy="$8" # proxy if set
- force_ipversion="0" # not needed but must be set
- use_https="0" # not needed but must be set
- [ -n "$proxy" -a "$ip_source" = "web" ] && {
- # proxy defined, used for ip_source=web
- export HTTP_PROXY="http://$proxy"
- export HTTPS_PROXY="http://$proxy"
- export http_proxy="http://$proxy"
- export https_proxy="http://$proxy"
- }
- # don't need IP only the return code
- [ "$ip_source" = "web" -o "$ip_source" = "script" ] && {
- # we wait only 3 seconds for an
- # answer from "web" or "script"
- write_log 7 "-----> timeout 3 -- get_local_ip IP"
- timeout 3 -- get_local_ip IP
- } || {
- write_log 7 "-----> get_local_ip IP"
- get_local_ip IP
- }
- ;;
- *)
- return 255
- ;;
-esac