summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-ddns/luasrc/controller/ddns.lua
diff options
context:
space:
mode:
Diffstat (limited to 'applications/luci-ddns/luasrc/controller/ddns.lua')
-rw-r--r--applications/luci-ddns/luasrc/controller/ddns.lua235
1 files changed, 229 insertions, 6 deletions
diff --git a/applications/luci-ddns/luasrc/controller/ddns.lua b/applications/luci-ddns/luasrc/controller/ddns.lua
index 0c7293d5a..e59a2800c 100644
--- a/applications/luci-ddns/luasrc/controller/ddns.lua
+++ b/applications/luci-ddns/luasrc/controller/ddns.lua
@@ -3,6 +3,7 @@ LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
+Copyright 2014 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -15,16 +16,238 @@ $Id$
module("luci.controller.ddns", package.seeall)
+require "nixio"
+require "nixio.fs"
+require "luci.sys"
+require "luci.http"
+require "luci.model.uci"
+require "luci.dispatcher"
+require "luci.tools.ddns"
+
function index()
+ -- no configuration file, don't start
if not nixio.fs.access("/etc/config/ddns") then
return
end
-
- local page
+ -- ddns-scripts 1.0.0 installed, run old luci app
+ if not nixio.fs.access("/usr/lib/ddns/services_ipv6")
+ or nixio.fs.access("/usr/lib/ddns/url_escape.sed") then
+ local page
+ page = entry({"admin", "services", "ddns"}, cbi("ddns/ddns"), _("Dynamic DNS"), 60)
+ page.dependent = true
+ page = entry({"mini", "network", "ddns"}, cbi("ddns/ddns", {autoapply=true}), _("Dynamic DNS"), 60)
+ page.dependent = true
+ -- it looks like ddns-scripts 2.x.x are installed
+ 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",
+ {hideapplybtn=true, hidesavebtn=true, hideresetbtn=true}), nil ).leaf = true
+ entry( {"admin", "services", "ddns", "logview"}, call("logread") ).leaf = true
+ entry( {"admin", "services", "ddns", "status"}, call("status") ).leaf = true
+ entry( {"admin", "services", "ddns", "startstop"}, call("startstop") ).leaf = true
+ end
+end
+
+-- function to read all sections status and return data array
+function _get_status()
+ local uci = luci.model.uci.cursor()
+ local service = luci.sys.init.enabled("ddns") and 1 or 0
+ local url_start = luci.dispatcher.build_url("admin", "system", "startup")
+ local data = {} -- Array to transfer data to javascript
+
+ -- read application settings
+ local date_format = uci:get("ddns", "global", "date_format") or "%F %R"
+ local run_dir = uci:get("ddns", "global", "run_dir") or "/var/run/ddns"
+
+ data[#data+1] = {
+ enabled = service, -- service enabled
+ url_up = url_start -- link to enable DDS (System-Startup)
+ }
+
+ uci:foreach("ddns", "service", function (s)
+
+ -- Get section we are looking at
+ -- and enabled state
+ local section = s[".name"]
+ local enabled = tonumber(s["enabled"]) or 0
+ local datelast = "_empty_" -- formated date of last update
+ local datenext = "_empty_" -- formated date of next update
+
+ -- get force seconds
+ local force_seconds = luci.tools.ddns.calc_seconds(
+ tonumber(s["force_interval"]) or 72 ,
+ s["force_unit"] or "hours" )
+ -- get/validate pid and last update
+ local pid = luci.tools.ddns.get_pid(section, run_dir)
+ local uptime = luci.sys.uptime()
+ local lasttime = tonumber(nixio.fs.readfile("%s/%s.update" % { run_dir, section } ) or 0 )
+ if lasttime > uptime then -- /var might not be linked to /tmp
+ lasttime = 0 -- and/or not cleared on reboot
+ end
+
+ -- no last update happen
+ if lasttime == 0 then
+ datelast = "_never_"
+
+ -- we read last update
+ else
+ -- calc last update
+ -- sys.epoch - sys uptime + lastupdate(uptime)
+ local epoch = os.time() - uptime + lasttime
+ -- use linux date to convert epoch
+ datelast = luci.sys.exec([[/bin/date -d @]] .. epoch .. [[ +']] .. date_format .. [[']])
+ -- calc and fill next update
+ datenext = luci.sys.exec([[/bin/date -d @]] .. (epoch + force_seconds) ..
+ [[ +']] .. date_format .. [[']])
+ end
+
+ -- process running but update needs to happen
+ -- problems it force_seconds > uptime
+ force_seconds = (force_seconds > uptime) and uptime or force_seconds
+ if pid > 0 and ( lasttime + force_seconds - uptime ) <= 0 then
+ datenext = "_verify_"
+
+ -- run once
+ elseif force_seconds == 0 then
+ datenext = "_runonce_"
+
+ -- no process running and NOT enabled
+ elseif pid == 0 and enabled == 0 then
+ datenext = "_disabled_"
+
+ -- 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
+ if iface ~= "_nonet_" then
+ local ipv = (use_ipv6 == 1) and "IPv6" or "IPv4"
+ iface = ipv .. " / " .. iface
+ end
+
+ -- try to get registered IP
+ local domain = s["domain"] or "_nodomain_"
+ local dnsserver = s["dns_server"] or ""
+ 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 ..
+ [[ ]] .. force_ipversion .. [[ ]] .. force_dnstcp .. [[ ]] .. dnsserver
+ local reg_ip = luci.sys.exec(command)
+ if reg_ip == "" then
+ reg_ip = "_nodata_"
+ end
+
+ -- fill transfer array
+ data[#data+1] = {
+ section = section,
+ enabled = enabled,
+ iface = iface,
+ domain = domain,
+ reg_ip = reg_ip,
+ pid = pid,
+ datelast = datelast,
+ datenext = datenext
+ }
+ end)
+
+ uci:unload("ddns")
+
+ return data
+end
+
+-- called by XHR.get from detail_logview.htm
+function logread(section)
+ -- read application settings
+ local uci = luci.model.uci.cursor()
+ local log_dir = uci:get("ddns", "global", "log_dir") or "/var/log/ddns"
+ local lfile=log_dir .. "/" .. section .. ".log"
+
+ local ldata=nixio.fs.readfile(lfile)
+ if not ldata or #ldata == 0 then
+ ldata="_nodata_"
+ end
+ luci.http.write(ldata)
+end
+
+-- called by XHR.get from overview_status.htm
+function startstop(section, enabled)
+ -- Array to transfer data to javascript
+ local data = {}
+ -- read application settings
+ local uci = luci.model.uci.cursor()
+ local run_dir = uci:get("ddns", "global", "run_dir") or "/var/run/ddns"
+
+ -- if process running we want to stop and return
+ local pid = luci.tools.ddns.get_pid(section, run_dir)
+ if pid > 0 then
+ os.execute ([[kill -9 %s]] % pid)
+ nixio.nanosleep(2) -- 2 second "show time"
+ -- status changed so return full status
+ data = _get_status()
+ luci.http.prepare_content("application/json")
+ luci.http.write_json(data)
+ return
+ end
- page = entry({"admin", "services", "ddns"}, cbi("ddns/ddns"), _("Dynamic DNS"), 60)
- page.dependent = true
+ -- read uncommited changes
+ -- we don't save and commit data from other section or other options
+ -- only enabled will be done
+ local exec = true
+ local changed = uci:changes("ddns")
+ for k_config, v_section in pairs(changed) do
+ -- security check because uci.changes only gets our config
+ if k_config ~= "ddns" then
+ exec = false
+ break
+ end
+ for k_section, v_option in pairs(v_section) do
+ -- check if only section of button was changed
+ if k_section ~= section then
+ exec = false
+ break
+ end
+ for k_option, v_value in pairs(v_option) do
+ -- check if only enabled was changed
+ if k_option ~= "enabled" then
+ exec = false
+ break
+ end
+ end
+ end
+
+ end
+
+ -- we can not execute because other
+ -- uncommited changes pending, so exit here
+ if not exec then
+ luci.http.write("_uncommited_")
+ return
+ end
+
+ -- save enable state
+ uci:set("ddns", section, "enabled", ( (enabled == "true") and "1" or "0") )
+ 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)
+ nixio.nanosleep(3) -- 3 seconds "show time"
+
+ -- status changed so return full status
+ data = _get_status()
+ luci.http.prepare_content("application/json")
+ luci.http.write_json(data)
+end
- page = entry({"mini", "network", "ddns"}, cbi("ddns/ddns", {autoapply=true}), _("Dynamic DNS"), 60)
- page.dependent = true
+-- called by XHR.poll from overview_status.htm
+function status()
+ local data = _get_status()
+ luci.http.prepare_content("application/json")
+ luci.http.write_json(data)
end