The network topology of a BMX6 mesh can be obtained by asking all the nodes about their links via the bmx6-info script. The wget() function in the bmx6json.lua file is part of the process, but it often returns nil, even if the remote data can actually be fetched, in what seems to be a race condition. By calling the sys.exec("") function empty, the race condition disappears. Dirty fix to https://github.com/openwrt-routing/packages/issues/436. Signed-off-by: Roger Pueyo Centelles <roger.pueyo@guifi.net>
224 lines
5.4 KiB
Lua
224 lines
5.4 KiB
Lua
--[[
|
|
Copyright (C) 2011 Pau Escrich <pau@dabax.net>
|
|
Contributors Jo-Philipp Wich <xm@subsignal.org>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
The full GNU General Public License is included in this distribution in
|
|
the file called "COPYING".
|
|
--]]
|
|
|
|
local ltn12 = require("luci.ltn12")
|
|
local json = require("luci.json")
|
|
local util = require("luci.util")
|
|
local uci = require("luci.model.uci")
|
|
local sys = require("luci.sys")
|
|
local template = require("luci.template")
|
|
local http = require("luci.http")
|
|
local string = require("string")
|
|
local table = require("table")
|
|
local nixio = require("nixio")
|
|
local nixiofs = require("nixio.fs")
|
|
local ipairs = ipairs
|
|
|
|
module "luci.model.bmx6json"
|
|
|
|
-- Returns a LUA object from bmx6 JSON daemon
|
|
|
|
function get(field, host)
|
|
local url
|
|
if host ~= nil then
|
|
if host:match(":") then
|
|
url = 'http://[%s]/cgi-bin/bmx6-info?' % host
|
|
else
|
|
url = 'http://%s/cgi-bin/bmx6-info?' % host
|
|
end
|
|
else
|
|
url = uci.cursor():get("luci-bmx6","luci","json")
|
|
end
|
|
|
|
if url == nil then
|
|
print_error("bmx6 json url not configured, cannot fetch bmx6 daemon data",true)
|
|
return nil
|
|
end
|
|
|
|
local json_url = util.split(url,":")
|
|
local raw = ""
|
|
|
|
if json_url[1] == "http" then
|
|
raw,err = wget(url..field,1000)
|
|
sys.exec("")
|
|
else
|
|
|
|
if json_url[1] == "exec" then
|
|
raw = sys.exec(json_url[2]..' '..field)
|
|
else
|
|
print_error("bmx6 json url not recognized, cannot fetch bmx6 daemon data. Use http: or exec:",true)
|
|
return nil
|
|
end
|
|
|
|
end
|
|
|
|
local data = nil
|
|
|
|
if raw and raw:len() > 10 then
|
|
local decoder = json.Decoder()
|
|
ltn12.pump.all(ltn12.source.string(raw), decoder:sink())
|
|
data = decoder:get()
|
|
-- else
|
|
-- print_error("Cannot get data from bmx6 daemon",true)
|
|
-- return nil
|
|
end
|
|
|
|
return data
|
|
end
|
|
|
|
function print_error(txt,popup)
|
|
util.perror(txt)
|
|
sys.call("logger -t bmx6json " .. txt)
|
|
|
|
if popup then
|
|
http.write('<script type="text/javascript">alert("Some error detected, please check it: '..txt..'");</script>')
|
|
else
|
|
http.write("<h1>Dammit! some error detected</h1>")
|
|
http.write("bmx6-luci: " .. txt)
|
|
http.write('<p><FORM><INPUT TYPE="BUTTON" VALUE="Go Back" ONCLICK="history.go(-1)"></FORM></p>')
|
|
end
|
|
|
|
end
|
|
|
|
function text2html(txt)
|
|
txt = string.gsub(txt,"<","{")
|
|
txt = string.gsub(txt,">","}")
|
|
txt = util.striptags(txt)
|
|
return txt
|
|
end
|
|
|
|
|
|
function wget(url, timeout)
|
|
local rfd, wfd = nixio.pipe()
|
|
local pid = nixio.fork()
|
|
if pid == 0 then
|
|
rfd:close()
|
|
nixio.dup(wfd, nixio.stdout)
|
|
-- candidates for wget, try first ones with SSL support
|
|
local candidates = {{"/usr/bin/wget-ssl",1},{"/usr/bin/wget",0},{"/bin/wget",0}}
|
|
local _, bin
|
|
for _, bin in ipairs(candidates) do
|
|
if nixiofs.access(bin[1], "x") then
|
|
if bin[2] == 0 then
|
|
nixio.exec(bin[1], "-q", "-O", "-", url)
|
|
else
|
|
nixio.exec(bin[1], "--no-check-certificate", "-q", "-O", "-", url)
|
|
end
|
|
end
|
|
end
|
|
return
|
|
else
|
|
wfd:close()
|
|
rfd:setblocking(false)
|
|
|
|
local buffer = { }
|
|
local err1, err2
|
|
|
|
while true do
|
|
local ready = nixio.poll({{ fd = rfd, events = nixio.poll_flags("in") }}, timeout)
|
|
if not ready then
|
|
nixio.kill(pid, nixio.const.SIGKILL)
|
|
err1 = "timeout"
|
|
break
|
|
end
|
|
|
|
local rv = rfd:read(4096)
|
|
if rv then
|
|
-- eof
|
|
if #rv == 0 then
|
|
break
|
|
end
|
|
|
|
buffer[#buffer+1] = rv
|
|
else
|
|
-- error
|
|
if nixio.errno() ~= nixio.const.EAGAIN and
|
|
nixio.errno() ~= nixio.const.EWOULDBLOCK then
|
|
err1 = "error"
|
|
err2 = nixio.errno()
|
|
end
|
|
end
|
|
end
|
|
|
|
nixio.waitpid(pid, "nohang")
|
|
if not err1 then
|
|
return table.concat(buffer)
|
|
else
|
|
return nil, err1, err2
|
|
end
|
|
end
|
|
end
|
|
|
|
function getOptions(name)
|
|
-- Getting json and Checking if bmx6-json is avaiable
|
|
local options = get("options")
|
|
if options == nil or options.OPTIONS == nil then
|
|
m.message = "bmx6-json plugin is not running or some mistake in luci-bmx6 configuration, check /etc/config/luci-bmx6"
|
|
return nil
|
|
else
|
|
options = options.OPTIONS
|
|
end
|
|
|
|
-- Filtering by the option name
|
|
local i,_
|
|
local namedopt = nil
|
|
if name ~= nil then
|
|
for _,i in ipairs(options) do
|
|
if i.name == name and i.CHILD_OPTIONS ~= nil then
|
|
namedopt = i.CHILD_OPTIONS
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
return namedopt
|
|
end
|
|
|
|
-- Rturns a help string formated to be used in HTML scope
|
|
function getHtmlHelp(opt)
|
|
if opt == nil then return nil end
|
|
|
|
local help = ""
|
|
if opt.help ~= nil then
|
|
help = text2html(opt.help)
|
|
end
|
|
if opt.syntax ~= nil then
|
|
help = help .. "<br/><b>Syntax: </b>" .. text2html(opt.syntax)
|
|
end
|
|
|
|
return help
|
|
end
|
|
|
|
function testandreload()
|
|
local test = sys.call('bmx6 -c --test > /tmp/bmx6-luci.err.tmp')
|
|
if test ~= 0 then
|
|
return sys.exec("cat /tmp/bmx6-luci.err.tmp")
|
|
end
|
|
|
|
local err = sys.call('bmx6 -c --configReload > /tmp/bmx6-luci.err.tmp')
|
|
if err ~= 0 then
|
|
return sys.exec("cat /tmp/bmx6-luci.err.tmp")
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|