gluon-hoodselector: util.lua, use taps instead of spaces. Use posix.unistd.access instead of io.open

Signed-off-by: Jan-Tarek Butt <tarek@ring0.de>
This commit is contained in:
Jan-Tarek Butt 2019-02-09 04:50:31 +01:00
parent 45b8a190dd
commit 4554e23b37

View File

@ -1,3 +1,4 @@
local unistd = require('posix.unistd')
local util = require 'gluon.util' local util = require 'gluon.util'
local json = require 'jsonc' local json = require 'jsonc'
local uci = require('simple-uci').cursor() local uci = require('simple-uci').cursor()
@ -7,27 +8,27 @@ local logger = require('posix.syslog')
local M = {} local M = {}
function M.split(s, delimiter) function M.split(s, delimiter)
local result = {} local result = {}
for match in (s..delimiter):gmatch("(.-)"..delimiter) do for match in (s..delimiter):gmatch("(.-)"..delimiter) do
table.insert(result, match) table.insert(result, match)
end end
return result return result
end end
function M.log(msg) function M.log(msg)
io.stdout:write(msg..'\n') io.stdout:write(msg..'\n')
logger.openlog(msg, logger.LOG_PID) logger.openlog(msg, logger.LOG_PID)
end end
function M.get_domains() function M.get_domains()
local list = {} local list = {}
for _, domain_path in ipairs(util.glob('/lib/gluon/domains/*.json')) do for _, domain_path in ipairs(util.glob('/lib/gluon/domains/*.json')) do
table.insert(list, { table.insert(list, {
domain_code = domain_path:match('([^/]+)%.json$'), domain_code = domain_path:match('([^/]+)%.json$'),
domain = assert(json.load(domain_path)), domain = assert(json.load(domain_path)),
}) })
end end
return list return list
end end
-- Return the default hood in the hood list. -- Return the default hood in the hood list.
@ -35,31 +36,31 @@ end
-- * default hood -- * default hood
-- * nil if no default hood has been defined -- * nil if no default hood has been defined
function M.get_default_hood(jhood) function M.get_default_hood(jhood)
for _, h in pairs(jhood) do for _, h in pairs(jhood) do
if h.domain_code == site.default_domain() then if h.domain_code == site.default_domain() then
return h return h
end end
end end
return nil return nil
end end
-- bool if direct VPN. The detection is realised by searching the fastd network interface inside the originator table -- Returns true if the node has an established running VPN connection.
function M.direct_vpn() function M.direct_vpn()
for outgoing_if in io.popen(string.format("batctl o"), 'r'):lines() do for outgoing_if in io.popen(string.format("batctl o"), 'r'):lines() do
-- escape special chars "[]-" -- escape special chars "[]-"
if outgoing_if:match(string.gsub("%[ " .. vpn_util.get_mesh_vpn_interface() .. "%]","%-", "%%-")) then if outgoing_if:match(string.gsub("%[ " .. vpn_util.get_mesh_vpn_interface() .. "%]","%-", "%%-")) then
return true return true
end end
end end
return false return false
end end
-- Get Geoposition. Return nil for no position -- Get Geoposition. Return nil for no position
function M.get_geolocation() function M.get_geolocation()
return { return {
lat = tonumber(uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'latitude')), lat = tonumber(uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'latitude')),
lon = tonumber(uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'longitude')) lon = tonumber(uci:get('gluon-node-info', uci:get_first('gluon-node-info', 'location'), 'longitude'))
} }
end end
-- Source with pseudocode: https://de.wikipedia.org/wiki/Punkt-in-Polygon-Test_nach_Jordan -- Source with pseudocode: https://de.wikipedia.org/wiki/Punkt-in-Polygon-Test_nach_Jordan
@ -68,100 +69,100 @@ end
-- return value: 1 if the ray from A to the right bisects the edge [BC] (the lower vortex of [BC] -- return value: 1 if the ray from A to the right bisects the edge [BC] (the lower vortex of [BC]
-- is not seen as part of [BC]); -- is not seen as part of [BC]);
-- 0 if A is on [BC]; -- 0 if A is on [BC];
-- +1 else -- +1 else
function M.cross_prod_test(x_a,y_a,x_b,y_b,x_c,y_c) function M.cross_prod_test(x_a,y_a,x_b,y_b,x_c,y_c)
if y_a == y_b and y_b == y_c then if y_a == y_b and y_b == y_c then
if (x_b <= x_a and x_a <= x_c) or (x_c <= x_a and x_a <= x_b) then if (x_b <= x_a and x_a <= x_c) or (x_c <= x_a and x_a <= x_b) then
return 0 return 0
end end
return 1 return 1
end end
if not ((y_a == y_b) and (x_a == x_b)) then if not ((y_a == y_b) and (x_a == x_b)) then
if y_b > y_c then if y_b > y_c then
-- swap b and c -- swap b and c
local h = x_b local h = x_b
x_b = x_c x_b = x_c
x_c = h x_c = h
h = y_b h = y_b
y_b = y_c y_b = y_c
y_c = h y_c = h
end end
if (y_a <= y_b) or (y_a > y_c) then if (y_a <= y_b) or (y_a > y_c) then
return 1 return 1
end end
local delta = (x_b-x_a) * (y_c-y_a) - (y_b-y_a) * (x_c-x_a) local delta = (x_b-x_a) * (y_c-y_a) - (y_b-y_a) * (x_c-x_a)
if delta > 0 then if delta > 0 then
return 1 return 1
elseif delta < 0 then elseif delta < 0 then
return -1 return -1
end end
end end
return 0 return 0
end end
-- Source with pseudocode: https://de.wikipedia.org/wiki/Punkt-in-Polygon-Test_nach_Jordan -- Source with pseudocode: https://de.wikipedia.org/wiki/Punkt-in-Polygon-Test_nach_Jordan
-- see also: https://en.wikipedia.org/wiki/Point_in_polygon -- see also: https://en.wikipedia.org/wiki/Point_in_polygon
-- let P be a 2D Polygon and Q a 2D Point -- let P be a 2D Polygon and Q a 2D Point
-- return value: +1 if Q within P; -- return value: +1 if Q within P;
-- 1 if Q outside of P; -- 1 if Q outside of P;
-- 0 if Q on an edge of P -- 0 if Q on an edge of P
function M.point_in_polygon(poly, point) function M.point_in_polygon(poly, point)
local t = -1 local t = -1
for i=1,#poly-1 do for i=1,#poly-1 do
t = t * M.crossProdTest(point.lon,point.lat,poly[i].lon,poly[i].lat,poly[i+1].lon,poly[i+1].lat) t = t * M.crossProdTest(point.lon,point.lat,poly[i].lon,poly[i].lat,poly[i+1].lon,poly[i+1].lat)
if t == 0 then break end if t == 0 then break end
end end
return t return t
end end
-- Return hood from the hood file based on geo position or nil if no real hood could be determined -- Return hood from the hood file based on geo position or nil if no real hood could be determined
-- First check if an area has > 2 points and is hence a polygon. Else assume it is a rectangular -- First check if an area has > 2 points and is hence a polygon. Else assume it is a rectangular
-- box defined by two points (south-west and north-east) -- box defined by two points (south-west and north-east)
function M.get_hood_by_geo(jhood,geo) function M.get_hood_by_geo(jhood,geo)
for _, hood in pairs(jhood) do for _, hood in pairs(jhood) do
if hood.domain_code ~= site.default_domain() then if hood.domain_code ~= site.default_domain() then
for _, area in pairs(hood.domain.hoodselector.shapes) do for _, area in pairs(hood.domain.hoodselector.shapes) do
if #area > 2 then if #area > 2 then
if (M.point_in_polygon(area,geo) == 1) then if (M.point_in_polygon(area,geo) == 1) then
return hood return hood
end end
else else
if ( geo.lat >= area[1].lat and geo.lat < area[2].lat and geo.lon >= area[1].lon if ( geo.lat >= area[1].lat and geo.lat < area[2].lat and geo.lon >= area[1].lon
and geo.lon < area[2].lon ) then and geo.lon < area[2].lon ) then
return hood return hood
end end
end end
end end
end end
end end
return nil return nil
end end
function M.set_hoodconfig(geo_hood) function M.set_hoodconfig(geo_hood)
if uci:get('gluon', 'core', 'domain') ~= geo_hood.domain_code then if uci:get('gluon', 'core', 'domain') ~= geo_hood.domain_code then
uci:set('gluon', 'core', 'domain', geo_hood.domain_code) uci:set('gluon', 'core', 'domain', geo_hood.domain_code)
uci:commit('gluon') uci:commit('gluon')
os.execute('gluon-reconfigure') os.execute('gluon-reconfigure')
M.log('Set domain "'..geo_hood.domain.domain_names[geo_hood.domain_code]..'"') M.log('Set domain "'..geo_hood.domain.domain_names[geo_hood.domain_code]..'"')
return true return true
end end
return false return false
end end
function M.restart_services() function M.restart_services()
local proc_tbl = { local proc_tbl = {
"fastd", "fastd",
"tunneldigger", "tunneldigger",
"network", "network",
"gluon-respondd", "gluon-respondd",
} }
for proc in ipairs(proc_tbl) do for proc in ipairs(proc_tbl) do
if io.open("/etc/init.d/"..proc, 'r') ~= nil then if unistd.access("/etc/init.d/"..proc, "x") == 0 then
print(proc.." restarting ...") print(proc.." restarting ...")
os.execute("/etc/init.d/"..proc.." restart") os.execute("/etc/init.d/"..proc.." restart")
end end
end end
end end
return M return M