mirror of
https://github.com/JamesonHuang/OpenWrt_Luci_Lua.git
synced 2024-11-23 22:00:11 +00:00
add h10 code
This commit is contained in:
parent
665cb6c93f
commit
b48c8407aa
14
Me_Lua/h10/MZLog.lua
Normal file
14
Me_Lua/h10/MZLog.lua
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module ("MZLog", package.seeall)
|
||||||
|
|
||||||
|
function log(...)
|
||||||
|
local posix = require("posix")
|
||||||
|
local util = require("luci.util")
|
||||||
|
local priority = arg[1]
|
||||||
|
if priority and tonumber(priority) then
|
||||||
|
posix.openlog("luci", "nep", LOG_USER)
|
||||||
|
for i = 2, arg.n do
|
||||||
|
posix.syslog(priority, util.serialize_data(arg[i]))
|
||||||
|
end
|
||||||
|
posix.closelog()
|
||||||
|
end
|
||||||
|
end
|
113
Me_Lua/h10/Posix.lua
Normal file
113
Me_Lua/h10/Posix.lua
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
local base = _G
|
||||||
|
local string = require("string")
|
||||||
|
local M = require "posix"
|
||||||
|
|
||||||
|
function M.timeradd (x,y)
|
||||||
|
local sec, usec = 0, 0
|
||||||
|
if x.sec then sec = sec + x.sec end
|
||||||
|
if y.sec then sec = sec + y.sec end
|
||||||
|
if x.usec then usec = usec + x.usec end
|
||||||
|
if y.usec then usec = usec + y.usec end
|
||||||
|
if usec > 1000000 then
|
||||||
|
sec = sec + 1
|
||||||
|
usec = usec - 1000000
|
||||||
|
end
|
||||||
|
|
||||||
|
return { sec = sec, usec = usec }
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.timercmp (x, y)
|
||||||
|
local x = { sec = x.sec or 0, usec = x.usec or 0 }
|
||||||
|
local y = { sec = y.sec or 0, usec = y.usec or 0 }
|
||||||
|
if x.sec ~= y.sec then
|
||||||
|
return x.sec - y.sec
|
||||||
|
else
|
||||||
|
return x.usec - y.usec
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function M.timersub (x,y)
|
||||||
|
local sec, usec = 0, 0
|
||||||
|
if x.sec then sec = x.sec end
|
||||||
|
if y.sec then sec = sec - y.sec end
|
||||||
|
if x.usec then usec = x.usec end
|
||||||
|
if y.usec then usec = usec - y.usec end
|
||||||
|
if usec < 0 then
|
||||||
|
sec = sec - 1
|
||||||
|
usec = usec + 1000000
|
||||||
|
end
|
||||||
|
|
||||||
|
return { sec = sec, usec = usec }
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.timesleep (x)
|
||||||
|
local sec, nsec = 0, 0
|
||||||
|
y = M.gettimeofday();
|
||||||
|
if( M.timercmp(x, y) > 0 ) then
|
||||||
|
sec = x.sec - y.sec
|
||||||
|
nsec = (x.usec - y.usec) * 1000
|
||||||
|
if nsec < 0 then
|
||||||
|
sec = sec - 1
|
||||||
|
nsec = nsec + 1000000000
|
||||||
|
end
|
||||||
|
M.nanosleep(sec, nsec)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.strsplit(str, delim, maxNb)
|
||||||
|
-- Eliminate bad cases...
|
||||||
|
if string.find(str, delim) == nil then
|
||||||
|
return { str }
|
||||||
|
end
|
||||||
|
if maxNb == nil or maxNb < 1 then
|
||||||
|
maxNb = 0 -- No limit
|
||||||
|
end
|
||||||
|
local result = {}
|
||||||
|
local pat = "(.-)" .. delim .. "()"
|
||||||
|
local nb = 0
|
||||||
|
local lastPos
|
||||||
|
for part, pos in string.gfind(str, pat) do
|
||||||
|
nb = nb + 1
|
||||||
|
result[nb] = part
|
||||||
|
lastPos = pos
|
||||||
|
if nb == maxNb then break end
|
||||||
|
end
|
||||||
|
-- Handle the last field
|
||||||
|
if nb ~= maxNb then
|
||||||
|
result[nb + 1] = string.sub(str, lastPos)
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.var_dump(data, max_level, prefix)
|
||||||
|
if type(prefix) ~= "string" then
|
||||||
|
prefix = ""
|
||||||
|
end
|
||||||
|
if type(data) ~= "table" then
|
||||||
|
print(prefix .. tostring(data))
|
||||||
|
else
|
||||||
|
print(data)
|
||||||
|
if max_level ~= 0 then
|
||||||
|
local prefix_next = prefix .. " "
|
||||||
|
print(prefix .. "{")
|
||||||
|
for k,v in pairs(data) do
|
||||||
|
io.stdout:write(prefix_next .. k .. " = ")
|
||||||
|
if type(v) ~= "table" or (type(max_level) == "number" and max_level <= 1) then
|
||||||
|
print(v)
|
||||||
|
else
|
||||||
|
if max_level == nil then
|
||||||
|
M.var_dump(v, nil, prefix_next)
|
||||||
|
else
|
||||||
|
M.var_dump(v, max_level - 1, prefix_next)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print(prefix .. "}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return M
|
BIN
Me_Lua/h10/cjson.so
Normal file
BIN
Me_Lua/h10/cjson.so
Normal file
Binary file not shown.
BIN
Me_Lua/h10/lfs.so
Executable file
BIN
Me_Lua/h10/lfs.so
Executable file
Binary file not shown.
BIN
Me_Lua/h10/lsqlite3.so
Normal file
BIN
Me_Lua/h10/lsqlite3.so
Normal file
Binary file not shown.
305
Me_Lua/h10/ltn12.lua
Normal file
305
Me_Lua/h10/ltn12.lua
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- LTN12 - Filters, sources, sinks and pumps.
|
||||||
|
-- LuaSocket toolkit.
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Declare module
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local string = require("string")
|
||||||
|
local table = require("table")
|
||||||
|
local base = _G
|
||||||
|
local _M = {}
|
||||||
|
if module then -- heuristic for exporting a global package table
|
||||||
|
ltn12 = _M
|
||||||
|
end
|
||||||
|
local filter,source,sink,pump = {},{},{},{}
|
||||||
|
|
||||||
|
_M.filter = filter
|
||||||
|
_M.source = source
|
||||||
|
_M.sink = sink
|
||||||
|
_M.pump = pump
|
||||||
|
|
||||||
|
-- 2048 seems to be better in windows...
|
||||||
|
_M.BLOCKSIZE = 2048
|
||||||
|
_M._VERSION = "LTN12 1.0.3"
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Filter stuff
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- returns a high level filter that cycles a low-level filter
|
||||||
|
function filter.cycle(low, ctx, extra)
|
||||||
|
base.assert(low)
|
||||||
|
return function(chunk)
|
||||||
|
local ret
|
||||||
|
ret, ctx = low(ctx, chunk, extra)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- chains a bunch of filters together
|
||||||
|
-- (thanks to Wim Couwenberg)
|
||||||
|
function filter.chain(...)
|
||||||
|
local arg = {...}
|
||||||
|
local n = select('#',...)
|
||||||
|
local top, index = 1, 1
|
||||||
|
local retry = ""
|
||||||
|
return function(chunk)
|
||||||
|
retry = chunk and retry
|
||||||
|
while true do
|
||||||
|
if index == top then
|
||||||
|
chunk = arg[index](chunk)
|
||||||
|
if chunk == "" or top == n then return chunk
|
||||||
|
elseif chunk then index = index + 1
|
||||||
|
else
|
||||||
|
top = top+1
|
||||||
|
index = top
|
||||||
|
end
|
||||||
|
else
|
||||||
|
chunk = arg[index](chunk or "")
|
||||||
|
if chunk == "" then
|
||||||
|
index = index - 1
|
||||||
|
chunk = retry
|
||||||
|
elseif chunk then
|
||||||
|
if index == n then return chunk
|
||||||
|
else index = index + 1 end
|
||||||
|
else base.error("filter returned inappropriate nil") end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Source stuff
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- create an empty source
|
||||||
|
local function empty()
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function source.empty()
|
||||||
|
return empty
|
||||||
|
end
|
||||||
|
|
||||||
|
-- returns a source that just outputs an error
|
||||||
|
function source.error(err)
|
||||||
|
return function()
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creates a file source
|
||||||
|
function source.file(handle, io_err)
|
||||||
|
if handle then
|
||||||
|
return function()
|
||||||
|
local chunk = handle:read(_M.BLOCKSIZE)
|
||||||
|
if not chunk then handle:close() end
|
||||||
|
return chunk
|
||||||
|
end
|
||||||
|
else return source.error(io_err or "unable to open file") end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- turns a fancy source into a simple source
|
||||||
|
function source.simplify(src)
|
||||||
|
base.assert(src)
|
||||||
|
return function()
|
||||||
|
local chunk, err_or_new = src()
|
||||||
|
src = err_or_new or src
|
||||||
|
if not chunk then return nil, err_or_new
|
||||||
|
else return chunk end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creates string source
|
||||||
|
function source.string(s)
|
||||||
|
if s then
|
||||||
|
local i = 1
|
||||||
|
return function()
|
||||||
|
local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1)
|
||||||
|
i = i + _M.BLOCKSIZE
|
||||||
|
if chunk ~= "" then return chunk
|
||||||
|
else return nil end
|
||||||
|
end
|
||||||
|
else return source.empty() end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creates rewindable source
|
||||||
|
function source.rewind(src)
|
||||||
|
base.assert(src)
|
||||||
|
local t = {}
|
||||||
|
return function(chunk)
|
||||||
|
if not chunk then
|
||||||
|
chunk = table.remove(t)
|
||||||
|
if not chunk then return src()
|
||||||
|
else return chunk end
|
||||||
|
else
|
||||||
|
table.insert(t, chunk)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- chains a source with one or several filter(s)
|
||||||
|
function source.chain(src, f, ...)
|
||||||
|
if ... then f=filter.chain(f, ...) end
|
||||||
|
base.assert(src and f)
|
||||||
|
local last_in, last_out = "", ""
|
||||||
|
local state = "feeding"
|
||||||
|
local err
|
||||||
|
return function()
|
||||||
|
if not last_out then
|
||||||
|
base.error('source is empty!', 2)
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
if state == "feeding" then
|
||||||
|
last_in, err = src()
|
||||||
|
if err then return nil, err end
|
||||||
|
last_out = f(last_in)
|
||||||
|
if not last_out then
|
||||||
|
if last_in then
|
||||||
|
base.error('filter returned inappropriate nil')
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
elseif last_out ~= "" then
|
||||||
|
state = "eating"
|
||||||
|
if last_in then last_in = "" end
|
||||||
|
return last_out
|
||||||
|
end
|
||||||
|
else
|
||||||
|
last_out = f(last_in)
|
||||||
|
if last_out == "" then
|
||||||
|
if last_in == "" then
|
||||||
|
state = "feeding"
|
||||||
|
else
|
||||||
|
base.error('filter returned ""')
|
||||||
|
end
|
||||||
|
elseif not last_out then
|
||||||
|
if last_in then
|
||||||
|
base.error('filter returned inappropriate nil')
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return last_out
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creates a source that produces contents of several sources, one after the
|
||||||
|
-- other, as if they were concatenated
|
||||||
|
-- (thanks to Wim Couwenberg)
|
||||||
|
function source.cat(...)
|
||||||
|
local arg = {...}
|
||||||
|
local src = table.remove(arg, 1)
|
||||||
|
return function()
|
||||||
|
while src do
|
||||||
|
local chunk, err = src()
|
||||||
|
if chunk then return chunk end
|
||||||
|
if err then return nil, err end
|
||||||
|
src = table.remove(arg, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Sink stuff
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- creates a sink that stores into a table
|
||||||
|
function sink.table(t)
|
||||||
|
t = t or {}
|
||||||
|
local f = function(chunk, err)
|
||||||
|
if chunk then table.insert(t, chunk) end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
return f, t
|
||||||
|
end
|
||||||
|
|
||||||
|
-- turns a fancy sink into a simple sink
|
||||||
|
function sink.simplify(snk)
|
||||||
|
base.assert(snk)
|
||||||
|
return function(chunk, err)
|
||||||
|
local ret, err_or_new = snk(chunk, err)
|
||||||
|
if not ret then return nil, err_or_new end
|
||||||
|
snk = err_or_new or snk
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creates a file sink
|
||||||
|
function sink.file(handle, io_err)
|
||||||
|
if handle then
|
||||||
|
return function(chunk, err)
|
||||||
|
if not chunk then
|
||||||
|
handle:close()
|
||||||
|
return 1
|
||||||
|
else return handle:write(chunk) end
|
||||||
|
end
|
||||||
|
else return sink.error(io_err or "unable to open file") end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creates a sink that discards data
|
||||||
|
local function null()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function sink.null()
|
||||||
|
return null
|
||||||
|
end
|
||||||
|
|
||||||
|
-- creates a sink that just returns an error
|
||||||
|
function sink.error(err)
|
||||||
|
return function()
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- chains a sink with one or several filter(s)
|
||||||
|
function sink.chain(f, snk, ...)
|
||||||
|
if ... then
|
||||||
|
local args = { f, snk, ... }
|
||||||
|
snk = table.remove(args, #args)
|
||||||
|
f = filter.chain(unpack(args))
|
||||||
|
end
|
||||||
|
base.assert(f and snk)
|
||||||
|
return function(chunk, err)
|
||||||
|
if chunk ~= "" then
|
||||||
|
local filtered = f(chunk)
|
||||||
|
local done = chunk and ""
|
||||||
|
while true do
|
||||||
|
local ret, snkerr = snk(filtered, err)
|
||||||
|
if not ret then return nil, snkerr end
|
||||||
|
if filtered == done then return 1 end
|
||||||
|
filtered = f(done)
|
||||||
|
end
|
||||||
|
else return 1 end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Pump stuff
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- pumps one chunk from the source to the sink
|
||||||
|
function pump.step(src, snk)
|
||||||
|
local chunk, src_err = src()
|
||||||
|
local ret, snk_err = snk(chunk, src_err)
|
||||||
|
if chunk and ret then return 1
|
||||||
|
else return nil, src_err or snk_err end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- pumps all data from a source to a sink, using a step function
|
||||||
|
function pump.all(src, snk, step)
|
||||||
|
base.assert(src and snk)
|
||||||
|
step = step or pump.step
|
||||||
|
while true do
|
||||||
|
local ret, err = step(src, snk)
|
||||||
|
if not ret then
|
||||||
|
if err then return nil, err
|
||||||
|
else return 1 end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return _M
|
610
Me_Lua/h10/luci/controller/admin/network.lua
Normal file
610
Me_Lua/h10/luci/controller/admin/network.lua
Normal file
@ -0,0 +1,610 @@
|
|||||||
|
--[[
|
||||||
|
LuCI - Lua Configuration Interface
|
||||||
|
|
||||||
|
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||||
|
Copyright 2011 Jo-Philipp Wich <xm@subsignal.org>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
]]--
|
||||||
|
|
||||||
|
module("luci.controller.admin.network", package.seeall)
|
||||||
|
|
||||||
|
function index()
|
||||||
|
local uci = require("luci.model.uci").cursor()
|
||||||
|
local page
|
||||||
|
|
||||||
|
page = node("admin", "network")
|
||||||
|
page.target = firstchild()
|
||||||
|
page.title = _("Network")
|
||||||
|
page.order = 50
|
||||||
|
page.index = true
|
||||||
|
|
||||||
|
-- if page.inreq then
|
||||||
|
local has_switch = false
|
||||||
|
|
||||||
|
uci:foreach("network", "switch",
|
||||||
|
function(s)
|
||||||
|
has_switch = true
|
||||||
|
return false
|
||||||
|
end)
|
||||||
|
|
||||||
|
if has_switch then
|
||||||
|
page = node("admin", "network", "vlan")
|
||||||
|
page.target = cbi("admin_network/vlan")
|
||||||
|
page.title = _("Switch")
|
||||||
|
page.order = 20
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local has_wifi = false
|
||||||
|
|
||||||
|
uci:foreach("wireless", "wifi-device",
|
||||||
|
function(s)
|
||||||
|
has_wifi = true
|
||||||
|
return false
|
||||||
|
end)
|
||||||
|
|
||||||
|
if has_wifi then
|
||||||
|
page = entry({"admin", "network", "wireless_join"}, call("wifi_join"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "wireless_add"}, call("wifi_add"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "wireless_delete"}, call("wifi_delete"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "wireless_status"}, call("wifi_status"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "getWifiSettings"}, call("getWifiSettings"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "getConnectInfo"}, call("lease_status"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "getUpLoadSpeed"}, call("getUpLoadSpeed"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"admin", "network", "getWanInfo"}, call("getWanInfo"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"admin", "network", "getLanDhcp"}, call("getLanDhcp"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "wireless_reconnect"}, call("wifi_reconnect"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "wireless_shutdown"}, call("wifi_shutdown"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "wireless"}, arcombine(template("admin_network/wifi_overview"), cbi("admin_network/wifi")), _("Wifi"), 15)
|
||||||
|
page.leaf = true
|
||||||
|
page.subindex = true
|
||||||
|
|
||||||
|
if page.inreq then
|
||||||
|
local wdev
|
||||||
|
local net = require "luci.model.network".init(uci)
|
||||||
|
for _, wdev in ipairs(net:get_wifidevs()) do
|
||||||
|
local wnet
|
||||||
|
for _, wnet in ipairs(wdev:get_wifinets()) do
|
||||||
|
entry(
|
||||||
|
{"admin", "network", "wireless", wnet:id()},
|
||||||
|
alias("admin", "network", "wireless"),
|
||||||
|
wdev:name() .. ": " .. wnet:shortname()
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "iface_add"}, cbi("admin_network/iface_add"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "iface_delete"}, call("iface_delete"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "iface_status"}, call("iface_status"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "iface_reconnect"}, call("iface_reconnect"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "iface_shutdown"}, call("iface_shutdown"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "network"}, arcombine(cbi("admin_network/network"), cbi("admin_network/ifaces")), _("Interfaces"), 10)
|
||||||
|
page.leaf = true
|
||||||
|
page.subindex = true
|
||||||
|
|
||||||
|
if page.inreq then
|
||||||
|
uci:foreach("network", "interface",
|
||||||
|
function (section)
|
||||||
|
local ifc = section[".name"]
|
||||||
|
if ifc ~= "loopback" then
|
||||||
|
entry({"admin", "network", "network", ifc},
|
||||||
|
true, ifc:upper())
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if nixio.fs.access("/etc/config/dhcp") then
|
||||||
|
page = node("admin", "network", "dhcp")
|
||||||
|
page.target = cbi("admin_network/dhcp")
|
||||||
|
page.title = _("DHCP and DNS")
|
||||||
|
page.order = 30
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "dhcplease_status"}, call("lease_status"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = node("admin", "network", "hosts")
|
||||||
|
page.target = cbi("admin_network/hosts")
|
||||||
|
page.title = _("Hostnames")
|
||||||
|
page.order = 40
|
||||||
|
end
|
||||||
|
|
||||||
|
page = node("admin", "network", "routes")
|
||||||
|
page.target = cbi("admin_network/routes")
|
||||||
|
page.title = _("Static Routes")
|
||||||
|
page.order = 50
|
||||||
|
|
||||||
|
page = node("admin", "network", "diagnostics")
|
||||||
|
page.target = template("admin_network/diagnostics")
|
||||||
|
page.title = _("Diagnostics")
|
||||||
|
page.order = 60
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "diag_ping"}, call("diag_ping"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "diag_nslookup"}, call("diag_nslookup"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "diag_traceroute"}, call("diag_traceroute"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "diag_ping6"}, call("diag_ping6"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"admin", "network", "diag_traceroute6"}, call("diag_traceroute6"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function wifi_join()
|
||||||
|
local function param(x)
|
||||||
|
return luci.http.formvalue(x)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ptable(x)
|
||||||
|
x = param(x)
|
||||||
|
return x and (type(x) ~= "table" and { x } or x) or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local dev = param("device")
|
||||||
|
local ssid = param("join")
|
||||||
|
|
||||||
|
if dev and ssid then
|
||||||
|
local cancel = (param("cancel") or param("cbi.cancel")) and true or false
|
||||||
|
|
||||||
|
if cancel then
|
||||||
|
luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless_join?device=" .. dev))
|
||||||
|
else
|
||||||
|
local cbi = require "luci.cbi"
|
||||||
|
local tpl = require "luci.template"
|
||||||
|
local map = luci.cbi.load("admin_network/wifi_add")[1]
|
||||||
|
|
||||||
|
if map:parse() ~= cbi.FORM_DONE then
|
||||||
|
tpl.render("header")
|
||||||
|
map:render()
|
||||||
|
tpl.render("footer")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
luci.template.render("admin_network/wifi_join")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function wifi_add()
|
||||||
|
local dev = luci.http.formvalue("device")
|
||||||
|
local ntm = require "luci.model.network".init()
|
||||||
|
|
||||||
|
dev = dev and ntm:get_wifidev(dev)
|
||||||
|
|
||||||
|
if dev then
|
||||||
|
local net = dev:add_wifinet({
|
||||||
|
mode = "ap",
|
||||||
|
ssid = "OpenWrt",
|
||||||
|
encryption = "none"
|
||||||
|
})
|
||||||
|
|
||||||
|
ntm:save("wireless")
|
||||||
|
luci.http.redirect(net:adminlink())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function wifi_delete(network)
|
||||||
|
local ntm = require "luci.model.network".init()
|
||||||
|
local wnet = ntm:get_wifinet(network)
|
||||||
|
if wnet then
|
||||||
|
local dev = wnet:get_device()
|
||||||
|
local nets = wnet:get_networks()
|
||||||
|
if dev then
|
||||||
|
ntm:del_wifinet(network)
|
||||||
|
ntm:commit("wireless")
|
||||||
|
local _, net
|
||||||
|
for _, net in ipairs(nets) do
|
||||||
|
if net:is_empty() then
|
||||||
|
ntm:del_network(net:name())
|
||||||
|
ntm:commit("network")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null")
|
||||||
|
luci.sys.call("env -i /sbin/wifi reload >/dev/null 2>/dev/null")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless"))
|
||||||
|
end
|
||||||
|
|
||||||
|
function iface_status(ifaces)
|
||||||
|
local netm = require "luci.model.network".init()
|
||||||
|
local rv = { }
|
||||||
|
|
||||||
|
local iface
|
||||||
|
for iface in ifaces:gmatch("[%w%.%-_]+") do
|
||||||
|
local net = netm:get_network(iface)
|
||||||
|
local device = net and net:get_interface()
|
||||||
|
if device then
|
||||||
|
local data = {
|
||||||
|
id = iface,
|
||||||
|
proto = net:proto(),
|
||||||
|
uptime = net:uptime(),
|
||||||
|
gwaddr = net:gwaddr(),
|
||||||
|
dnsaddrs = net:dnsaddrs(),
|
||||||
|
name = device:shortname(),
|
||||||
|
type = device:type(),
|
||||||
|
ifname = device:name(),
|
||||||
|
macaddr = device:mac(),
|
||||||
|
is_up = device:is_up(),
|
||||||
|
rx_bytes = device:rx_bytes(),
|
||||||
|
tx_bytes = device:tx_bytes(),
|
||||||
|
rx_packets = device:rx_packets(),
|
||||||
|
tx_packets = device:tx_packets(),
|
||||||
|
|
||||||
|
ipaddrs = { },
|
||||||
|
ip6addrs = { },
|
||||||
|
subdevices = { }
|
||||||
|
}
|
||||||
|
|
||||||
|
local _, a
|
||||||
|
for _, a in ipairs(device:ipaddrs()) do
|
||||||
|
data.ipaddrs[#data.ipaddrs+1] = {
|
||||||
|
addr = a:host():string(),
|
||||||
|
netmask = a:mask():string(),
|
||||||
|
prefix = a:prefix()
|
||||||
|
}
|
||||||
|
end
|
||||||
|
for _, a in ipairs(device:ip6addrs()) do
|
||||||
|
if not a:is6linklocal() then
|
||||||
|
data.ip6addrs[#data.ip6addrs+1] = {
|
||||||
|
addr = a:host():string(),
|
||||||
|
netmask = a:mask():string(),
|
||||||
|
prefix = a:prefix()
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, device in ipairs(net:get_interfaces() or {}) do
|
||||||
|
data.subdevices[#data.subdevices+1] = {
|
||||||
|
name = device:shortname(),
|
||||||
|
type = device:type(),
|
||||||
|
ifname = device:name(),
|
||||||
|
macaddr = device:mac(),
|
||||||
|
macaddr = device:mac(),
|
||||||
|
is_up = device:is_up(),
|
||||||
|
rx_bytes = device:rx_bytes(),
|
||||||
|
tx_bytes = device:tx_bytes(),
|
||||||
|
rx_packets = device:rx_packets(),
|
||||||
|
tx_packets = device:tx_packets(),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
rv[#rv+1] = data
|
||||||
|
else
|
||||||
|
rv[#rv+1] = {
|
||||||
|
id = iface,
|
||||||
|
name = iface,
|
||||||
|
type = "ethernet"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if #rv > 0 then
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
luci.http.write_json(rv)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.status(404, "No such device")
|
||||||
|
end
|
||||||
|
|
||||||
|
function iface_reconnect(iface)
|
||||||
|
local netmd = require "luci.model.network".init()
|
||||||
|
local net = netmd:get_network(iface)
|
||||||
|
if net then
|
||||||
|
luci.sys.call("env -i /sbin/ifup %q >/dev/null 2>/dev/null" % iface)
|
||||||
|
luci.http.status(200, "Reconnected")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.status(404, "No such interface")
|
||||||
|
end
|
||||||
|
|
||||||
|
function iface_shutdown(iface)
|
||||||
|
local netmd = require "luci.model.network".init()
|
||||||
|
local net = netmd:get_network(iface)
|
||||||
|
if net then
|
||||||
|
luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
|
||||||
|
luci.http.status(200, "Shutdown")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.status(404, "No such interface")
|
||||||
|
end
|
||||||
|
|
||||||
|
function iface_delete(iface)
|
||||||
|
local netmd = require "luci.model.network".init()
|
||||||
|
local net = netmd:del_network(iface)
|
||||||
|
if net then
|
||||||
|
luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface)
|
||||||
|
luci.http.redirect(luci.dispatcher.build_url("admin/network/network"))
|
||||||
|
netmd:commit("network")
|
||||||
|
netmd:commit("wireless")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.status(404, "No such interface")
|
||||||
|
end
|
||||||
|
|
||||||
|
function wifi_status(devs)
|
||||||
|
local s = require "luci.tools.status"
|
||||||
|
local rv = { }
|
||||||
|
|
||||||
|
local dev
|
||||||
|
for dev in devs:gmatch("[%w%.%-]+") do
|
||||||
|
rv[#rv+1] = s.wifi_network(dev)
|
||||||
|
end
|
||||||
|
|
||||||
|
if #rv > 0 then
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
luci.http.write_json(rv)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.status(404, "No such device")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wifi_reconnect_shutdown(shutdown, wnet)
|
||||||
|
local netmd = require "luci.model.network".init()
|
||||||
|
local net = netmd:get_wifinet(wnet)
|
||||||
|
local dev = net:get_device()
|
||||||
|
if dev and net then
|
||||||
|
dev:set("disabled", nil)
|
||||||
|
net:set("disabled", shutdown and 1 or nil)
|
||||||
|
netmd:commit("wireless")
|
||||||
|
|
||||||
|
luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null")
|
||||||
|
|
||||||
|
luci.sys.call("env -i /sbin/wifi reload >/dev/null 2>/dev/null")
|
||||||
|
|
||||||
|
luci.http.status(200, shutdown and "Shutdown" or "Reconnected")
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.status(404, "No such radio")
|
||||||
|
end
|
||||||
|
|
||||||
|
function wifi_reconnect(wnet)
|
||||||
|
wifi_reconnect_shutdown(false, wnet)
|
||||||
|
end
|
||||||
|
|
||||||
|
function wifi_shutdown(wnet)
|
||||||
|
wifi_reconnect_shutdown(true, wnet)
|
||||||
|
end
|
||||||
|
|
||||||
|
function wifiNetworks()
|
||||||
|
local result = {}
|
||||||
|
local network = require "luci.model.network".init()
|
||||||
|
local dev
|
||||||
|
for _, dev in ipairs(network:get_wifidevs()) do
|
||||||
|
local rd = {
|
||||||
|
up = dev:is_up(),
|
||||||
|
device = dev:name(),
|
||||||
|
name = dev:get_i18n(),
|
||||||
|
networks = {}
|
||||||
|
}
|
||||||
|
local wifiNet
|
||||||
|
for _, wifiNet in ipairs(dev:get_wifinets()) do
|
||||||
|
rd.networks[#rd.networks+1] = {
|
||||||
|
name = wifiNet:shortname(),
|
||||||
|
up = wifiNet:is_up(),
|
||||||
|
mode = wifiNet:active_mode(),
|
||||||
|
ssid = wifiNet:active_ssid(),
|
||||||
|
bssid = wifiNet:active_bssid(),
|
||||||
|
encryption = wifiNet:active_encryption(),
|
||||||
|
frequency = wifiNet:frequency(),
|
||||||
|
channel = wifiNet:channel(),
|
||||||
|
signal = wifiNet:signal(),
|
||||||
|
quality = wifiNet:signal_percent(),
|
||||||
|
noise = wifiNet:noise(),
|
||||||
|
bitrate = wifiNet:bitrate(),
|
||||||
|
ifname = wifiNet:ifname(),
|
||||||
|
assoclist = wifiNet:assoclist(),
|
||||||
|
country = wifiNet:country(),
|
||||||
|
txpower = wifiNet:txpower(),
|
||||||
|
txpoweroff = wifiNet:txpower_offset(),
|
||||||
|
key = wifiNet:get("key"),
|
||||||
|
key1 = wifiNet:get("key1"),
|
||||||
|
encryption_src = wifiNet:get("encryption"),
|
||||||
|
hidden = wifiNet:get("hidden"),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
result[#result+1] = rd
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function wifiNetwork(wifiDeviceName)
|
||||||
|
local network = require "luci.model.network".init()
|
||||||
|
local wifiNet = network:get_wifinet(wifiDeviceName)
|
||||||
|
if wifiNet then
|
||||||
|
local dev = wifiNet:get_device()
|
||||||
|
if dev then
|
||||||
|
return {
|
||||||
|
id = wifiDeviceName,
|
||||||
|
name = wifiNet:shortname(),
|
||||||
|
up = wifiNet:is_up(),
|
||||||
|
mode = wifiNet:active_mode(),
|
||||||
|
ssid = wifiNet:active_ssid(),
|
||||||
|
bssid = wifiNet:active_bssid(),
|
||||||
|
encryption = wifiNet:active_encryption(),
|
||||||
|
encryption_src = wifiNet:get("encryption"),
|
||||||
|
frequency = wifiNet:frequency(),
|
||||||
|
channel = wifiNet:channel(),
|
||||||
|
signal = wifiNet:signal(),
|
||||||
|
quality = wifiNet:signal_percent(),
|
||||||
|
noise = wifiNet:noise(),
|
||||||
|
bitrate = wifiNet:bitrate(),
|
||||||
|
ifname = wifiNet:ifname(),
|
||||||
|
assoclist = wifiNet:assoclist(),
|
||||||
|
country = wifiNet:country(),
|
||||||
|
txpower = wifiNet:txpower(),
|
||||||
|
txpoweroff = wifiNet:txpower_offset(),
|
||||||
|
key = wifiNet:get("key"),
|
||||||
|
key1 = wifiNet:get("key1"),
|
||||||
|
hidden = wifiNet:get("hidden"),
|
||||||
|
device = {
|
||||||
|
up = dev:is_up(),
|
||||||
|
device = dev:name(),
|
||||||
|
name = dev:get_i18n()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
function getWifiSettings()
|
||||||
|
local infoList = {}
|
||||||
|
local wifis = wifiNetworks()
|
||||||
|
for i,wifiNet in ipairs(wifis) do
|
||||||
|
local item = {}
|
||||||
|
local index = 1
|
||||||
|
if wifiNet["up"] then
|
||||||
|
item["status"] = "1"
|
||||||
|
else
|
||||||
|
item["status"] = "0"
|
||||||
|
end
|
||||||
|
local encryption = wifiNet.networks[index].encryption_src
|
||||||
|
local key = wifiNet.networks[index].key
|
||||||
|
if encryption == "wep-open" then
|
||||||
|
key = wifiNet.networks[index].key1
|
||||||
|
if key:len()>4 and key:sub(0,2)=="s:" then
|
||||||
|
key = key:sub(3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local channel = wifiNet.networks[index].cchannel
|
||||||
|
-- local channelparseinfo = channelHelper(channel)
|
||||||
|
item["ifname"] = wifiNet.networks[index].ifname
|
||||||
|
item["device"] = wifiNet.device..".network"..index
|
||||||
|
item["ssid"] = wifiNet.networks[index].ssid
|
||||||
|
-- item["channel"] = channelparseinfo.channel
|
||||||
|
-- item["channelInfo"] = getBandList(channel)
|
||||||
|
-- item["channelInfo"]["channel"] = wifiNet.networks[index].channel
|
||||||
|
item["mode"] = wifiNet.networks[index].mode
|
||||||
|
item["hidden"] = wifiNet.networks[index].hidden or 0
|
||||||
|
item["signal"] = wifiNet.networks[index].signal
|
||||||
|
item["password"] = key
|
||||||
|
item["encryption"] = encryption
|
||||||
|
infoList[#wifis+1-i] = item
|
||||||
|
end
|
||||||
|
--local guestwifi = getGuestWifi(1)
|
||||||
|
-- if guestwifi then
|
||||||
|
-- table.insert(infoList, guestwifi)
|
||||||
|
-- end
|
||||||
|
--return infoList
|
||||||
|
local result = {}
|
||||||
|
-- local code = 0
|
||||||
|
-- result["info"] = infoList
|
||||||
|
-- result["code"] = code
|
||||||
|
luci.http.write_json(infoList)
|
||||||
|
end
|
||||||
|
|
||||||
|
function lease_status()
|
||||||
|
local s = require "luci.tools.status"
|
||||||
|
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
luci.http.write('[')
|
||||||
|
luci.http.write_json(s.dhcp_leases())
|
||||||
|
luci.http.write(',')
|
||||||
|
luci.http.write_json(s.dhcp6_leases())
|
||||||
|
luci.http.write(']')
|
||||||
|
end
|
||||||
|
|
||||||
|
function switch_status(switches)
|
||||||
|
local s = require "luci.tools.status"
|
||||||
|
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
luci.http.write_json(s.switch_status(switches))
|
||||||
|
end
|
||||||
|
|
||||||
|
function diag_command(cmd, addr)
|
||||||
|
if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then
|
||||||
|
luci.http.prepare_content("text/plain")
|
||||||
|
|
||||||
|
local util = io.popen(cmd % addr)
|
||||||
|
if util then
|
||||||
|
while true do
|
||||||
|
local ln = util:read("*l")
|
||||||
|
if not ln then break end
|
||||||
|
luci.http.write(ln)
|
||||||
|
luci.http.write("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
util:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
luci.http.status(500, "Bad address")
|
||||||
|
end
|
||||||
|
|
||||||
|
function diag_ping(addr)
|
||||||
|
diag_command("ping -c 5 -W 1 %q 2>&1", addr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function diag_traceroute(addr)
|
||||||
|
diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function diag_nslookup(addr)
|
||||||
|
diag_command("nslookup %q 2>&1", addr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function diag_ping6(addr)
|
||||||
|
diag_command("ping6 -c 5 %q 2>&1", addr)
|
||||||
|
end
|
||||||
|
|
||||||
|
function diag_traceroute6(addr)
|
||||||
|
diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr)
|
||||||
|
end
|
||||||
|
|
308
Me_Lua/h10/luci/controller/api/index.lua
Normal file
308
Me_Lua/h10/luci/controller/api/index.lua
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
module("luci.controller.api.index", package.seeall)
|
||||||
|
|
||||||
|
local bfs = require "meizu.bfs"
|
||||||
|
local cjson = require "cjson"
|
||||||
|
local disk = require "meizu.disk"
|
||||||
|
local dlfs = require "meizu.dlfs"
|
||||||
|
local lfs = require "lfs"
|
||||||
|
local lue = require("luci.util").exec
|
||||||
|
local nwfs = require "meizu.nwfs"
|
||||||
|
local RC = require "meizu.r10config"
|
||||||
|
local sipfs = require "meizu.sipfs"
|
||||||
|
local upgdfs = require "meizu.upgdfs"
|
||||||
|
local btfs = require "meizu.btfs"
|
||||||
|
|
||||||
|
b64dec = bfs.b64dec
|
||||||
|
batchfile_checklist = bfs.batchfile_checklist
|
||||||
|
batchfile_compare_upload = bfs.batchfile_compare_upload
|
||||||
|
bind_router = bfs.bind_router
|
||||||
|
data_to_json = bfs.data_to_json
|
||||||
|
exec_cmd_in_sh = bfs.exec_cmd_in_sh
|
||||||
|
exec_reboot = bfs.exec_reboot
|
||||||
|
findInDir = bfs.findInDir
|
||||||
|
get_device_SN = bfs.get_device_SN
|
||||||
|
get_device_version = bfs.get_device_version
|
||||||
|
get_https_data = bfs.get_https_data
|
||||||
|
getFilesList = bfs.getFilesList
|
||||||
|
factory_reset = bfs.factory_reset
|
||||||
|
rts_get_access_token = bfs.rts_get_access_token
|
||||||
|
set_passwd = bfs.set_passwd
|
||||||
|
silent_upgrade = bfs.silent_upgrade
|
||||||
|
|
||||||
|
nw_get_disk_info = disk.nw_get_disk_info
|
||||||
|
disk_formatting = disk.disk_formatting
|
||||||
|
|
||||||
|
sip = sipfs.sip
|
||||||
|
pysip = sipfs.pysip
|
||||||
|
upload_router_log = sipfs.upload_router_log
|
||||||
|
|
||||||
|
nw_check_sys_password = nwfs.nw_check_sys_password
|
||||||
|
nw_get_connect_device_list = nwfs.nw_get_connect_device_list
|
||||||
|
nw_get_device_details = nwfs.nw_get_device_details
|
||||||
|
nw_get_wan_type = nwfs.nw_get_wan_type
|
||||||
|
nw_get_smbswitch = nwfs.nw_get_smbswitch
|
||||||
|
nw_get_wifi_settings = nwfs.nw_get_wifi_settings
|
||||||
|
nw_set_device_name = nwfs.nw_set_device_name
|
||||||
|
nw_set_disk_access = nwfs.nw_set_disk_access
|
||||||
|
nw_set_wan_switch = nwfs.nw_set_wan_switch
|
||||||
|
nw_set_wan_type = nwfs.nw_set_wan_type
|
||||||
|
nw_set_smbswitch = nwfs.nw_set_smbswitch
|
||||||
|
nw_wifi_settings = nwfs.nw_wifi_settings
|
||||||
|
nw_get_tx_power_mode = nwfs.nw_get_tx_power_mode
|
||||||
|
nw_set_tx_power_mode = nwfs.nw_set_tx_power_mode
|
||||||
|
nw_get_wireless_channel = nwfs.nw_get_wireless_channel
|
||||||
|
nw_set_wireless_channel = nwfs.nw_set_wireless_channel
|
||||||
|
|
||||||
|
get_connect_info = nwfs.get_connect_info
|
||||||
|
get_net_device = nwfs.get_net_device
|
||||||
|
real_time_net_speed = nwfs.real_time_net_speed
|
||||||
|
|
||||||
|
nw_scan_ble_switch = btfs.nw_scan_ble_switch
|
||||||
|
nw_get_ble_device_list = btfs.nw_get_ble_device_list
|
||||||
|
nw_add_ble_mesh_device = btfs.nw_add_ble_mesh_device
|
||||||
|
nw_get_ble_device_status = btfs.nw_get_ble_device_status
|
||||||
|
nw_get_mesh_device_list = btfs.nw_get_mesh_device_list
|
||||||
|
nw_remove_ble_from_mesh = btfs.nw_remove_ble_from_mesh
|
||||||
|
nw_dismiss_mesh = btfs.nw_dismiss_mesh
|
||||||
|
nw_set_mesh_device_attr = btfs.nw_set_mesh_device_attr
|
||||||
|
nw_reboot_mesh_device = btfs.nw_reboot_mesh_device
|
||||||
|
nw_unmesh_all_device = btfs.nw_unmesh_all_device
|
||||||
|
nw_set_mesh_device_timer = btfs.nw_set_mesh_device_timer
|
||||||
|
nw_del_mesh_device_timer = btfs.nw_del_mesh_device_timer
|
||||||
|
nw_set_mesh_network_pwd = btfs.nw_set_mesh_network_pwd
|
||||||
|
nw_set_lamp_brightness = btfs.nw_set_lamp_brightness
|
||||||
|
|
||||||
|
check_upgrade = upgdfs.check_upgrade
|
||||||
|
do_upgrade = upgdfs.do_upgrade
|
||||||
|
local_upgrade = upgdfs.local_upgrade
|
||||||
|
|
||||||
|
nw_download_task_operate = dlfs.nw_download_task_operate
|
||||||
|
nw_get_active_list = dlfs.nw_get_active_list
|
||||||
|
nw_get_history_list = dlfs.nw_get_history_list
|
||||||
|
--nw_get_pause_list = dlfs.nw_get_pause_list
|
||||||
|
nw_thunder_get_bind_code = dlfs.nw_thunder_get_bind_code
|
||||||
|
|
||||||
|
nw_download_task_start = dlfs.nw_download_task_start
|
||||||
|
|
||||||
|
function index()
|
||||||
|
--nw: abridged for "Nei Wang"; ww abridged for "Wai Wang"
|
||||||
|
local root = node()
|
||||||
|
if not root.target then
|
||||||
|
root.target = alias("api")
|
||||||
|
root.index = true
|
||||||
|
end
|
||||||
|
local page = node("api")
|
||||||
|
page.target = firstchild()
|
||||||
|
page.title = _("api")
|
||||||
|
page.order = 10
|
||||||
|
page.index = true
|
||||||
|
page.sysauth = "root"
|
||||||
|
page.sysauth_authenticator = "htmlauth"
|
||||||
|
--page = entry({"api", "getUserAccessToken"}, call("get_user_access_token"), nil, nil)
|
||||||
|
--page.leaf = true
|
||||||
|
page = entry({"api", "bindRouter"}, call("bind_router"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
--page = entry({"api", "unbindRouter"}, call("unbind_router"), nil, nil)
|
||||||
|
--page.leaf = true
|
||||||
|
--page = entry({"api", "getDeviceAccessToken"}, call("rts_get_access_token"), nil, nil)
|
||||||
|
--page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "sip"}, call("sip"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "pysip"}, call("pysip"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "getconnectinfo"}, call("get_connect_info"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getWifiSettings"}, call("nw_get_wifi_settings"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getConnectDeviceList"}, call("nw_get_connect_device_list"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getdevicedetails"}, call("nw_get_device_details"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getNetDevice"}, call("get_net_device"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getWanType"}, call("nw_get_wan_type"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "realtimenetspeed"}, call("nw_real_time_net_speed"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setWanType"}, call("nw_set_wan_type"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setDeviceName"}, call("nw_set_device_name"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setDiskAccess"}, call("nw_set_disk_access"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setWanSwitch"}, call("nw_set_wan_switch"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "wifiSettings"}, call("nw_wifi_settings"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "gettxpowermode"}, call("nw_get_tx_power_mode"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "settxpowermode"}, call("nw_set_tx_power_mode"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getWirelessChannel"}, call("nw_get_wireless_channel"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setWirelessChannel"}, call("nw_set_wireless_channel"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "diskinfo"}, call("nw_get_disk_info"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "diskformat"}, call("disk_formatting"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "factoryreset"}, call("factory_reset"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "reboot"}, call("nw_exec_reboot"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "localupgrade"}, call("local_upgrade"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "silentupgrade"}, call("silent_upgrade"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "checkSysPassword"}, call("nw_check_sys_password"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setpasswd"}, call("set_passwd"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "downloadstart"}, call("nw_download_task_start"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getActiveList"}, call("nw_get_active_list"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getHistoryList"}, call("nw_get_history_list"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "operateTask"}, call("nw_download_task_operate"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getPauseList"}, call("nw_get_pause_list"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "thunder_get_bind_code"}, call("nw_thunder_get_bind_code"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "batchFileCompareUpload"}, call("batchfile_compare_upload"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "batchFileCheckList"}, call("batchfile_checklist"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getFilesList"}, call("getFilesList"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
--page = entry({"api", "setPPPoE"}, call("set_pppoe"), nil)
|
||||||
|
--page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "checkupgrade"}, call("nw_check_upgrade"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "doupgrade"}, call("nw_do_upgrade"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "setsmbsingleswitch"}, call("setsmbsingleswitch"),nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setsmbswitch"}, call("nw_set_smbswitch"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getsmbsingleswitch"}, call("getsmbsingleswitch"),nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getsmbswitch"}, call("nw_get_smbswitch"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"api", "scanBleSwitch"}, call("nw_scan_ble_switch"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getBleDeviceList"}, call("nw_get_ble_device_list"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "addMeshDevice"}, call("nw_add_ble_mesh_device"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "removeBleFromMesh"}, call("nw_remove_ble_from_mesh"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getMeshDeviceDetail"}, call("nw_get_ble_device_status"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "getMeshDeviceList"}, call("nw_get_mesh_device_list"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "dismissMesh"}, call("nw_dismiss_mesh"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setMeshDeviceAttr"}, call("nw_set_mesh_device_attr"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "rebootMeshDevice"}, call("nw_reboot_mesh_device"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "unmeshAllDevice"}, call("nw_unmesh_all_device"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setMeshDeviceTimer"}, call("nw_set_mesh_device_timer"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "delMeshDeviceTimer"}, call("nw_del_mesh_device_timer"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setMeshNetWorkPassword"}, call("nw_set_mesh_network_pwd"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"api", "setLampBrightness"}, call("nw_set_lamp_brightness"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_check_upgrade()
|
||||||
|
local ret = check_upgrade()
|
||||||
|
luci.http.write(ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_do_upgrade()
|
||||||
|
local ret = {}
|
||||||
|
luci.http.status(200, "upgrading....")
|
||||||
|
ret["code"] = 2004
|
||||||
|
ret["result"] = "upgrading...."
|
||||||
|
luci.http.write(data_to_json(ret))
|
||||||
|
do_upgrade()
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_real_time_net_speed()
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
local result = real_time_net_speed()
|
||||||
|
luci.http.write_json(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
function setsmbsingleswitch()
|
||||||
|
--local mac = luci.http.formvalue("mac")
|
||||||
|
--generate a white/black list to store this mac.
|
||||||
|
--if you want a mac not rw hdd, then write his mac into deny list.
|
||||||
|
--if you want a mac rw hdd, write his mac into allow list.
|
||||||
|
--modify smb.conf to ban this user's access.
|
||||||
|
--restart samba service
|
||||||
|
end
|
||||||
|
|
||||||
|
function setsmbswitch()
|
||||||
|
local result = {}
|
||||||
|
local code = false
|
||||||
|
local onoff = luci.http.formvalue("smbswitch")
|
||||||
|
if (tonumber)(onoff) == 1 then
|
||||||
|
luci.sys.init.enable("samba")
|
||||||
|
exec_cmd_in_sh("sleep 1")
|
||||||
|
if luci.sys.init.enabled("samba") == true then
|
||||||
|
code = true
|
||||||
|
else
|
||||||
|
code = false
|
||||||
|
end
|
||||||
|
elseif (tonumber)(onoff) == 0 then
|
||||||
|
luci.sys.init.disable("samba")
|
||||||
|
exec_cmd_in_sh("sleep 1")
|
||||||
|
if luci.sys.init.enabled("samba") == true then
|
||||||
|
code = false
|
||||||
|
else
|
||||||
|
code = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result["result"] = code
|
||||||
|
luci.http.write_json(result)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function getsmbsingleswitch()
|
||||||
|
--
|
||||||
|
end
|
||||||
|
|
||||||
|
function getsmbswitch()
|
||||||
|
local smbswitch = {}
|
||||||
|
local code = false
|
||||||
|
code = luci.sys.init.enabled("samba")
|
||||||
|
smbswitch["smbswitch"] = code
|
||||||
|
luci.http.write_json(smbswitch)
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_exec_reboot()
|
||||||
|
local ret = {}
|
||||||
|
ret["result"] = true
|
||||||
|
luci.http.write_json(ret)
|
||||||
|
exec_reboot()
|
||||||
|
end
|
149
Me_Lua/h10/luci/controller/bs/index.lua
Normal file
149
Me_Lua/h10/luci/controller/bs/index.lua
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
module("luci.controller.bs.index", package.seeall)
|
||||||
|
|
||||||
|
|
||||||
|
local arpmon = require "meizu.arpmon"
|
||||||
|
local bfs = require "meizu.bfs"
|
||||||
|
local btfs = require "meizu.btfs"
|
||||||
|
|
||||||
|
nw_get_bluetooth_info = btfs.nw_get_bluetooth_info
|
||||||
|
new_device_notify = arpmon.new_device_notify
|
||||||
|
|
||||||
|
function index()
|
||||||
|
local root = node()
|
||||||
|
if not root.target then
|
||||||
|
root.target = alias("bs")
|
||||||
|
root.index = true
|
||||||
|
end
|
||||||
|
local page = node("bs")
|
||||||
|
--page.target = firstchild()
|
||||||
|
page.title = _("bs")
|
||||||
|
page.order = 10
|
||||||
|
page.index = true
|
||||||
|
page = entry({"bs", "info"}, call("info"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"bs", "token"}, call("token"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"bs", "newdevicenotify"}, call("new_device_notify"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"bs", "devip"}, call("devip"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"bs", "testip"}, call("testip"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"bs", "normip"}, call("normip"), nil, nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"bs", "apk"}, call("apk"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"bs", "getToken"}, call("get_token"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
page = entry({"bs", "sysauth"}, call("sysauth"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
page = entry({"bs", "getBluetoothInfo"}, call("nw_get_bluetooth_info"), nil)
|
||||||
|
page.leaf = true
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function info()
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
local result = bfs.sysinfo()
|
||||||
|
luci.http.write_json(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
function token()
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
local httpHandler = require("socket.http")
|
||||||
|
local usernm = luci.http.formvalue("username")
|
||||||
|
local passwd = luci.http.formvalue("password")
|
||||||
|
if usernm == nil and passwd == nil then
|
||||||
|
local sauth = require "luci.sauth"
|
||||||
|
local token = sauth.noAuthGetToken()
|
||||||
|
if token then
|
||||||
|
luci.http.write_json(token)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local ret = luci.sys.user.checkpasswd(usernm, passwd)
|
||||||
|
if ret == true then
|
||||||
|
local sauth = require "luci.sauth"
|
||||||
|
local token = sauth.noAuthGetToken()
|
||||||
|
if token then
|
||||||
|
luci.http.write_json(token)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function show_hosts()
|
||||||
|
local lue = require"luci.util".exec
|
||||||
|
local cmd = "cat /etc/hosts"
|
||||||
|
local ret = lue(cmd)
|
||||||
|
luci.http.write(ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
function devip()
|
||||||
|
local lue = require"luci.util".exec
|
||||||
|
local cmd = "/usr/sbin/mzrts_ips.sh devip"
|
||||||
|
local ret = lue(cmd)
|
||||||
|
show_hosts()
|
||||||
|
end
|
||||||
|
|
||||||
|
function normip()
|
||||||
|
local lue = require"luci.util".exec
|
||||||
|
local cmd = "/usr/sbin/mzrts_ips.sh"
|
||||||
|
local ret = lue(cmd)
|
||||||
|
show_hosts()
|
||||||
|
end
|
||||||
|
|
||||||
|
function testip()
|
||||||
|
local lue = require"luci.util".exec
|
||||||
|
local cmd = "/usr/sbin/mzrts_ips.sh testip"
|
||||||
|
local ret = lue(cmd)
|
||||||
|
show_hosts()
|
||||||
|
end
|
||||||
|
|
||||||
|
function apk()
|
||||||
|
local fn, fd, block
|
||||||
|
local cmd = "ls /www/apk_download/apk/*.apk | awk '{printf $1}'"
|
||||||
|
fd = io.popen(cmd)
|
||||||
|
fn = fd:read("*l")
|
||||||
|
fd:close()
|
||||||
|
if fn ~= nil then
|
||||||
|
fd = nixio.open(fn, "r")
|
||||||
|
luci.http.header('Content-Disposition', 'attachment; filename="%s"' % {nixio.fs.basename(fn)})
|
||||||
|
luci.http.prepare_content("application/octet-stream")
|
||||||
|
while true do
|
||||||
|
block = fd:read(nixio.const.buffersize)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if (not block) or (#block == 0) then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
luci.http.write(block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fd:close()
|
||||||
|
end
|
||||||
|
luci.http.close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function sysauth()
|
||||||
|
local res = {}
|
||||||
|
local usernm = luci.http.formvalue("username")
|
||||||
|
local passwd = luci.http.formvalue("password")
|
||||||
|
res["result"] = luci.sys.user.checkpasswd(usernm, passwd)
|
||||||
|
luci.http.write_json(res)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_token()
|
||||||
|
local res = {}
|
||||||
|
local sauth = require "luci.sauth"
|
||||||
|
local sess = luci.http.getcookie("sysauth")
|
||||||
|
sess = sess and sess:match("^[a-f0-9]*$")
|
||||||
|
local sdat = sauth.read(sess)
|
||||||
|
res["sysauth"] = sess
|
||||||
|
res["token"] = sdat.token
|
||||||
|
luci.http.write_json(res)
|
||||||
|
end
|
965
Me_Lua/h10/luci/dispatcher.lua
Normal file
965
Me_Lua/h10/luci/dispatcher.lua
Normal file
@ -0,0 +1,965 @@
|
|||||||
|
--[[
|
||||||
|
LuCI - Dispatcher
|
||||||
|
|
||||||
|
Description:
|
||||||
|
The request dispatcher and module dispatcher generators
|
||||||
|
|
||||||
|
FileId:
|
||||||
|
$Id$
|
||||||
|
|
||||||
|
License:
|
||||||
|
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
]]--
|
||||||
|
|
||||||
|
--- LuCI web dispatcher.
|
||||||
|
local fs = require "nixio.fs"
|
||||||
|
local sys = require "luci.sys"
|
||||||
|
local init = require "luci.init"
|
||||||
|
local util = require "luci.util"
|
||||||
|
local http = require "luci.http"
|
||||||
|
local nixio = require "nixio", require "nixio.util"
|
||||||
|
|
||||||
|
module("luci.dispatcher", package.seeall)
|
||||||
|
context = util.threadlocal()
|
||||||
|
uci = require "luci.model.uci"
|
||||||
|
i18n = require "luci.i18n"
|
||||||
|
_M.fs = fs
|
||||||
|
|
||||||
|
authenticator = {}
|
||||||
|
|
||||||
|
-- Index table
|
||||||
|
local index = nil
|
||||||
|
|
||||||
|
-- Fastindex
|
||||||
|
local fi
|
||||||
|
|
||||||
|
|
||||||
|
--- Build the URL relative to the server webroot from given virtual path.
|
||||||
|
-- @param ... Virtual path
|
||||||
|
-- @return Relative URL
|
||||||
|
function build_url(...)
|
||||||
|
local path = {...}
|
||||||
|
local url = { http.getenv("SCRIPT_NAME") or "" }
|
||||||
|
|
||||||
|
local k, v
|
||||||
|
for k, v in pairs(context.urltoken) do
|
||||||
|
url[#url+1] = "/;"
|
||||||
|
url[#url+1] = http.urlencode(k)
|
||||||
|
url[#url+1] = "="
|
||||||
|
url[#url+1] = http.urlencode(v)
|
||||||
|
end
|
||||||
|
|
||||||
|
local p
|
||||||
|
for _, p in ipairs(path) do
|
||||||
|
if p:match("^[a-zA-Z0-9_%-%.%%/,;]+$") then
|
||||||
|
url[#url+1] = "/"
|
||||||
|
url[#url+1] = p
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.concat(url, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check whether a dispatch node shall be visible
|
||||||
|
-- @param node Dispatch node
|
||||||
|
-- @return Boolean indicating whether the node should be visible
|
||||||
|
function node_visible(node)
|
||||||
|
if node then
|
||||||
|
return not (
|
||||||
|
(not node.title or #node.title == 0) or
|
||||||
|
(not node.target or node.hidden == true) or
|
||||||
|
(type(node.target) == "table" and node.target.type == "firstchild" and
|
||||||
|
(type(node.nodes) ~= "table" or not next(node.nodes)))
|
||||||
|
)
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Return a sorted table of visible childs within a given node
|
||||||
|
-- @param node Dispatch node
|
||||||
|
-- @return Ordered table of child node names
|
||||||
|
function node_childs(node)
|
||||||
|
local rv = { }
|
||||||
|
if node then
|
||||||
|
local k, v
|
||||||
|
for k, v in util.spairs(node.nodes,
|
||||||
|
function(a, b)
|
||||||
|
return (node.nodes[a].order or 100)
|
||||||
|
< (node.nodes[b].order or 100)
|
||||||
|
end)
|
||||||
|
do
|
||||||
|
if node_visible(v) then
|
||||||
|
rv[#rv+1] = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return rv
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Send a 404 error code and render the "error404" template if available.
|
||||||
|
-- @param message Custom error message (optional)
|
||||||
|
-- @return false
|
||||||
|
function error404(message)
|
||||||
|
luci.http.status(404, "Not Found")
|
||||||
|
message = message or "Not Found"
|
||||||
|
|
||||||
|
require("luci.template")
|
||||||
|
if not luci.util.copcall(luci.template.render, "error404") then
|
||||||
|
luci.http.prepare_content("text/plain")
|
||||||
|
luci.http.write(message)
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Send a 500 error code and render the "error500" template if available.
|
||||||
|
-- @param message Custom error message (optional)#
|
||||||
|
-- @return false
|
||||||
|
function error500(message)
|
||||||
|
luci.util.perror(message)
|
||||||
|
if not context.template_header_sent then
|
||||||
|
luci.http.status(500, "Internal Server Error")
|
||||||
|
luci.http.prepare_content("text/plain")
|
||||||
|
luci.http.write(message)
|
||||||
|
else
|
||||||
|
require("luci.template")
|
||||||
|
if not luci.util.copcall(luci.template.render, "error500", {message=message}) then
|
||||||
|
luci.http.prepare_content("text/plain")
|
||||||
|
luci.http.write(message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function authenticator.htmlauth(validator, accs, default)
|
||||||
|
local user = luci.http.formvalue("username")
|
||||||
|
local pass = luci.http.formvalue("password")
|
||||||
|
|
||||||
|
if user and validator(user, pass) then
|
||||||
|
return user
|
||||||
|
end
|
||||||
|
|
||||||
|
require("luci.i18n")
|
||||||
|
require("luci.template")
|
||||||
|
context.path = {}
|
||||||
|
luci.template.render("sysauth", {duser=default, fuser=user})
|
||||||
|
return false
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Dispatch an HTTP request.
|
||||||
|
-- @param request LuCI HTTP Request object
|
||||||
|
function httpdispatch(request, prefix)
|
||||||
|
luci.http.context.request = request
|
||||||
|
|
||||||
|
local r = {}
|
||||||
|
context.request = r
|
||||||
|
context.urltoken = {}
|
||||||
|
|
||||||
|
local pathinfo = http.urldecode(request:getenv("PATH_INFO") or "", true)
|
||||||
|
|
||||||
|
if prefix then
|
||||||
|
for _, node in ipairs(prefix) do
|
||||||
|
r[#r+1] = node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local tokensok = true
|
||||||
|
for node in pathinfo:gmatch("[^/]+") do
|
||||||
|
local tkey, tval
|
||||||
|
if tokensok then
|
||||||
|
tkey, tval = node:match(";(%w+)=([a-fA-F0-9]*)")
|
||||||
|
end
|
||||||
|
if tkey then
|
||||||
|
context.urltoken[tkey] = tval
|
||||||
|
else
|
||||||
|
tokensok = false
|
||||||
|
r[#r+1] = node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local stat, err = util.coxpcall(function()
|
||||||
|
dispatch(context.request)
|
||||||
|
end, error500)
|
||||||
|
|
||||||
|
luci.http.close()
|
||||||
|
|
||||||
|
--context._disable_memtrace()
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Dispatches a LuCI virtual path.
|
||||||
|
-- @param request Virtual path
|
||||||
|
function dispatch(request)
|
||||||
|
--context._disable_memtrace = require "luci.debug".trap_memtrace("l")
|
||||||
|
require "MZLog".log(3, request)
|
||||||
|
local ctx = context
|
||||||
|
ctx.path = request
|
||||||
|
|
||||||
|
local conf = require "luci.config"
|
||||||
|
assert(conf.main,
|
||||||
|
"/etc/config/luci seems to be corrupt, unable to find section 'main'")
|
||||||
|
|
||||||
|
local lang = conf.main.lang or "auto"
|
||||||
|
if lang == "auto" then
|
||||||
|
lang = "zh_cn"
|
||||||
|
--[[
|
||||||
|
[local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or ""
|
||||||
|
[for lpat in aclang:gmatch("[%w-]+") do
|
||||||
|
[ lpat = lpat and lpat:gsub("-", "_")
|
||||||
|
[ if conf.languages[lpat] then
|
||||||
|
[ lang = lpat
|
||||||
|
[ break
|
||||||
|
[ end
|
||||||
|
[end
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
require "luci.i18n".setlanguage(lang)
|
||||||
|
|
||||||
|
local c = ctx.tree
|
||||||
|
local stat
|
||||||
|
if not c then
|
||||||
|
c = createtree()
|
||||||
|
end
|
||||||
|
|
||||||
|
local track = {}
|
||||||
|
local args = {}
|
||||||
|
ctx.args = args
|
||||||
|
ctx.requestargs = ctx.requestargs or args
|
||||||
|
local n
|
||||||
|
local token = ctx.urltoken
|
||||||
|
local preq = {}
|
||||||
|
local freq = {}
|
||||||
|
|
||||||
|
for i, s in ipairs(request) do
|
||||||
|
preq[#preq+1] = s
|
||||||
|
freq[#freq+1] = s
|
||||||
|
c = c.nodes[s]
|
||||||
|
n = i
|
||||||
|
if not c then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
util.update(track, c)
|
||||||
|
|
||||||
|
if c.leaf then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if c and c.leaf then
|
||||||
|
for j=n+1, #request do
|
||||||
|
args[#args+1] = request[j]
|
||||||
|
freq[#freq+1] = request[j]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ctx.requestpath = ctx.requestpath or freq
|
||||||
|
ctx.path = preq
|
||||||
|
|
||||||
|
if track.i18n then
|
||||||
|
i18n.loadc(track.i18n)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Init template engine
|
||||||
|
if (c and c.index) or not track.notemplate then
|
||||||
|
local tpl = require("luci.template")
|
||||||
|
local media = track.mediaurlbase or luci.config.main.mediaurlbase
|
||||||
|
if not pcall(tpl.Template, "themes/%s/header" % fs.basename(media)) then
|
||||||
|
media = nil
|
||||||
|
for name, theme in pairs(luci.config.themes) do
|
||||||
|
if name:sub(1,1) ~= "." and pcall(tpl.Template,
|
||||||
|
"themes/%s/header" % fs.basename(theme)) then
|
||||||
|
media = theme
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assert(media, "No valid theme found")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _ifattr(cond, key, val)
|
||||||
|
if cond then
|
||||||
|
local env = getfenv(3)
|
||||||
|
local scope = (type(env.self) == "table") and env.self
|
||||||
|
return string.format(
|
||||||
|
' %s="%s"', tostring(key),
|
||||||
|
luci.util.pcdata(tostring( val
|
||||||
|
or (type(env[key]) ~= "function" and env[key])
|
||||||
|
or (scope and type(scope[key]) ~= "function" and scope[key])
|
||||||
|
or "" ))
|
||||||
|
)
|
||||||
|
else
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tpl.context.viewns = setmetatable({
|
||||||
|
write = luci.http.write;
|
||||||
|
include = function(name) tpl.Template(name):render(getfenv(2)) end;
|
||||||
|
translate = i18n.translate;
|
||||||
|
translatef = i18n.translatef;
|
||||||
|
export = function(k, v) if tpl.context.viewns[k] == nil then tpl.context.viewns[k] = v end end;
|
||||||
|
striptags = util.striptags;
|
||||||
|
pcdata = util.pcdata;
|
||||||
|
media = media;
|
||||||
|
theme = fs.basename(media);
|
||||||
|
resource = luci.config.main.resourcebase;
|
||||||
|
ifattr = function(...) return _ifattr(...) end;
|
||||||
|
attr = function(...) return _ifattr(true, ...) end;
|
||||||
|
}, {__index=function(table, key)
|
||||||
|
if key == "controller" then
|
||||||
|
return build_url()
|
||||||
|
elseif key == "REQUEST_URI" then
|
||||||
|
return build_url(unpack(ctx.requestpath))
|
||||||
|
else
|
||||||
|
return rawget(table, key) or _G[key]
|
||||||
|
end
|
||||||
|
end})
|
||||||
|
end
|
||||||
|
|
||||||
|
track.dependent = (track.dependent ~= false)
|
||||||
|
assert(not track.dependent or not track.auto,
|
||||||
|
"Access Violation\nThe page at '" .. table.concat(request, "/") .. "/' " ..
|
||||||
|
"has no parent node so the access to this location has been denied.\n" ..
|
||||||
|
"This is a software bug, please report this message at " ..
|
||||||
|
"http://luci.subsignal.org/trac/newticket"
|
||||||
|
)
|
||||||
|
|
||||||
|
local isremote = http.getenv("REMOTE_ADDR") == "127.0.0.1"
|
||||||
|
|
||||||
|
if not isremote and track.sysauth then
|
||||||
|
local sauth = require "luci.sauth"
|
||||||
|
|
||||||
|
local authen = type(track.sysauth_authenticator) == "function"
|
||||||
|
and track.sysauth_authenticator
|
||||||
|
or authenticator[track.sysauth_authenticator]
|
||||||
|
|
||||||
|
local def = (type(track.sysauth) == "string") and track.sysauth
|
||||||
|
local accs = def and {track.sysauth} or track.sysauth
|
||||||
|
local sess = ctx.authsession
|
||||||
|
local verifytoken = false
|
||||||
|
if not sess then
|
||||||
|
sess = luci.http.getcookie("sysauth")
|
||||||
|
sess = sess and sess:match("^[a-f0-9]*$")
|
||||||
|
verifytoken = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local sdat = sauth.read(sess)
|
||||||
|
local user
|
||||||
|
|
||||||
|
if sdat then
|
||||||
|
if not verifytoken or ctx.urltoken.stok == sdat.token then
|
||||||
|
user = sdat.user
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local eu = http.getenv("HTTP_AUTH_USER")
|
||||||
|
local ep = http.getenv("HTTP_AUTH_PASS")
|
||||||
|
if eu and ep and luci.sys.user.checkpasswd(eu, ep) then
|
||||||
|
authen = function() return eu end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not util.contains(accs, user) then
|
||||||
|
if authen then
|
||||||
|
ctx.urltoken.stok = nil
|
||||||
|
local user, sess = authen(luci.sys.user.checkpasswd, accs, def)
|
||||||
|
if not user or not util.contains(accs, user) then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
local sid = sess or luci.sys.uniqueid(16)
|
||||||
|
if not sess then
|
||||||
|
local token = luci.sys.uniqueid(16)
|
||||||
|
sauth.reap()
|
||||||
|
sauth.write(sid, {
|
||||||
|
user=user,
|
||||||
|
token=token,
|
||||||
|
secret=luci.sys.uniqueid(16)
|
||||||
|
})
|
||||||
|
ctx.urltoken.stok = token
|
||||||
|
end
|
||||||
|
luci.http.header("Set-Cookie", "sysauth=" .. sid.."; path="..build_url())
|
||||||
|
ctx.authsession = sid
|
||||||
|
ctx.authuser = user
|
||||||
|
end
|
||||||
|
else
|
||||||
|
luci.http.status(403, "Forbidden")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
ctx.authsession = sess
|
||||||
|
ctx.authuser = user
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if track.setgroup then
|
||||||
|
luci.sys.process.setgroup(track.setgroup)
|
||||||
|
end
|
||||||
|
|
||||||
|
if track.setuser then
|
||||||
|
luci.sys.process.setuser(track.setuser)
|
||||||
|
end
|
||||||
|
|
||||||
|
local target = nil
|
||||||
|
if c then
|
||||||
|
if type(c.target) == "function" then
|
||||||
|
target = c.target
|
||||||
|
elseif type(c.target) == "table" then
|
||||||
|
target = c.target.target
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if c and (c.index or type(target) == "function") then
|
||||||
|
ctx.dispatched = c
|
||||||
|
ctx.requested = ctx.requested or ctx.dispatched
|
||||||
|
end
|
||||||
|
|
||||||
|
if c and c.index then
|
||||||
|
local tpl = require "luci.template"
|
||||||
|
|
||||||
|
if util.copcall(tpl.render, "indexer", {}) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(target) == "function" then
|
||||||
|
util.copcall(function()
|
||||||
|
local oldenv = getfenv(target)
|
||||||
|
local module = require(c.module)
|
||||||
|
local env = setmetatable({}, {__index=
|
||||||
|
|
||||||
|
function(tbl, key)
|
||||||
|
return rawget(tbl, key) or module[key] or oldenv[key]
|
||||||
|
end})
|
||||||
|
|
||||||
|
setfenv(target, env)
|
||||||
|
end)
|
||||||
|
|
||||||
|
local ok, err
|
||||||
|
if type(c.target) == "table" then
|
||||||
|
ok, err = util.copcall(target, c.target, unpack(args))
|
||||||
|
else
|
||||||
|
ok, err = util.copcall(target, unpack(args))
|
||||||
|
end
|
||||||
|
assert(ok,
|
||||||
|
"Failed to execute " .. (type(c.target) == "function" and "function" or c.target.type or "unknown") ..
|
||||||
|
" dispatcher target for entry '/" .. table.concat(request, "/") .. "'.\n" ..
|
||||||
|
"The called action terminated with an exception:\n" .. tostring(err or "(unknown)"))
|
||||||
|
else
|
||||||
|
local root = node()
|
||||||
|
if not root or not root.target then
|
||||||
|
error404("No root node was registered, this usually happens if no module was installed.\n" ..
|
||||||
|
"Install luci-mod-admin-full and retry. " ..
|
||||||
|
"If the module is already installed, try removing the /tmp/luci-indexcache file.")
|
||||||
|
else
|
||||||
|
error404("No page is registered at '/" .. table.concat(request, "/") .. "'.\n" ..
|
||||||
|
"If this url belongs to an extension, make sure it is properly installed.\n" ..
|
||||||
|
"If the extension was recently installed, try removing the /tmp/luci-indexcache file.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Generate the dispatching index using the best possible strategy.
|
||||||
|
function createindex()
|
||||||
|
local path = luci.util.libpath() .. "/controller/"
|
||||||
|
local suff = { ".lua", ".lua.gz" }
|
||||||
|
|
||||||
|
if luci.util.copcall(require, "luci.fastindex") then
|
||||||
|
createindex_fastindex(path, suff)
|
||||||
|
else
|
||||||
|
createindex_plain(path, suff)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Generate the dispatching index using the fastindex C-indexer.
|
||||||
|
-- @param path Controller base directory
|
||||||
|
-- @param suffixes Controller file suffixes
|
||||||
|
function createindex_fastindex(path, suffixes)
|
||||||
|
index = {}
|
||||||
|
|
||||||
|
if not fi then
|
||||||
|
fi = luci.fastindex.new("index")
|
||||||
|
for _, suffix in ipairs(suffixes) do
|
||||||
|
fi.add(path .. "*" .. suffix)
|
||||||
|
fi.add(path .. "*/*" .. suffix)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
fi.scan()
|
||||||
|
|
||||||
|
for k, v in pairs(fi.indexes) do
|
||||||
|
index[v[2]] = v[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Generate the dispatching index using the native file-cache based strategy.
|
||||||
|
-- @param path Controller base directory
|
||||||
|
-- @param suffixes Controller file suffixes
|
||||||
|
function createindex_plain(path, suffixes)
|
||||||
|
local controllers = { }
|
||||||
|
for _, suffix in ipairs(suffixes) do
|
||||||
|
nixio.util.consume((fs.glob(path .. "*" .. suffix)), controllers)
|
||||||
|
nixio.util.consume((fs.glob(path .. "*/*" .. suffix)), controllers)
|
||||||
|
end
|
||||||
|
|
||||||
|
if indexcache then
|
||||||
|
local cachedate = fs.stat(indexcache, "mtime")
|
||||||
|
if cachedate then
|
||||||
|
local realdate = 0
|
||||||
|
for _, obj in ipairs(controllers) do
|
||||||
|
local omtime = fs.stat(obj, "mtime")
|
||||||
|
realdate = (omtime and omtime > realdate) and omtime or realdate
|
||||||
|
end
|
||||||
|
|
||||||
|
if cachedate > realdate then
|
||||||
|
assert(
|
||||||
|
sys.process.info("uid") == fs.stat(indexcache, "uid")
|
||||||
|
and fs.stat(indexcache, "modestr") == "rw-------",
|
||||||
|
"Fatal: Indexcache is not sane!"
|
||||||
|
)
|
||||||
|
|
||||||
|
index = loadfile(indexcache)()
|
||||||
|
return index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
index = {}
|
||||||
|
|
||||||
|
for i,c in ipairs(controllers) do
|
||||||
|
local modname = "luci.controller." .. c:sub(#path+1, #c):gsub("/", ".")
|
||||||
|
for _, suffix in ipairs(suffixes) do
|
||||||
|
modname = modname:gsub(suffix.."$", "")
|
||||||
|
end
|
||||||
|
|
||||||
|
local mod = require(modname)
|
||||||
|
assert(mod ~= true,
|
||||||
|
"Invalid controller file found\n" ..
|
||||||
|
"The file '" .. c .. "' contains an invalid module line.\n" ..
|
||||||
|
"Please verify whether the module name is set to '" .. modname ..
|
||||||
|
"' - It must correspond to the file path!")
|
||||||
|
|
||||||
|
local idx = mod.index
|
||||||
|
assert(type(idx) == "function",
|
||||||
|
"Invalid controller file found\n" ..
|
||||||
|
"The file '" .. c .. "' contains no index() function.\n" ..
|
||||||
|
"Please make sure that the controller contains a valid " ..
|
||||||
|
"index function and verify the spelling!")
|
||||||
|
|
||||||
|
index[modname] = idx
|
||||||
|
end
|
||||||
|
|
||||||
|
if indexcache then
|
||||||
|
local f = nixio.open(indexcache, "w", 600)
|
||||||
|
f:writeall(util.get_bytecode(index))
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create the dispatching tree from the index.
|
||||||
|
-- Build the index before if it does not exist yet.
|
||||||
|
function createtree()
|
||||||
|
if not index then
|
||||||
|
createindex()
|
||||||
|
end
|
||||||
|
|
||||||
|
local ctx = context
|
||||||
|
local tree = {nodes={}, inreq=true}
|
||||||
|
local modi = {}
|
||||||
|
|
||||||
|
ctx.treecache = setmetatable({}, {__mode="v"})
|
||||||
|
ctx.tree = tree
|
||||||
|
ctx.modifiers = modi
|
||||||
|
|
||||||
|
-- Load default translation
|
||||||
|
require "luci.i18n".loadc("base")
|
||||||
|
|
||||||
|
local scope = setmetatable({}, {__index = luci.dispatcher})
|
||||||
|
|
||||||
|
for k, v in pairs(index) do
|
||||||
|
scope._NAME = k
|
||||||
|
setfenv(v, scope)
|
||||||
|
v()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function modisort(a,b)
|
||||||
|
return modi[a].order < modi[b].order
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, v in util.spairs(modi, modisort) do
|
||||||
|
scope._NAME = v.module
|
||||||
|
setfenv(v.func, scope)
|
||||||
|
v.func()
|
||||||
|
end
|
||||||
|
|
||||||
|
return tree
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Register a tree modifier.
|
||||||
|
-- @param func Modifier function
|
||||||
|
-- @param order Modifier order value (optional)
|
||||||
|
function modifier(func, order)
|
||||||
|
context.modifiers[#context.modifiers+1] = {
|
||||||
|
func = func,
|
||||||
|
order = order or 0,
|
||||||
|
module
|
||||||
|
= getfenv(2)._NAME
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Clone a node of the dispatching tree to another position.
|
||||||
|
-- @param path Virtual path destination
|
||||||
|
-- @param clone Virtual path source
|
||||||
|
-- @param title Destination node title (optional)
|
||||||
|
-- @param order Destination node order value (optional)
|
||||||
|
-- @return Dispatching tree node
|
||||||
|
function assign(path, clone, title, order)
|
||||||
|
local obj = node(unpack(path))
|
||||||
|
obj.nodes = nil
|
||||||
|
obj.module = nil
|
||||||
|
|
||||||
|
obj.title = title
|
||||||
|
obj.order = order
|
||||||
|
|
||||||
|
setmetatable(obj, {__index = _create_node(clone)})
|
||||||
|
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a new dispatching node and define common parameters.
|
||||||
|
-- @param path Virtual path
|
||||||
|
-- @param target Target function to call when dispatched.
|
||||||
|
-- @param title Destination node title
|
||||||
|
-- @param order Destination node order value (optional)
|
||||||
|
-- @return Dispatching tree node
|
||||||
|
function entry(path, target, title, order)
|
||||||
|
local c = node(unpack(path))
|
||||||
|
|
||||||
|
c.target = target
|
||||||
|
c.title = title
|
||||||
|
c.order = order
|
||||||
|
c.module = getfenv(2)._NAME
|
||||||
|
|
||||||
|
return c
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Fetch or create a dispatching node without setting the target module or
|
||||||
|
-- enabling the node.
|
||||||
|
-- @param ... Virtual path
|
||||||
|
-- @return Dispatching tree node
|
||||||
|
function get(...)
|
||||||
|
return _create_node({...})
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Fetch or create a new dispatching node.
|
||||||
|
-- @param ... Virtual path
|
||||||
|
-- @return Dispatching tree node
|
||||||
|
function node(...)
|
||||||
|
local c = _create_node({...})
|
||||||
|
|
||||||
|
c.module = getfenv(2)._NAME
|
||||||
|
c.auto = nil
|
||||||
|
|
||||||
|
return c
|
||||||
|
end
|
||||||
|
|
||||||
|
function _create_node(path)
|
||||||
|
if #path == 0 then
|
||||||
|
return context.tree
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = table.concat(path, ".")
|
||||||
|
local c = context.treecache[name]
|
||||||
|
|
||||||
|
if not c then
|
||||||
|
local last = table.remove(path)
|
||||||
|
local parent = _create_node(path)
|
||||||
|
|
||||||
|
c = {nodes={}, auto=true}
|
||||||
|
-- the node is "in request" if the request path matches
|
||||||
|
-- at least up to the length of the node path
|
||||||
|
if parent.inreq and context.path[#path+1] == last then
|
||||||
|
c.inreq = true
|
||||||
|
end
|
||||||
|
parent.nodes[last] = c
|
||||||
|
context.treecache[name] = c
|
||||||
|
end
|
||||||
|
return c
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Subdispatchers --
|
||||||
|
|
||||||
|
function _firstchild()
|
||||||
|
local path = { unpack(context.path) }
|
||||||
|
local name = table.concat(path, ".")
|
||||||
|
local node = context.treecache[name]
|
||||||
|
|
||||||
|
local lowest
|
||||||
|
if node and node.nodes and next(node.nodes) then
|
||||||
|
local k, v
|
||||||
|
for k, v in pairs(node.nodes) do
|
||||||
|
if not lowest or
|
||||||
|
(v.order or 100) < (node.nodes[lowest].order or 100)
|
||||||
|
then
|
||||||
|
lowest = k
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(lowest ~= nil,
|
||||||
|
"The requested node contains no childs, unable to redispatch")
|
||||||
|
|
||||||
|
path[#path+1] = lowest
|
||||||
|
dispatch(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Alias the first (lowest order) page automatically
|
||||||
|
function firstchild()
|
||||||
|
return { type = "firstchild", target = _firstchild }
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a redirect to another dispatching node.
|
||||||
|
-- @param ... Virtual path destination
|
||||||
|
function alias(...)
|
||||||
|
local req = {...}
|
||||||
|
return function(...)
|
||||||
|
for _, r in ipairs({...}) do
|
||||||
|
req[#req+1] = r
|
||||||
|
end
|
||||||
|
|
||||||
|
dispatch(req)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Rewrite the first x path values of the request.
|
||||||
|
-- @param n Number of path values to replace
|
||||||
|
-- @param ... Virtual path to replace removed path values with
|
||||||
|
function rewrite(n, ...)
|
||||||
|
local req = {...}
|
||||||
|
return function(...)
|
||||||
|
local dispatched = util.clone(context.dispatched)
|
||||||
|
|
||||||
|
for i=1,n do
|
||||||
|
table.remove(dispatched, 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, r in ipairs(req) do
|
||||||
|
table.insert(dispatched, i, r)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, r in ipairs({...}) do
|
||||||
|
dispatched[#dispatched+1] = r
|
||||||
|
end
|
||||||
|
|
||||||
|
dispatch(dispatched)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function _call(self, ...)
|
||||||
|
local func = getfenv()[self.name]
|
||||||
|
assert(func ~= nil,
|
||||||
|
'Cannot resolve function "' .. self.name .. '". Is it misspelled or local?')
|
||||||
|
|
||||||
|
assert(type(func) == "function",
|
||||||
|
'The symbol "' .. self.name .. '" does not refer to a function but data ' ..
|
||||||
|
'of type "' .. type(func) .. '".')
|
||||||
|
|
||||||
|
if #self.argv > 0 then
|
||||||
|
return func(unpack(self.argv), ...)
|
||||||
|
else
|
||||||
|
return func(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a function-call dispatching target.
|
||||||
|
-- @param name Target function of local controller
|
||||||
|
-- @param ... Additional parameters passed to the function
|
||||||
|
function call(name, ...)
|
||||||
|
return {type = "call", argv = {...}, name = name, target = _call}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local _template = function(self, ...)
|
||||||
|
require "luci.template".render(self.view)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a template render dispatching target.
|
||||||
|
-- @param name Template to be rendered
|
||||||
|
function template(name)
|
||||||
|
return {type = "template", view = name, target = _template}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function _cbi(self, ...)
|
||||||
|
local cbi = require "luci.cbi"
|
||||||
|
local tpl = require "luci.template"
|
||||||
|
local http = require "luci.http"
|
||||||
|
|
||||||
|
local config = self.config or {}
|
||||||
|
local maps = cbi.load(self.model, ...)
|
||||||
|
|
||||||
|
local state = nil
|
||||||
|
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
res.flow = config
|
||||||
|
local cstate = res:parse()
|
||||||
|
if cstate and (not state or cstate < state) then
|
||||||
|
state = cstate
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _resolve_path(path)
|
||||||
|
return type(path) == "table" and build_url(unpack(path)) or path
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.on_valid_to and state and state > 0 and state < 2 then
|
||||||
|
http.redirect(_resolve_path(config.on_valid_to))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.on_changed_to and state and state > 1 then
|
||||||
|
http.redirect(_resolve_path(config.on_changed_to))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.on_success_to and state and state > 0 then
|
||||||
|
http.redirect(_resolve_path(config.on_success_to))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.state_handler then
|
||||||
|
if not config.state_handler(state, maps) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
http.header("X-CBI-State", state or 0)
|
||||||
|
|
||||||
|
if not config.noheader then
|
||||||
|
tpl.render("cbi/header", {state = state})
|
||||||
|
end
|
||||||
|
|
||||||
|
local redirect
|
||||||
|
local messages
|
||||||
|
local applymap = false
|
||||||
|
local pageaction = true
|
||||||
|
local parsechain = { }
|
||||||
|
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
if res.apply_needed and res.parsechain then
|
||||||
|
local c
|
||||||
|
for _, c in ipairs(res.parsechain) do
|
||||||
|
parsechain[#parsechain+1] = c
|
||||||
|
end
|
||||||
|
applymap = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.redirect then
|
||||||
|
redirect = redirect or res.redirect
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.pageaction == false then
|
||||||
|
pageaction = false
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.message then
|
||||||
|
messages = messages or { }
|
||||||
|
messages[#messages+1] = res.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
res:render({
|
||||||
|
firstmap = (i == 1),
|
||||||
|
applymap = applymap,
|
||||||
|
redirect = redirect,
|
||||||
|
messages = messages,
|
||||||
|
pageaction = pageaction,
|
||||||
|
parsechain = parsechain
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if not config.nofooter then
|
||||||
|
tpl.render("cbi/footer", {
|
||||||
|
flow = config,
|
||||||
|
pageaction = pageaction,
|
||||||
|
redirect = redirect,
|
||||||
|
state = state,
|
||||||
|
autoapply = config.autoapply
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a CBI model dispatching target.
|
||||||
|
-- @param model CBI model to be rendered
|
||||||
|
function cbi(model, config)
|
||||||
|
return {type = "cbi", config = config, model = model, target = _cbi}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function _arcombine(self, ...)
|
||||||
|
local argv = {...}
|
||||||
|
local target = #argv > 0 and self.targets[2] or self.targets[1]
|
||||||
|
setfenv(target.target, self.env)
|
||||||
|
target:target(unpack(argv))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a combined dispatching target for non argv and argv requests.
|
||||||
|
-- @param trg1 Overview Target
|
||||||
|
-- @param trg2 Detail Target
|
||||||
|
function arcombine(trg1, trg2)
|
||||||
|
return {type = "arcombine", env = getfenv(), target = _arcombine, targets = {trg1, trg2}}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function _form(self, ...)
|
||||||
|
local cbi = require "luci.cbi"
|
||||||
|
local tpl = require "luci.template"
|
||||||
|
local http = require "luci.http"
|
||||||
|
|
||||||
|
local maps = luci.cbi.load(self.model, ...)
|
||||||
|
local state = nil
|
||||||
|
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
local cstate = res:parse()
|
||||||
|
if cstate and (not state or cstate < state) then
|
||||||
|
state = cstate
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
http.header("X-CBI-State", state or 0)
|
||||||
|
tpl.render("header")
|
||||||
|
for i, res in ipairs(maps) do
|
||||||
|
res:render()
|
||||||
|
end
|
||||||
|
tpl.render("footer")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a CBI form model dispatching target.
|
||||||
|
-- @param model CBI form model tpo be rendered
|
||||||
|
function form(model)
|
||||||
|
return {type = "cbi", model = model, target = _form}
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Access the luci.i18n translate() api.
|
||||||
|
-- @class function
|
||||||
|
-- @name translate
|
||||||
|
-- @param text Text to translate
|
||||||
|
translate = i18n.translate
|
||||||
|
|
||||||
|
--- No-op function used to mark translation entries for menu labels.
|
||||||
|
-- This function does not actually translate the given argument but
|
||||||
|
-- is used by build/i18n-scan.pl to find translatable entries.
|
||||||
|
function _(text)
|
||||||
|
return text
|
||||||
|
end
|
1632
Me_Lua/h10/luci/model/network.lua
Normal file
1632
Me_Lua/h10/luci/model/network.lua
Normal file
File diff suppressed because it is too large
Load Diff
200
Me_Lua/h10/luci/sauth.lua
Normal file
200
Me_Lua/h10/luci/sauth.lua
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
--[[
|
||||||
|
|
||||||
|
Session authentication
|
||||||
|
(c) 2008 Steven Barth <steven@midlink.org>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
|
||||||
|
]]--
|
||||||
|
|
||||||
|
--- LuCI session library.
|
||||||
|
module("luci.sauth", package.seeall)
|
||||||
|
require("luci.util")
|
||||||
|
require("luci.sys")
|
||||||
|
require("luci.config")
|
||||||
|
local nixio = require "nixio", require "nixio.util"
|
||||||
|
local fs = require "nixio.fs"
|
||||||
|
|
||||||
|
|
||||||
|
luci.config.sauth = luci.config.sauth or {}
|
||||||
|
sessionpath = luci.config.sauth.sessionpath
|
||||||
|
sessiontime = tonumber(luci.config.sauth.sessiontime) or 15 * 60
|
||||||
|
|
||||||
|
--- Prepare session storage by creating the session directory.
|
||||||
|
function prepare()
|
||||||
|
fs.mkdir(sessionpath, 700)
|
||||||
|
if not sane() then
|
||||||
|
error("Security Exception: Session path is not sane!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _read(id)
|
||||||
|
local blob = fs.readfile(sessionpath .. "/" .. id)
|
||||||
|
return blob
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _write(id, data)
|
||||||
|
local tempid = luci.sys.uniqueid(16)
|
||||||
|
local tempfile = sessionpath .. "/" .. tempid
|
||||||
|
local sessfile = sessionpath .. "/" .. id
|
||||||
|
local f = nixio.open(tempfile, "w", 600)
|
||||||
|
f:writeall(data)
|
||||||
|
f:close()
|
||||||
|
fs.rename(tempfile, sessfile)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function _checkid(id)
|
||||||
|
return not not (id and #id == 32 and id:match("^[a-fA-F0-9]+$"))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Write session data to a session file.
|
||||||
|
-- @param id Session identifier
|
||||||
|
-- @param data Session data table
|
||||||
|
function write(id, data)
|
||||||
|
if not sane() then
|
||||||
|
prepare()
|
||||||
|
end
|
||||||
|
|
||||||
|
if not _checkid(id) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(data) ~= "table" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
data.atime = luci.sys.uptime()
|
||||||
|
|
||||||
|
_write(id, luci.util.get_bytecode(data))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Read a session and return its content.
|
||||||
|
-- @param id Session identifier
|
||||||
|
-- @return Session data table or nil if the given id is not found
|
||||||
|
function read(id)
|
||||||
|
if not id or #id == 0 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if not _checkid(id) then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if not sane(sessionpath .. "/" .. id) then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local blob = _read(id)
|
||||||
|
local func = loadstring(blob)
|
||||||
|
setfenv(func, {})
|
||||||
|
|
||||||
|
local sess = func()
|
||||||
|
if type(sess) ~= "table" then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if sess.atime and sess.atime + sessiontime < luci.sys.uptime() then
|
||||||
|
kill(id)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- refresh atime in session
|
||||||
|
write(id, sess)
|
||||||
|
|
||||||
|
return sess
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check whether Session environment is sane.
|
||||||
|
-- @return Boolean status
|
||||||
|
function sane(file)
|
||||||
|
return luci.sys.process.info("uid")
|
||||||
|
== fs.stat(file or sessionpath, "uid")
|
||||||
|
and fs.stat(file or sessionpath, "modestr")
|
||||||
|
== (file and "rw-------" or "rwx------")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Kills a session
|
||||||
|
-- @param id Session identifier
|
||||||
|
function kill(id)
|
||||||
|
if not _checkid(id) then
|
||||||
|
else
|
||||||
|
fs.unlink(sessionpath .. "/" .. id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove all expired session data files
|
||||||
|
function reap()
|
||||||
|
if sane() then
|
||||||
|
local id
|
||||||
|
for id in nixio.fs.dir(sessionpath) do
|
||||||
|
if _checkid(id) then
|
||||||
|
-- reading the session will kill it if it is expired
|
||||||
|
read(id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get available session data
|
||||||
|
function available()
|
||||||
|
if sane() then
|
||||||
|
local id
|
||||||
|
for id in nixio.fs.dir(sessionpath) do
|
||||||
|
if _checkid(id) then
|
||||||
|
-- reading the session will kill it if it is expired
|
||||||
|
local available = read(id)
|
||||||
|
if available then
|
||||||
|
return available
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function genAuthToken()
|
||||||
|
local id = luci.sys.uniqueid(16)
|
||||||
|
local token = luci.sys.uniqueid(16)
|
||||||
|
write(id, {
|
||||||
|
user="root",
|
||||||
|
token=token,
|
||||||
|
secret=luci.sys.uniqueid(16)
|
||||||
|
})
|
||||||
|
return id, read(id)
|
||||||
|
end
|
||||||
|
|
||||||
|
function noAuthGetToken()
|
||||||
|
local id
|
||||||
|
local data
|
||||||
|
local ret = {}
|
||||||
|
if sessionpath then
|
||||||
|
local ids = nixio.fs.dir(sessionpath)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if not ids then
|
||||||
|
genAuthToken()
|
||||||
|
end
|
||||||
|
for id in nixio.fs.dir(sessionpath) do
|
||||||
|
if id then
|
||||||
|
read(id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for id in nixio.fs.dir(sessionpath) do
|
||||||
|
if id then
|
||||||
|
ret["sysauth"] = id
|
||||||
|
ret["data"] = read(id)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
id, data = genAuthToken()
|
||||||
|
ret["sysauth"] = id
|
||||||
|
ret["data"] = read(id)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
end
|
99
Me_Lua/h10/meizu/arpmon.lua
Normal file
99
Me_Lua/h10/meizu/arpmon.lua
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
module("meizu.arpmon", package.seeall)
|
||||||
|
--network functions
|
||||||
|
|
||||||
|
local cjson = require "cjson"
|
||||||
|
local lfs = require "lfs"
|
||||||
|
local bfs = require "meizu.bfs"
|
||||||
|
local dbfs = require "meizu.dbfs"
|
||||||
|
local RC = require "meizu.r10config"
|
||||||
|
local sipfs = require "meizu.sipfs"
|
||||||
|
local nwfs = require "meizu.nwfs"
|
||||||
|
|
||||||
|
local lue = require("luci.util").exec
|
||||||
|
|
||||||
|
local bind_router = bfs.bind_router
|
||||||
|
local data_to_json = bfs.data_to_json
|
||||||
|
local exec_cmd_in_sh = bfs.exec_cmd_in_sh
|
||||||
|
local exec_reboot = bfs.exec_reboot
|
||||||
|
local get_device_SN = bfs.get_device_SN
|
||||||
|
local get_device_version = bfs.get_device_version
|
||||||
|
local get_https_data = bfs.get_https_data
|
||||||
|
local rts_get_access_token = bfs.rts_get_access_token
|
||||||
|
local set_passwd = bfs.set_passwd
|
||||||
|
local silent_upgrade = bfs.silent_upgrade
|
||||||
|
local strsplit = bfs.strsplit
|
||||||
|
|
||||||
|
local delete_arp_all_mac = dbfs.delete_arp_all_mac
|
||||||
|
local fetch_arp_mac = dbfs.fetch_arp_mac
|
||||||
|
local get_dev_nick_name = dbfs.get_dev_nick_name
|
||||||
|
local init_arp_table = dbfs.init_arp_table
|
||||||
|
local insert_arp_macip = dbfs.insert_arp_macip
|
||||||
|
|
||||||
|
function new_device_notify()
|
||||||
|
|
||||||
|
init_arp_table()
|
||||||
|
local ret = {}
|
||||||
|
local cmd = [[cat /proc/net/arp |grep br-lan|awk '{print $1","$4}']]
|
||||||
|
local ipmacs = {}
|
||||||
|
local devs = lue(cmd)
|
||||||
|
if devs ~= "" then
|
||||||
|
ipmacs = strsplit(devs, '\n')
|
||||||
|
end
|
||||||
|
local new_devs = {}
|
||||||
|
ipmacs[#ipmacs] = nil
|
||||||
|
local wifiDeviceDict = nwfs.getAllWifiConnetDeviceDict()
|
||||||
|
for k, v in pairs(ipmacs) do
|
||||||
|
local ipmac = strsplit(v, ',')
|
||||||
|
local ip = ipmac[1]
|
||||||
|
local mac = ipmac[2]
|
||||||
|
mac = string.upper(mac)
|
||||||
|
local wifiType = wifiDeviceDict[mac]
|
||||||
|
local data = dbfs.fetch_wireless_device_mac(mac)
|
||||||
|
if wifiType ~= nil then
|
||||||
|
--local res = dbfs.fetch_wireless_device_mac(mac)
|
||||||
|
if data == "" then
|
||||||
|
dbfs.insert_wireless_device_mac(mac)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local ret = dbfs.fetch_wire_device_mac(mac)
|
||||||
|
local res = nwfs.is_device_online(ip)
|
||||||
|
if res == false and ret == "" and data == "" then
|
||||||
|
dbfs.insert_wireless_device_mac(mac)
|
||||||
|
elseif res == true and ret == "" then
|
||||||
|
dbfs.insert_wire_device_mac(mac, ip)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ip ~= "" then
|
||||||
|
if fetch_arp_mac(mac) == "" then
|
||||||
|
table.insert(new_devs, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
delete_arp_all_mac()
|
||||||
|
for k, v in pairs(ipmacs) do
|
||||||
|
local ipmac = strsplit(v, ',')
|
||||||
|
local ip = ipmac[1]
|
||||||
|
local mac = ipmac[2]
|
||||||
|
if ip ~= "" then
|
||||||
|
insert_arp_macip(mac, ip)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for k, v in pairs(new_devs) do
|
||||||
|
local ipmac = strsplit(v, ',')
|
||||||
|
local ip = ipmac[1]
|
||||||
|
local mac = ipmac[2]
|
||||||
|
if ip ~= "" then
|
||||||
|
local logtype = 1
|
||||||
|
ret["mac_address"] = mac
|
||||||
|
local nickname = get_dev_nick_name(mac)
|
||||||
|
if nickname and nickname ~= "" then
|
||||||
|
ret["name"] = nickname
|
||||||
|
else
|
||||||
|
ret["name"] = ip
|
||||||
|
end
|
||||||
|
local res, code, headers, status = sipfs.upload_router_log(data_to_json(ret), logtype)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
luci.http.write_json(ret)
|
||||||
|
end
|
511
Me_Lua/h10/meizu/bfs.lua
Normal file
511
Me_Lua/h10/meizu/bfs.lua
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
module("meizu.bfs", package.seeall)
|
||||||
|
--API base functions
|
||||||
|
|
||||||
|
local cjson = require "cjson"
|
||||||
|
local dbfs = require "meizu.dbfs"
|
||||||
|
|
||||||
|
local delete_access_token = dbfs.delete_access_token
|
||||||
|
|
||||||
|
function cal_str_md5(str)
|
||||||
|
local md5 = ""
|
||||||
|
local cmd = [[/bin/echo -n ']]..str
|
||||||
|
cmd = cmd..[['|/usr/bin/md5sum|/usr/bin/cut -d" " -f1]]
|
||||||
|
local fd = io.popen(cmd)
|
||||||
|
local ln = fd:read("*l")
|
||||||
|
if ln ~= nil then
|
||||||
|
md5 = ln
|
||||||
|
end
|
||||||
|
fd:close()
|
||||||
|
return md5
|
||||||
|
end
|
||||||
|
|
||||||
|
function strsplit(str, delim, maxNb)
|
||||||
|
local result = {}
|
||||||
|
if delim == nil then
|
||||||
|
delim = '\n'
|
||||||
|
end
|
||||||
|
if string.find(str, delim) == nil then
|
||||||
|
return { str }
|
||||||
|
end
|
||||||
|
if maxNb == nil or maxNb < 1 then
|
||||||
|
maxNb = 0
|
||||||
|
end
|
||||||
|
local pat = "(.-)" .. delim .. "()"
|
||||||
|
local nb = 0
|
||||||
|
local lastPos
|
||||||
|
for part, pos in string.gfind(str, pat) do
|
||||||
|
nb = nb + 1
|
||||||
|
result[nb] = part
|
||||||
|
lastPos = pos
|
||||||
|
if nb == maxNb then break end
|
||||||
|
end
|
||||||
|
if nb ~= maxNb then
|
||||||
|
result[nb + 1] = string.sub(str, lastPos)
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function data_to_json(x)
|
||||||
|
local buf = ""
|
||||||
|
if x == nil then
|
||||||
|
return ""
|
||||||
|
elseif x == "" then
|
||||||
|
return '""'
|
||||||
|
elseif type(x) == "table" then
|
||||||
|
local k, v
|
||||||
|
if type(next(x)) == "number" then
|
||||||
|
buf = buf.."[ "
|
||||||
|
for k, v in ipairs(x) do
|
||||||
|
buf = buf..data_to_json(v)
|
||||||
|
if next(x, k) then
|
||||||
|
buf = buf..", "
|
||||||
|
end
|
||||||
|
end
|
||||||
|
buf = buf.." ]"
|
||||||
|
else
|
||||||
|
buf = buf.."{ "
|
||||||
|
for k, v in pairs(x) do
|
||||||
|
buf = buf..string.format("%q: " % k)
|
||||||
|
buf = buf..data_to_json(v)
|
||||||
|
if next(x, k) then
|
||||||
|
buf = buf..", "
|
||||||
|
end
|
||||||
|
end
|
||||||
|
buf = buf.." }"
|
||||||
|
end
|
||||||
|
elseif type(x) == "number" or type(x) == "boolean" then
|
||||||
|
if (x ~= x) then
|
||||||
|
buf = buf.."Number.NaN"
|
||||||
|
else
|
||||||
|
buf = buf..tostring(x)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
buf = buf..string.format('"%s"' % tostring(x):gsub('[%z\1-\31]', function(c) return '\\u%04x' % c:byte(1) end))
|
||||||
|
end
|
||||||
|
return buf
|
||||||
|
end
|
||||||
|
|
||||||
|
function exec_cmd_in_sh(command)
|
||||||
|
local nio = require("nixio")
|
||||||
|
require "MZLog".log(3, command)
|
||||||
|
local pid = nio.fork()
|
||||||
|
if pid > 0 then
|
||||||
|
return
|
||||||
|
elseif pid == 0 then
|
||||||
|
nio.chdir("/")
|
||||||
|
local null = nio.open("/dev/null", "w+")
|
||||||
|
if null then
|
||||||
|
nio.dup(null, nio.stderr)
|
||||||
|
nio.dup(null, nio.stdout)
|
||||||
|
nio.dup(null, nio.stdin)
|
||||||
|
if null:fileno() > 2 then
|
||||||
|
null:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
nio.exec("/bin/sh", "-c", command)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--local get_https_data = function(url, data) return require("ssl.https").request(url, data) end
|
||||||
|
--return res, code, headers, status
|
||||||
|
function get_https_data(url, data)
|
||||||
|
if data ~= nil then
|
||||||
|
return require("ssl.https").request(url, data)
|
||||||
|
else
|
||||||
|
return require("ssl.https").request(url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function decodeURI(s)
|
||||||
|
local s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
function encodeURI(s)
|
||||||
|
local s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)
|
||||||
|
return string.gsub(s, " ", "+")
|
||||||
|
end
|
||||||
|
|
||||||
|
function b64enc(data)
|
||||||
|
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||||
|
return ((data:gsub('.', function(x)
|
||||||
|
local r,b='',x:byte()
|
||||||
|
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
|
||||||
|
return r;
|
||||||
|
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
|
||||||
|
if (#x < 6) then return '' end
|
||||||
|
local c=0
|
||||||
|
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
|
||||||
|
return b:sub(c+1,c+1)
|
||||||
|
end)..({ '', '==', '=' })[#data%3+1])
|
||||||
|
end
|
||||||
|
|
||||||
|
function b64dec(data)
|
||||||
|
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||||
|
data = string.gsub(data, '[^'..b..'=]', '')
|
||||||
|
return (data:gsub('.', function(x)
|
||||||
|
if (x == '=') then return '' end
|
||||||
|
local r,f='',(b:find(x)-1)
|
||||||
|
for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
|
||||||
|
return r;
|
||||||
|
end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
|
||||||
|
if (#x ~= 8) then return '' end
|
||||||
|
local c=0
|
||||||
|
for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
|
||||||
|
return string.char(c)
|
||||||
|
end))
|
||||||
|
end
|
||||||
|
|
||||||
|
function exec_reboot()
|
||||||
|
--luci.sys.reboot()
|
||||||
|
exec_cmd_in_sh("reboot -f")
|
||||||
|
end
|
||||||
|
|
||||||
|
function factory_reset()
|
||||||
|
--exec_cmd_in_sh("killall dropbear uhttpd; sleep 1; mtd erase nvram; mtd -r erase rootfs_data")
|
||||||
|
local result = {}
|
||||||
|
result["result"] = true
|
||||||
|
luci.http.write_json(result)
|
||||||
|
exec_cmd_in_sh("killall dropbear uhttpd; sleep 1; /sbin/router_reset;/sbin/reboot")
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_passwd()
|
||||||
|
local p1 = luci.http.formvalue("pwd1")
|
||||||
|
local p2 = luci.http.formvalue("pwd2")
|
||||||
|
local stat = nil
|
||||||
|
if p1 ~= nil and luci.sys.user.checkpasswd("root", p1) then
|
||||||
|
if p2 ~= nil then
|
||||||
|
stat = luci.sys.user.setpasswd("root", p2)
|
||||||
|
luci.http.status(200, "setpasswd successful!")
|
||||||
|
luci.http.write("setpasswd successful!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
luci.http.status(500, "Bad passwd!")
|
||||||
|
--luci.http.write("setpasswd failed!")
|
||||||
|
end
|
||||||
|
|
||||||
|
function rts_get_access_token()
|
||||||
|
local dbfs = require "meizu.dbfs"
|
||||||
|
dbfs.init_access_token_table()
|
||||||
|
local dbdata = dbfs.fetch_access_token()
|
||||||
|
local token
|
||||||
|
if #dbdata > 0 then
|
||||||
|
for _, data in ipairs(dbdata) do
|
||||||
|
local tokenFromdb = data.token
|
||||||
|
local expireTimeFromdb = data.expireTime
|
||||||
|
local nowTime = os.time()
|
||||||
|
if expireTimeFromdb < nowTime then
|
||||||
|
require "MZLog".log(3, "expireTime expire")
|
||||||
|
local httpsData = https_get_access_token()
|
||||||
|
token = httpsData.access_token
|
||||||
|
dbfs.update_access_token(tokenFromdb, token, httpsData.expires_in + os.time() - 10)
|
||||||
|
else
|
||||||
|
require "MZLog".log(3, "token from db")
|
||||||
|
token = tokenFromdb
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local httpsData = https_get_access_token()
|
||||||
|
token = httpsData.access_token
|
||||||
|
require "MZLog".log(3, "token from https")
|
||||||
|
dbfs.add_access_token(token, httpsData.expires_in + os.time() - 10)
|
||||||
|
end
|
||||||
|
return token
|
||||||
|
end
|
||||||
|
|
||||||
|
function https_get_access_token()
|
||||||
|
local url = "https://api.meizu.com/oauth/token?scope=router_trust&device="
|
||||||
|
local suffix = "&password=&grant_type=device_only&client_id=gkzyJzq4RPoaov3BamqsJgg&client_secret=yh9bdKurxxotCjrEvJOiumk2mrzhcyej"
|
||||||
|
local SN = get_device_SN()
|
||||||
|
url = url..SN..suffix
|
||||||
|
local res, code, headers, status = get_https_data(url)
|
||||||
|
local data = cjson.decode(res)
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_user_access_token()
|
||||||
|
local res, code, headers, status
|
||||||
|
local url = 'https://api.meizu.com/oauth/token?grant_type=password&client_id=gkzyJzq4RPoaov3BamqsJgg&client_secret=yh9bdKurxxotCjrEvJOiumk2mrzhcyej&username=appadmin@flyme.cn&password=appadmin111&scope=router_trust'
|
||||||
|
local res, code, headers, status = get_https_data(url)
|
||||||
|
local data = cjson.decode(res)
|
||||||
|
return data.access_token
|
||||||
|
end
|
||||||
|
|
||||||
|
function init_bind_router_body(access_token)
|
||||||
|
local body = "access_token="
|
||||||
|
local uat = luci.http.formvalue("uat")
|
||||||
|
body = body..access_token
|
||||||
|
body = body.."&user_access_token="
|
||||||
|
body = body..uat
|
||||||
|
return body
|
||||||
|
end
|
||||||
|
|
||||||
|
function bind_router()
|
||||||
|
local url = "https://router.meizu.com/oauth/router/bindRouter"
|
||||||
|
local access_token = rts_get_access_token()
|
||||||
|
local body = init_bind_router_body(access_token)
|
||||||
|
local https = require("ssl.https")
|
||||||
|
local res, code, headers, status = https.request(url, body)
|
||||||
|
if code == 401 then
|
||||||
|
delete_access_token()
|
||||||
|
access_token = rts_get_access_token()
|
||||||
|
body = init_bind_router_body(access_token)
|
||||||
|
res, code, headers, status = https.request(url, body)
|
||||||
|
end
|
||||||
|
luci.http.write(res)
|
||||||
|
end
|
||||||
|
|
||||||
|
function unbind_router()
|
||||||
|
local url = 'https://router.meizu.com/oauth/user/unbind?access_token='
|
||||||
|
local https = require("ssl.https")
|
||||||
|
local uat = luci.http.formvalue("uat")
|
||||||
|
url = url..uat
|
||||||
|
url = url..'&device='..get_device_SN()
|
||||||
|
local res, code, headers, status = https.request(url)
|
||||||
|
luci.http.write(res)
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_device_SN()
|
||||||
|
local sn = ""
|
||||||
|
local fd = io.popen("nvram get sn")
|
||||||
|
if fd then
|
||||||
|
local ln = fd:read("*l")
|
||||||
|
if ln ~= nil then
|
||||||
|
sn = ln
|
||||||
|
end
|
||||||
|
fd:close()
|
||||||
|
end
|
||||||
|
return sn
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_device_version()
|
||||||
|
local device_version = "1.0.0"
|
||||||
|
--[[
|
||||||
|
[local pcall, dofile = pcall, dofile
|
||||||
|
[if pcall(dofile, "/etc/openwrt_release") then
|
||||||
|
[ if DISTRIB_RELEASE ~= nil then
|
||||||
|
[ device_version = DISTRIB_RELEASE
|
||||||
|
[ end
|
||||||
|
[end
|
||||||
|
]]
|
||||||
|
local lu = require("luci.util")
|
||||||
|
local cmd = [[cat /etc/openwrt_version|awk '{printf $1}']]
|
||||||
|
local v = lu.exec(cmd)
|
||||||
|
if v ~= nil then
|
||||||
|
device_version = v
|
||||||
|
end
|
||||||
|
return device_version
|
||||||
|
end
|
||||||
|
|
||||||
|
function silent_upgrade()
|
||||||
|
local fd = nil
|
||||||
|
local image = "/tmp/firmware.img"
|
||||||
|
local touchcmd = "touch "..image
|
||||||
|
exec_cmd_in_sh(touchcmd)
|
||||||
|
local function image_supported()
|
||||||
|
return ( 0 == os.execute(
|
||||||
|
". /lib/functions.sh; " ..
|
||||||
|
"include /lib/upgrade; " ..
|
||||||
|
"platform_check_image %q >/dev/null"
|
||||||
|
% image
|
||||||
|
))
|
||||||
|
end
|
||||||
|
if luci.http.formvalue("act") == "update" then
|
||||||
|
luci.http.write("act == update")
|
||||||
|
end
|
||||||
|
if image_supported() then
|
||||||
|
luci.http.write("updating")
|
||||||
|
exec_cmd_in_sh("killall dropbear uhttpd; sleep 1; /sbin/sysupgrade -v %q" %{ image })
|
||||||
|
luci.http.write("update finished!")
|
||||||
|
else
|
||||||
|
luci.http.write("image_supported check failed!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function batchfile_checklist()
|
||||||
|
local IMEI = luci.http.formvalue("imei")
|
||||||
|
local dbfs = require "meizu.dbfs"
|
||||||
|
local searchEndFlag = "searchend"
|
||||||
|
local flag = dbfs.fetchBatchFileEndFlag(searchEndFlag, IMEI)
|
||||||
|
dbfs.deleteBatchFileEndFlag(searchEndFlag, IMEI)
|
||||||
|
local res = dbfs.fetchAllBatchFile(IMEI)
|
||||||
|
local result = res
|
||||||
|
dbfs.deleteBatchFile(IMEI)
|
||||||
|
res = cjson.encode(res)
|
||||||
|
|
||||||
|
if next(result) ~= nil then
|
||||||
|
if flag.hashCode ~= nil then
|
||||||
|
res = '{"status":"2002", "data":'..res.."}"
|
||||||
|
else
|
||||||
|
res = '{"status":"2001", "data":'..res.."}"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
res = '{"status":"2003"}'
|
||||||
|
end
|
||||||
|
luci.http.write(res)
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function findInDir(rootpath, wefind, hashCode, md5sum, IMEI)
|
||||||
|
local dbfs = require "meizu.dbfs"
|
||||||
|
local flag = 0
|
||||||
|
local ret, files, iter = pcall(lfs.dir, rootpath)
|
||||||
|
if ret == false then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
for entry in files, iter do
|
||||||
|
if entry ~= '.' and entry ~= '..' then
|
||||||
|
local f = rootpath .. '/' .. entry
|
||||||
|
local filename = string.match(f, ".+/([^/]*%.%w+)$")
|
||||||
|
|
||||||
|
if wefind == filename then
|
||||||
|
flag = 1
|
||||||
|
if(md5sum == luci.sys.exec("md5sum %q" % f):match("^([^%s]+)")) then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
else
|
||||||
|
dbfs.addBatchFile(hashCode, IMEI)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return flag
|
||||||
|
end
|
||||||
|
|
||||||
|
function batchfile_compare_upload()
|
||||||
|
local data = luci.http.formvalue("data")
|
||||||
|
local tableData = cjson.decode(data)
|
||||||
|
local dbfs = require "meizu.dbfs"
|
||||||
|
dbfs.initBatchFileTable()
|
||||||
|
local LuciUtil = require("luci.util")
|
||||||
|
local sharePath = "/mnt/Image"
|
||||||
|
local ID = nil
|
||||||
|
for key, value in pairs(tableData) do
|
||||||
|
local wefind = value.fileName
|
||||||
|
local md5sum = value.md5
|
||||||
|
local hashCode = value.hashCode
|
||||||
|
local IMEI = value.imei
|
||||||
|
local rootpath = sharePath
|
||||||
|
ID = IMEI
|
||||||
|
|
||||||
|
local ret, files, iter = pcall(lfs.dir, rootpath)
|
||||||
|
if ret == false then
|
||||||
|
dbfs.addBatchFile(hashCode, IMEI)
|
||||||
|
end
|
||||||
|
local flag = findInDir(rootpath, wefind, hashCode, md5sum, IMEI)
|
||||||
|
if flag == 0 then
|
||||||
|
dbfs.addBatchFile(hashCode, IMEI)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local searchEndFlag = "searchend"
|
||||||
|
dbfs.addBatchFile(searchEndFlag, ID)
|
||||||
|
end
|
||||||
|
|
||||||
|
function table_merge(t1, t2)
|
||||||
|
if (type(t1) == "table") and (type(t2) == "table") then
|
||||||
|
for k, v in pairs(t2) do
|
||||||
|
if (type(v) == "table") and (type(t1[k] or false) == "table") then
|
||||||
|
table_merge(t1[k], t2[k])
|
||||||
|
else
|
||||||
|
t1[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return t1
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_files_list(path, start, count, ID)
|
||||||
|
local result = {}
|
||||||
|
local ret, files, iter = pcall(lfs.dir, path)
|
||||||
|
local cmd_file = "ls -al " .. '"'.. path ..'"'.. " | awk '/^-/' | wc -l"
|
||||||
|
local cmd_dir = "ls -al " .. '"'.. path ..'"'.. " | awk '/^d/' | wc -l"
|
||||||
|
local luaUtil = require"luci.util"
|
||||||
|
local file_num = luaUtil.exec(cmd_file)
|
||||||
|
local dir_num = luaUtil.exec(cmd_dir)
|
||||||
|
local total_num = file_num + dir_num - 2
|
||||||
|
local start = tonumber(start)
|
||||||
|
local count = tonumber(count)
|
||||||
|
local fs = require "nixio.fs"
|
||||||
|
|
||||||
|
if ret == true then
|
||||||
|
for file in lfs.dir(path) do
|
||||||
|
if file ~= "." and file ~= ".." then
|
||||||
|
local f = path..'/'..file
|
||||||
|
local fname = file
|
||||||
|
local attr = lfs.attributes(f)
|
||||||
|
assert (type(attr) == "table")
|
||||||
|
|
||||||
|
if attr.mode == "directory" then
|
||||||
|
local res = {name = "", isfile = nil, size = nil, time = nil}
|
||||||
|
local cmd_file = "ls -al " .. '"'.. f ..'"'.. " | awk '/^-/' | wc -l"
|
||||||
|
local cmd_dir = "ls -al " .. '"'.. f ..'"'.. " | awk '/^d/' | wc -l"
|
||||||
|
local size_file = luaUtil.exec(cmd_file)
|
||||||
|
local size_dir = luaUtil.exec(cmd_dir)
|
||||||
|
local size = size_file + size_dir - 2
|
||||||
|
local name = fname
|
||||||
|
local stat = fs.stat(f)
|
||||||
|
local time = stat.mtime
|
||||||
|
res.name = fname
|
||||||
|
res.isfile = 0
|
||||||
|
res.size = size
|
||||||
|
res.time = time
|
||||||
|
|
||||||
|
table.insert(result, res)
|
||||||
|
else
|
||||||
|
local res = {name = "", isfile = nil, size = nil, time = nil}
|
||||||
|
local name = fname
|
||||||
|
local stat = fs.stat(f)
|
||||||
|
local time = stat.mtime
|
||||||
|
local size = nixio.fs.stat(f).size
|
||||||
|
res.name = fname
|
||||||
|
res.isfile = 1
|
||||||
|
res.size = size
|
||||||
|
res.time = time
|
||||||
|
|
||||||
|
table.insert(result, res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if total_num > count then
|
||||||
|
total_num = count
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(result, function(a, b) return (a.isfile < b.isfile) end)
|
||||||
|
local res = {}
|
||||||
|
for i = start + 1, start + count do
|
||||||
|
table.insert(res, result[i])
|
||||||
|
end
|
||||||
|
|
||||||
|
local res = cjson.encode(res)
|
||||||
|
path = string.gsub(path, "mnt", "router")
|
||||||
|
res = '{"result":true, "start":'..start..', "count":'..total_num..', "path":"'..path..'", "fileinfo":'..res.."}"
|
||||||
|
luci.http.write(res)
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function getFilesList()
|
||||||
|
local path = luci.http.formvalue("path")
|
||||||
|
local start = luci.http.formvalue("start")
|
||||||
|
local count = luci.http.formvalue("count")
|
||||||
|
local ID = luci.http.formvalue("ID")
|
||||||
|
local result = get_files_list(path, start, count, ID)
|
||||||
|
--luci.http.write(result)
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function sysinfo()
|
||||||
|
local lue = require("luci.util").exec
|
||||||
|
local ret = {}
|
||||||
|
ret["romversion"] = get_device_version()
|
||||||
|
ret["SN"] = get_device_SN()
|
||||||
|
ret["deviceModel"] = "R10"
|
||||||
|
ret["routername"] = "mzrt"..get_device_SN()
|
||||||
|
local ssid1, ssid2 = require "meizu.nwfs".get_wifi_ssids()
|
||||||
|
ret["ssid1"] = ssid1
|
||||||
|
ret["ssid2"] = ssid2
|
||||||
|
local cmd = [[df /mnt|grep -q sda;echo -n $?]]
|
||||||
|
ret["diskstatus"] = lue(cmd)
|
||||||
|
return ret
|
||||||
|
end
|
1442
Me_Lua/h10/meizu/btfs.lua
Normal file
1442
Me_Lua/h10/meizu/btfs.lua
Normal file
File diff suppressed because it is too large
Load Diff
604
Me_Lua/h10/meizu/dbfs.lua
Normal file
604
Me_Lua/h10/meizu/dbfs.lua
Normal file
@ -0,0 +1,604 @@
|
|||||||
|
module ("meizu.dbfs", package.seeall)
|
||||||
|
|
||||||
|
local sqlite3 = require("lsqlite3")
|
||||||
|
local r10db = "/etc/r10db"
|
||||||
|
|
||||||
|
function database_busy()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function updateDeviceNickname(mac, nickname)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("update maclist set devicename = '%s' where mac = '%s'", nickname, mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_dev_nick_name(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select devicename, orgname from maclist where mac like '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local nickname = ""
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row[1] ~= "" then
|
||||||
|
nickname = row[1]
|
||||||
|
else
|
||||||
|
if row[2] ~= "" then
|
||||||
|
nickname = row[2]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return nickname
|
||||||
|
end
|
||||||
|
|
||||||
|
function initSmbBanTable()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("create table if not exists SmbBanTable(mac varchar(100), smb_ban varchar(100))")
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function addSmbBanList(mac, smb_ban)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("insert into SmbBanTable values('%s', '%s')", mac, smb_ban)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchSmbBanList()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from SmbBanTable where smb_ban = 'true'")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["mac"] = row[1]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function deleteSmbBanList(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from SmbBanTable where mac = '%s' and smb_ban = 'true'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchDenyDeviceInfo(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from maclist where mac = '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["mac"] = row[1],
|
||||||
|
["orgname"] = row[2],
|
||||||
|
["devicename"] = row[3],
|
||||||
|
["ip"] = row[4]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function change_maclist_table()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("ALTER TABLE maclist ADD COLUMN ip varchar(100)")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchAllDeviceInfo()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from maclist")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["mac"] = row[1],
|
||||||
|
["orgname"] = row[2],
|
||||||
|
["devicename"] = row[3]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function updateDeviceOrgname(mac, orgname)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("update maclist set orgname = '%s' where mac = '%s'", orgname, mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function saveDeviceInfo(mac, orgname, devicename, deviceip)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local fetch = string.format("select * from maclist where mac = '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local exist = false
|
||||||
|
for row in db:rows(fetch) do
|
||||||
|
if row then
|
||||||
|
exist = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local sqlStr
|
||||||
|
if not exist then
|
||||||
|
sqlStr = string.format("insert into maclist values('%s','%s','%s', '%s')", mac, orgname, devicename, deviceip)
|
||||||
|
else
|
||||||
|
sqlStr = string.format("update maclist set mac = '%s', orgname = '%s', devicemame = '%s', ip = '%s' where mac = '%s'", mac, orgname, devicename, deviceip, mac)
|
||||||
|
end
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function initBatchFileTable()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("create table if not exists batchFilesTables(hashCode varchar(100), IMEI varchar(100))")
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchAllFilesIndex(ID, path)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from FilesListTable where ID = '%s' and path = '%s'", ID, path)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["name"] = row[3]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchAllFilesList(ID, start, fetchEnd, path)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from FilesListTable where ID = '%s' and path = '%s' ORDER BY isfile, name limit '%s' offset '%s' ", ID, path, fetchEnd, start)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["name"] = row[3],
|
||||||
|
["isfile"] = row[4],
|
||||||
|
["size"] = row[5],
|
||||||
|
["time"] = row[6]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function addBatchFile(hashCode, IMEI)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("insert into batchFilesTables values('%s', '%s')", hashCode, IMEI)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchAllBatchFile(IMEI)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from batchFilesTables where IMEI = '%s'",IMEI )
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["hashCode"] = row[1]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchBatchFileEndFlag(flag, IMEI)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from batchFilesTables where hashCode = '%s' and IMEI = '%s'", flag, IMEI)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
result = {
|
||||||
|
["hashCode"] = row[1]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function deleteBatchFileEndFlag(flag, IMEI)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from batchFilesTables where hashCode = '%s' and IMEI = '%s'", flag, IMEI)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function deleteBatchFile(IMEI)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from batchFilesTables where IMEI = '%s'", IMEI)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function init_arp_table()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("create table if not exists arp(mac varchar(18), ip varchar(16))")
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetch_arp_mac(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from arp where mac like '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = ""
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
result = row[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function insert_arp_macip(mac, ip)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from ")
|
||||||
|
sqlStr = string.format("insert into arp values('%s', '%s')", mac, ip)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function delete_arp_all_mac()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from arp")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function init_wireless_device_table()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("create table if not exists wireless_table(mac varchar(100))")
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetch_wireless_device_mac(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from wireless_table where mac = '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = ""
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
result = row[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetch_all_wireless_device()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from wireless_table")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["mac"] = row[1]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function insert_wireless_device_mac(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("insert into wireless_table values('%s')", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function init_wire_device_table()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("create table if not exists wire_table(mac varchar(100), ip varchar(100))")
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetch_wire_device_mac(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from wire_table where mac = '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = ""
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
result = row[1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetch_all_wire_device()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from wire_table")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["mac"] = row[1],
|
||||||
|
["ip"] = row[2]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function insert_wire_device_mac(mac, ip)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("insert into wire_table values('%s','%s')", mac, ip)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function update_wire_device_ip(mac, ip)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("update wire_table set ip = '%s' where mac = '%s'", ip, mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function delete_wire__device(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from wire_table where mac = '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function init_access_token_table()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("create table if not exists accessTokenTable(token varchar(100), expireTime bigint)")
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function add_access_token(token, expireTime)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("insert into accessTokenTable values('%s', %d)", token, expireTime)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetch_access_token()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from accessTokenTable")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["token"] = row[1],
|
||||||
|
["expireTime"] = row[2]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function update_access_token(oldToken, newToken, expireTime)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("update accessTokenTable set token = '%s', expireTime = %d where token = '%s'", newToken, expireTime, oldToken)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function delete_access_token()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from accessTokenTable")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function initBluetoothTable()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("create table if not exists blemeshtable(id varchar(100), mac varchar(100), key varchar(100), name varchar(100), deviceType varchar(100), len varchar(100))")
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function addBluetoothDevice(id, mac, key, name, deviceType, len)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("insert into blemeshtable values('%s', '%s', '%s', '%s', '%s', '%s')", id, mac, key, name, deviceType, len)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchAllBluetoothDevice()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from blemeshtable")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["mac"] = row[2],
|
||||||
|
["deviceType"] = row[5]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function deleteBluetoothDevice(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from blemeshtable where mac = '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function updateBluetoothDevice(id, key, name, len, mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("update blemeshtable set id = '%s', key = '%s', name = '%s', len = '%s' where mac = '%s'", id, key, name, len, mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchBluetoothDevice(mac)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from blemeshtable where mac = '%s'", mac)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["id"] = row[1],
|
||||||
|
["mac"] = row[2],
|
||||||
|
["deviceType"] = row[5],
|
||||||
|
["name"] = row[4]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchBluetoothDeviceKey()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from blemeshtable where key != ''")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["mac"] = row[2],
|
||||||
|
["key"] = row[3]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function getBluetoothDevice(id)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from blemeshtable where id = '%s'", id)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = ""
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
result = row[2]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function fetchAllBleMeshDevice()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from blemeshtable where id !=''")
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = {}
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
table.insert(result,{
|
||||||
|
["mac"] = row[2],
|
||||||
|
["deviceType"] = row[5],
|
||||||
|
["name"] = row[4]
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function getBleDeviceNameLength(id)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from blemeshtable where id = '%s'", id)
|
||||||
|
db:busy_handler(database_busy)
|
||||||
|
local result = ""
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
result = row[6]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
--[[
|
||||||
|
function initBleTimerTable()
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("create table if not exists bletimertable(id varchar(100), timer_id varchar(100), flag varchar(100), start_time varchar(100), end_time varchar(100))")
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function addBleTimer(id, timer_id, flag, start_time, end_time)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("insert into bletimertable values('%s', '%s', '%s', '%s', '%s')", id, timer_id, flag, start_time, end_time)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function deleteBleTimer(id, timer_id)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("delete from bletimertable where id = '%s' and timer_id = '%s'", id, timer_id)
|
||||||
|
db:exec(sqlStr)
|
||||||
|
return db:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function getBleTimerId(id, timer_id)
|
||||||
|
local db = sqlite3.open(r10db)
|
||||||
|
local sqlStr = string.format("select * from bletimertable where id = '%s' and timer = '%s'", id, timer_id)
|
||||||
|
local result = ""
|
||||||
|
for row in db:rows(sqlStr) do
|
||||||
|
if row then
|
||||||
|
result = row[2]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
db:close()
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
]]
|
63
Me_Lua/h10/meizu/disk.lua
Normal file
63
Me_Lua/h10/meizu/disk.lua
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
module("meizu.disk", package.seeall)
|
||||||
|
|
||||||
|
local bfs = require "meizu.bfs"
|
||||||
|
local exec_cmd_in_sh = bfs.exec_cmd_in_sh
|
||||||
|
local lue = require("luci.util").exec
|
||||||
|
|
||||||
|
function get_disk_space()
|
||||||
|
local lu = require("luci.util")
|
||||||
|
local cmd = "df -k | grep ' /mnt' | awk '{printf $2}'"
|
||||||
|
local disk = lue(cmd)
|
||||||
|
if disk ~= "" then
|
||||||
|
return disk
|
||||||
|
else
|
||||||
|
return "0"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_available_disk()
|
||||||
|
local lu = require("luci.util")
|
||||||
|
local cmd = "df -k | grep ' /mnt' | awk '{printf $4}'"
|
||||||
|
local disk = lue(cmd)
|
||||||
|
if disk ~= "" then
|
||||||
|
return disk
|
||||||
|
else
|
||||||
|
return "0"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_info_imp()
|
||||||
|
local ret = {}
|
||||||
|
ret["total"] = get_disk_space()
|
||||||
|
ret["free"] = get_available_disk()
|
||||||
|
return ret;
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_get_disk_info()
|
||||||
|
luci.http.prepare_content("application/json")
|
||||||
|
local ret = get_info_imp()
|
||||||
|
luci.http.write_json(ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ww_get_disk_info()
|
||||||
|
local res = {}
|
||||||
|
res = get_info_imp()
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function disk_formatting()
|
||||||
|
local result = {}
|
||||||
|
result["result"] = false
|
||||||
|
local cmd = [[ls /dev/sda |grep -E "/dev/sd.$" |wc -l|awk '{printf $1}']]
|
||||||
|
local res = lue(cmd)
|
||||||
|
|
||||||
|
if res == "1" then
|
||||||
|
result["result"] = true
|
||||||
|
luci.http.write_json(result)
|
||||||
|
local cmd = "hd_part.sh /dev/sda;echo $?"
|
||||||
|
exec_cmd_in_sh(cmd)
|
||||||
|
else
|
||||||
|
result["code"] = res
|
||||||
|
luci.http.write_json(result)
|
||||||
|
end
|
||||||
|
end
|
670
Me_Lua/h10/meizu/dlfs.lua
Normal file
670
Me_Lua/h10/meizu/dlfs.lua
Normal file
@ -0,0 +1,670 @@
|
|||||||
|
module("meizu.dlfs", package.seeall)
|
||||||
|
-- download functions
|
||||||
|
|
||||||
|
local cjson = require "cjson"
|
||||||
|
local lfs = require "lfs"
|
||||||
|
local bfs = require "meizu.bfs"
|
||||||
|
local RC = require "meizu.r10config"
|
||||||
|
local nixio = require "nixio"
|
||||||
|
|
||||||
|
local b64dec = bfs.b64dec
|
||||||
|
local bind_router = bfs.bind_router
|
||||||
|
local cal_str_md5 = bfs.cal_str_md5
|
||||||
|
local data_to_json = bfs.data_to_json
|
||||||
|
local exec_cmd_in_sh = bfs.exec_cmd_in_sh
|
||||||
|
local exec_reboot = bfs.exec_reboot
|
||||||
|
local get_device_SN = bfs.get_device_SN
|
||||||
|
local get_device_version = bfs.get_device_version
|
||||||
|
local get_https_data = bfs.get_https_data
|
||||||
|
local rts_get_access_token = bfs.rts_get_access_token
|
||||||
|
local set_passwd = bfs.set_passwd
|
||||||
|
local silent_upgrade = bfs.silent_upgrade
|
||||||
|
local table_merge = bfs.table_merge
|
||||||
|
|
||||||
|
local aria2rpc = "http://127.0.0.1:6800/jsonrpc"
|
||||||
|
local httpreq = require("socket.http").request
|
||||||
|
local lue = require("luci.util").exec
|
||||||
|
|
||||||
|
function aria2_make_req_param(method, gid)
|
||||||
|
local p = [[{"jsonrpc":"2.0", "method":"]]
|
||||||
|
p = p..method..[[", ]]
|
||||||
|
p = p..[["id":1, "params":["]]
|
||||||
|
p = p..gid..'"]}'
|
||||||
|
p = p..'{"Accept=application/json, text/javascript, */*; q=0.01"}'
|
||||||
|
p = p..'{"Accept-Encoding=gzip, deflate"}'
|
||||||
|
p = p..'{"Content-Type=application/x-www-form-urlencoded; charset=UTF-8"}'
|
||||||
|
p = p..'{"Pragma=no-cache"}'
|
||||||
|
p = p..'{"Cache-Control=no-cache"}'
|
||||||
|
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_make_status_param(method, params)
|
||||||
|
local p = [[{"jsonrpc":"2.0", "method":"]]
|
||||||
|
p = p..method..[[", ]]
|
||||||
|
p = p..[["id":1]]
|
||||||
|
if params == "" then
|
||||||
|
p = p..'}'
|
||||||
|
else
|
||||||
|
p = p..[[, "params":[]]
|
||||||
|
p = p..params..']}'
|
||||||
|
end
|
||||||
|
p = p..'{"Accept=application/json, text/javascript, */*; q=0.01"}'
|
||||||
|
p = p..'{"Accept-Encoding=gzip, deflate"}'
|
||||||
|
p = p..'{"Content-Type=application/x-www-form-urlencoded; charset=UTF-8"}'
|
||||||
|
p = p..'{"Pragma=no-cache"}'
|
||||||
|
p = p..'{"Cache-Control=no-cache"}'
|
||||||
|
|
||||||
|
return p
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_success_res(command, gid, status)
|
||||||
|
local res = [[{"result":true, "command":"]]..command..[[", "gid":"]]..gid..[[", "message":"]]..status..[["}]]
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_failed_res(command, gid, status)
|
||||||
|
local res = [[{"result":flase, "command":"]]..command..[[", "gid":"]]..gid..[[", "message":"]]..status..[["}]]
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_download_task_pause(gid, command)
|
||||||
|
local param = aria2_make_req_param("aria2.pause", gid)
|
||||||
|
local res, code, headers, status = httpreq(aria2rpc, param)
|
||||||
|
local success_res = aria2_success_res(command, gid, status)
|
||||||
|
local failed_res = aria2_failed_res(command, gid, status)
|
||||||
|
|
||||||
|
if code == 200 then
|
||||||
|
return success_res
|
||||||
|
else
|
||||||
|
return failed_res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_download_task_unpause(gid, command)
|
||||||
|
local param = aria2_make_req_param("aria2.unpause", gid)
|
||||||
|
local res, code, headers, status = httpreq(aria2rpc,param)
|
||||||
|
local success_res = aria2_success_res(command, gid, status)
|
||||||
|
local failed_res = aria2_failed_res(command, gid, status)
|
||||||
|
|
||||||
|
if code == 200 then
|
||||||
|
return success_res
|
||||||
|
else
|
||||||
|
return failed_res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_download_task_remove(gid, command)
|
||||||
|
local param = aria2_make_req_param("aria2.removeDownloadResult", gid)
|
||||||
|
local res, code, headers, status = httpreq(aria2rpc,param)
|
||||||
|
local success_res = aria2_success_res(command, gid, status)
|
||||||
|
local failed_res = aria2_failed_res(command, gid, status)
|
||||||
|
|
||||||
|
if code == 200 then
|
||||||
|
return success_res
|
||||||
|
else
|
||||||
|
return failed_res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_get_active_list()
|
||||||
|
local result = {}
|
||||||
|
local param = aria2_make_status_param("aria2.tellActive", "")
|
||||||
|
local res, code, headers, status = httpreq(aria2rpc, param)
|
||||||
|
|
||||||
|
if code == 200 then
|
||||||
|
local jsd = cjson.decode(res)
|
||||||
|
for key, value in pairs(jsd.result) do
|
||||||
|
local data = {status = "", speed = nil, total = nil,
|
||||||
|
completed = nil, gid = "", file = ""}
|
||||||
|
|
||||||
|
data.status = value.status
|
||||||
|
data.speed = tonumber(value.downloadSpeed)
|
||||||
|
data.total = tonumber(value.totalLength)
|
||||||
|
data.completed = tonumber(value.completedLength)
|
||||||
|
data.gid = value.gid
|
||||||
|
local jsd = cjson.encode(value.files)
|
||||||
|
jsd = string.sub(jsd, 2, -2)
|
||||||
|
local fn = cjson.decode(jsd)
|
||||||
|
data.file = ""
|
||||||
|
if string.match(fn.path, ".+/([^/]*%.%w+)$") then
|
||||||
|
data.file = string.match(fn.path, ".+/([^/]*%.%w+)$")
|
||||||
|
end
|
||||||
|
table.insert(result, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_get_pause_list()
|
||||||
|
local param = aria2_make_status_param("aria2.tellWaiting", "0, 1000")
|
||||||
|
local res, code, headers, status = httpreq(aria2rpc,param)
|
||||||
|
local result = {}
|
||||||
|
if code == 200 then
|
||||||
|
local jsd = cjson.decode(res)
|
||||||
|
|
||||||
|
for key, value in pairs(jsd.result) do
|
||||||
|
local data = {status = "", speed = nil, total = nil,
|
||||||
|
completed = nil, gid = "", file = ""}
|
||||||
|
data.status = value.status
|
||||||
|
data.speed = tonumber(value.downloadSpeed)
|
||||||
|
data.total = tonumber(value.totalLength)
|
||||||
|
data.completed = tonumber(value.completedLength)
|
||||||
|
data.gid = value.gid
|
||||||
|
local jsd = cjson.encode(value.files)
|
||||||
|
jsd = string.sub(jsd, 2, -2)
|
||||||
|
local fn = cjson.decode(jsd)
|
||||||
|
data.file = ""
|
||||||
|
if string.match(fn.path, ".+/([^/]*%.%w+)$") then
|
||||||
|
data.file = string.match(fn.path, ".+/([^/]*%.%w+)$")
|
||||||
|
end
|
||||||
|
table.insert(result, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return result;
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_get_history_list()
|
||||||
|
local param = aria2_make_status_param("aria2.tellStopped", "0, 1000")
|
||||||
|
local result = {}
|
||||||
|
local res, code, headers, status = httpreq(aria2rpc, param)
|
||||||
|
if code == 200 then
|
||||||
|
local jsd = cjson.decode(res)
|
||||||
|
for key, value in pairs(jsd.result) do
|
||||||
|
local data = {status = "", speed = nil, total = nil,
|
||||||
|
completed = nil, gid = "", file = ""}
|
||||||
|
data.speed = tonumber(value.downloadSpeed)
|
||||||
|
data.total = tonumber(value.totalLength)
|
||||||
|
data.completed = tonumber(value.completedLength)
|
||||||
|
local jsd = cjson.encode(value.files)
|
||||||
|
jsd = string.sub(jsd, 2, -2)
|
||||||
|
local fn = cjson.decode(jsd)
|
||||||
|
data.status = value.status
|
||||||
|
data.gid = value.gid
|
||||||
|
data.file = ""
|
||||||
|
if string.match(fn.path, ".+/([^/]*%.%w+)$") then
|
||||||
|
data.file = string.match(fn.path, ".+/([^/]*%.%w+)$")
|
||||||
|
end
|
||||||
|
table.insert(result, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function aria2_download_task_start(url)
|
||||||
|
local param = '[{"jsonrpc":"2.0", "method":"aria2.addUri", "id":"1",'..
|
||||||
|
'"params":[['..'"'..url..'"'.."]]}]"
|
||||||
|
local res, code, headers, status = httpreq(aria2rpc, param)
|
||||||
|
local jsd = nil
|
||||||
|
if code == 200 then
|
||||||
|
res = string.sub(res, 2, -2)
|
||||||
|
jsd = cjson.decode(res)
|
||||||
|
end
|
||||||
|
local success_res = '{"result":true, "gid":'..'"'..jsd.result..'"'..
|
||||||
|
', "message":'..'"'..status..'"'.."}"
|
||||||
|
local failed_res = '{"result":false, "message":'..'"'..status..'"'.."}"
|
||||||
|
|
||||||
|
if code == 200 then
|
||||||
|
return success_res
|
||||||
|
else
|
||||||
|
return failed_res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_clean_list_log()
|
||||||
|
if nixio.fs.access("/tmp/tdal.log") then
|
||||||
|
nixio.fs.unlink("/tmp/tdal.log")
|
||||||
|
end
|
||||||
|
if nixio.fs.access("/tmp/tdhl.log") then
|
||||||
|
nixio.fs.unlink("/tmp/tdhl.log")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_download_task_pause(gid, command)
|
||||||
|
thunder_clean_list_log()
|
||||||
|
local success_res = '{"result":true, "command":'..'"'..command..'"'..
|
||||||
|
', "gid":'..'"'..gid..'"'..
|
||||||
|
', "message":'..'"success"'.."}"
|
||||||
|
local cmd = "/usr/bin/xunleiR.py pause "..gid
|
||||||
|
local ret = lue(cmd)
|
||||||
|
|
||||||
|
return success_res
|
||||||
|
end
|
||||||
|
|
||||||
|
function download_task_pause(gid, command)
|
||||||
|
if string.match(gid, "^tdid_") then
|
||||||
|
local tdid = string.sub(gid, 6)
|
||||||
|
return thunder_download_task_pause(tdid, command)
|
||||||
|
else
|
||||||
|
return aria2_download_task_pause(gid, command)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_download_task_unpause(gid, command)
|
||||||
|
thunder_clean_list_log()
|
||||||
|
local success_res = '{"result":true, "command":'..
|
||||||
|
'"'..command..'"'..', "gid":'..
|
||||||
|
'"'..gid..'"'..', "message":'..'"success"'.."}"
|
||||||
|
local cmd = "/usr/bin/xunleiR.py start "..gid
|
||||||
|
local ret = lue(cmd)
|
||||||
|
|
||||||
|
return success_res
|
||||||
|
end
|
||||||
|
|
||||||
|
function download_task_unpause(gid, command)
|
||||||
|
if string.match(gid, "^tdid_") then
|
||||||
|
local tdid = string.sub(gid, 6)
|
||||||
|
return thunder_download_task_unpause(tdid, command)
|
||||||
|
else
|
||||||
|
return aria2_download_task_unpause(gid, command)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_download_task_remove(gid, command)
|
||||||
|
thunder_clean_list_log()
|
||||||
|
local success_res = '{"result":true, "command":'..
|
||||||
|
'"'..command..'"'..', "gid":'..
|
||||||
|
'"'..gid..'"'..', "message":'..'"success"'.."}"
|
||||||
|
--local cmd = "/usr/bin/xunleiR.py remove "..gid
|
||||||
|
local cmd = "/usr/bin/xunleiR.py delete "..gid
|
||||||
|
local ret = lue(cmd)
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
|
||||||
|
return success_res
|
||||||
|
end
|
||||||
|
|
||||||
|
function download_task_remove(gid, command)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, gid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if string.match(gid, "^tdid_") then
|
||||||
|
local tdid = string.sub(gid, 6)
|
||||||
|
return thunder_download_task_remove(tdid, command)
|
||||||
|
else
|
||||||
|
return aria2_download_task_remove(gid, command)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_pause_list()
|
||||||
|
local result = aria2_get_pause_list()
|
||||||
|
local ret_msg = ""
|
||||||
|
if nil ~= next(result) then
|
||||||
|
--result = cjson.encode(result)
|
||||||
|
local jsr = data_to_json(result)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, jsr)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
ret_msg = '{"result":true, "message":'..jsr.."}"
|
||||||
|
else
|
||||||
|
ret_msg = '{"result":false, "message":[]}'
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, ret_msg)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
|
||||||
|
return ret_msg
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_get_pause_list()
|
||||||
|
local data = get_pause_list()
|
||||||
|
luci.http.write(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_get_bind_code()
|
||||||
|
local ret = {}
|
||||||
|
local lue = require"luci.util".exec
|
||||||
|
local cmd = [[/usr/bin/xunleiR.py sysinfo|awk -F',' '{print $5}']]
|
||||||
|
local code = lue(cmd)
|
||||||
|
ret = '{"code":'..code..'}'
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_thunder_get_bind_code()
|
||||||
|
local data = thunder_get_bind_code()
|
||||||
|
luci.http.write(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ww_thunder_get_bind_code()
|
||||||
|
return thunder_get_bind_code()
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_state_code(code)
|
||||||
|
local ret = "active"
|
||||||
|
if code == 0 or code == 8 or code == 13 or code == 14 or code == 37 then
|
||||||
|
ret = "active"
|
||||||
|
end
|
||||||
|
if code == 9 or code == 10 then
|
||||||
|
ret = "paused"
|
||||||
|
end
|
||||||
|
if code == 11 or code == 15 then
|
||||||
|
ret = "complete"
|
||||||
|
end
|
||||||
|
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_localpath_translate(path)
|
||||||
|
if type(path) == "string" then
|
||||||
|
path = string.gsub(path, "/opt/xware/mnt/", "/router/Thunder/")
|
||||||
|
end
|
||||||
|
return path
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_get_active_list()
|
||||||
|
local cmd = "/usr/bin/xunleiR.py list"
|
||||||
|
local ret
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if nixio.fs.access("/tmp/tdal.log") then
|
||||||
|
local fp = io.open("/tmp/tdal.log", "r")
|
||||||
|
local data = fp:read("*a")
|
||||||
|
ret = data
|
||||||
|
fp:close()
|
||||||
|
else
|
||||||
|
ret = lue(cmd)
|
||||||
|
local fp = io.open("/tmp/tdal.log", "wb")
|
||||||
|
fp:write(ret)
|
||||||
|
fp:close()
|
||||||
|
end
|
||||||
|
local result = {}
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if ret then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local jsd = cjson.decode(ret)
|
||||||
|
local tasks = jsd.tasks
|
||||||
|
for k, v in pairs(tasks) do
|
||||||
|
local data = {}
|
||||||
|
if (_G.next(v) ~= nil) then
|
||||||
|
data.speed = v.speed
|
||||||
|
data.status = thunder_state_code(v.state)
|
||||||
|
data.total = tonumber(v.size)
|
||||||
|
data.completed = tonumber(data.total * tonumber(v.progress)/10000)
|
||||||
|
data.file = v.name
|
||||||
|
data.path = thunder_localpath_translate(v.path)
|
||||||
|
data.gid = 'tdid_'..v.id
|
||||||
|
end
|
||||||
|
table.insert(result, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, data_to_json(result))
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_get_rlist()
|
||||||
|
thunder_clean_list_log()
|
||||||
|
local cmd = "/usr/bin/xunleiR.py rlist"
|
||||||
|
local ret = lue(cmd)
|
||||||
|
local jsd = cjson.decode(ret)
|
||||||
|
local tasks = jsd.tasks
|
||||||
|
local result = {}
|
||||||
|
for k, v in pairs(tasks) do
|
||||||
|
local data = {}
|
||||||
|
if (_G.next(v) ~= nil) then
|
||||||
|
data.speed = v.speed
|
||||||
|
data.status = thunder_state_code(v.state)
|
||||||
|
data.total = tonumber(v.size)
|
||||||
|
data.completed = tonumber(data.total * tonumber(v.progress)/10000)
|
||||||
|
data.file = v.name
|
||||||
|
data.gid = 'tdid_'..v.id
|
||||||
|
end
|
||||||
|
table.insert(result, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_active_list(start, refine_cnt)
|
||||||
|
local s = 0
|
||||||
|
local cnt
|
||||||
|
if start then
|
||||||
|
s = start
|
||||||
|
end
|
||||||
|
local result = {}
|
||||||
|
local aria2_alist = aria2_get_active_list()
|
||||||
|
local thunder_alist = thunder_get_active_list()
|
||||||
|
local aria2_plist = aria2_get_pause_list()
|
||||||
|
--local thunder_rlist = thunder_get_rlist()
|
||||||
|
if _G.next(aria2_alist) then
|
||||||
|
result = table_merge(result, aria2_alist)
|
||||||
|
end
|
||||||
|
if _G.next(thunder_alist) then
|
||||||
|
result = table_merge(result, thunder_alist)
|
||||||
|
end
|
||||||
|
if _G.next(aria2_plist) then
|
||||||
|
result = table_merge(result, aria2_plist)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ret_msg = {}
|
||||||
|
local total = require("table").getn(result)
|
||||||
|
ret_msg["total"] = total
|
||||||
|
ret_msg["result"] = false
|
||||||
|
local ret = {}
|
||||||
|
if _G.next(result) then
|
||||||
|
if refine_cnt then
|
||||||
|
cnt = refine_cnt
|
||||||
|
else
|
||||||
|
cnt = total
|
||||||
|
end
|
||||||
|
local pos = 0
|
||||||
|
for k, v in pairs(result) do
|
||||||
|
if pos >= s and (pos - s + 1 <= cnt) then
|
||||||
|
table.insert(ret, v)
|
||||||
|
pos = pos + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ret_msg["result"] = true
|
||||||
|
ret_msg["message"] = ret
|
||||||
|
else
|
||||||
|
ret_msg["message"] = "[]"
|
||||||
|
end
|
||||||
|
ret_msg["start"] = s
|
||||||
|
if ret and type(ret) == "table" and _G.next(ret) then
|
||||||
|
ret_msg["count"] = require("table").getn(ret)
|
||||||
|
else
|
||||||
|
ret_msg["count"] = 0
|
||||||
|
end
|
||||||
|
ret_msg = data_to_json(ret_msg)
|
||||||
|
require "MZLog".log(3, ret_msg)
|
||||||
|
|
||||||
|
return ret_msg
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_get_active_list()
|
||||||
|
local data = get_active_list()
|
||||||
|
luci.http.write(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_get_history_list()
|
||||||
|
local cmd = "/usr/bin/xunleiR.py clist"
|
||||||
|
local ret
|
||||||
|
if nixio.fs.access("/tmp/tdhl.log") then
|
||||||
|
local fp = io.open("/tmp/tdhl.log", "r")
|
||||||
|
local data = nixio.fs.readfile("/tmp/tdhl.log")
|
||||||
|
ret = data
|
||||||
|
else
|
||||||
|
ret = lue(cmd)
|
||||||
|
local fp = io.open("/tmp/tdhl.log", "wb")
|
||||||
|
fp:write(ret)
|
||||||
|
fp:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local jsd = cjson.decode(ret)
|
||||||
|
local tasks = jsd.tasks
|
||||||
|
local result = {}
|
||||||
|
for k, v in pairs(tasks) do
|
||||||
|
local data = {}
|
||||||
|
if (_G.next(v) ~= nil) then
|
||||||
|
data.speed = v.speed
|
||||||
|
data.total = tonumber(v.size)
|
||||||
|
data.completed = v.size
|
||||||
|
data.status = thunder_state_code(v.state)
|
||||||
|
data.file = v.name
|
||||||
|
data.path = thunder_localpath_translate(v.path)
|
||||||
|
data.gid = 'tdid_'..v.id
|
||||||
|
end
|
||||||
|
table.insert(result, data)
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_history_list(start, refine_cnt)
|
||||||
|
local s = 0
|
||||||
|
local cnt
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if start then
|
||||||
|
s = start
|
||||||
|
require "MZLog".log(3, start)
|
||||||
|
end
|
||||||
|
if refine_cnt then
|
||||||
|
require "MZLog".log(3, refine_cnt)
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local result = {}
|
||||||
|
local aria2_ret = aria2_get_history_list()
|
||||||
|
local thunder_ret = thunder_get_history_list()
|
||||||
|
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, data_to_json(aria2_ret))
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
|
||||||
|
if nil ~= _G.next(aria2_ret) then
|
||||||
|
table_merge(result, aria2_ret)
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, data_to_json(thunder_ret))
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if _G.next(thunder_ret) then
|
||||||
|
table_merge(result, thunder_ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local total = require("table").getn(result)
|
||||||
|
local ret_msg = {}
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
ret_msg["total"] = total
|
||||||
|
ret_msg["result"] = false
|
||||||
|
if _G.next(result) then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local cnt
|
||||||
|
if refine_cnt then
|
||||||
|
cnt = refine_cnt
|
||||||
|
else
|
||||||
|
cnt = total
|
||||||
|
end
|
||||||
|
local ret = {}
|
||||||
|
local pos = 0
|
||||||
|
for k, v in pairs(result) do
|
||||||
|
if pos >= s and (pos - s + 1 <= cnt) then
|
||||||
|
table.insert(ret, v)
|
||||||
|
pos = pos + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ret_msg["count"] = require("table").getn(ret)
|
||||||
|
local jsd = data_to_json(ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, jsd)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
ret_msg["result"] = true
|
||||||
|
--ret_msg["message"] = jsd
|
||||||
|
ret_msg["message"] = ret
|
||||||
|
else
|
||||||
|
ret_msg["message"] = "[]"
|
||||||
|
end
|
||||||
|
ret_msg["start"] = s
|
||||||
|
if ret and type(ret) == "table" and _G.next(ret) then
|
||||||
|
ret_msg["count"] = require("table").getn(ret)
|
||||||
|
else
|
||||||
|
ret_msg["count"] = 0
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
ret_msg = data_to_json(ret_msg)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, ret_msg)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
|
||||||
|
return ret_msg
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_get_history_list()
|
||||||
|
local data = get_history_list()
|
||||||
|
luci.http.write(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function thunder_download_task_start(url)
|
||||||
|
thunder_clean_list_log()
|
||||||
|
local ret = ""
|
||||||
|
local cmd = [[/usr/bin/xunleiR.py download ']]..url..[[']]
|
||||||
|
require "MZLog".log(3, cmd)
|
||||||
|
ret = lue(cmd)
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
local jsr = cjson.decode(ret)
|
||||||
|
ret = {}
|
||||||
|
ret["message"] = ""
|
||||||
|
ret["result"] = false
|
||||||
|
if jsr and jsr.rtn then
|
||||||
|
require "MZLog".log(3, jsr.rtn)
|
||||||
|
ret["rtn"] = jsr.rtn
|
||||||
|
if jsr.rtn == 0 or jsr.rtn == 202 then
|
||||||
|
ret["result"] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if jsr and jsr.id then
|
||||||
|
ret["gid"] = "tdid_"..jsr.id
|
||||||
|
else
|
||||||
|
ret["gid"] = "tdid_0"
|
||||||
|
end
|
||||||
|
|
||||||
|
return data_to_json(ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
function download_task_start(url, dltype)
|
||||||
|
require "MZLog".log(3, url)
|
||||||
|
require "MZLog".log(3, dltype)
|
||||||
|
local res = ""
|
||||||
|
if dltype == "thunder" then
|
||||||
|
res = thunder_download_task_start(url)
|
||||||
|
else
|
||||||
|
res = aria2_download_task_start(url)
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_download_task_start()
|
||||||
|
local url = luci.http.formvalue("url")
|
||||||
|
local dltype = luci.http.formvalue("type")
|
||||||
|
local res = download_task_start(url, dltype)
|
||||||
|
luci.http.write(res)
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function download_task_operate(gid, command)
|
||||||
|
if command == "downloadpause" then
|
||||||
|
return download_task_pause(gid, command)
|
||||||
|
elseif command == "downloadunpause" then
|
||||||
|
return download_task_unpause(gid, command)
|
||||||
|
elseif command == "downloadremove" then
|
||||||
|
return download_task_remove(gid, command)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function nw_download_task_operate()
|
||||||
|
local command = luci.http.formvalue("command")
|
||||||
|
local gid = luci.http.formvalue("gid")
|
||||||
|
local ret = download_task_operate(gid, command)
|
||||||
|
|
||||||
|
luci.http.write(ret)
|
||||||
|
end
|
1747
Me_Lua/h10/meizu/nwfs.lua
Normal file
1747
Me_Lua/h10/meizu/nwfs.lua
Normal file
File diff suppressed because it is too large
Load Diff
3
Me_Lua/h10/meizu/r10config.lua
Normal file
3
Me_Lua/h10/meizu/r10config.lua
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
upgradeFlagFile = "/tmp/upgradeFlagFile"
|
||||||
|
upgradeLOCK = "/bin/touch "..upgradeFlagFile
|
||||||
|
upgradeUNLOCK = "/bin/rm "..upgradeFlagFile
|
906
Me_Lua/h10/meizu/sipfs.lua
Normal file
906
Me_Lua/h10/meizu/sipfs.lua
Normal file
@ -0,0 +1,906 @@
|
|||||||
|
module("meizu.sipfs", package.seeall)
|
||||||
|
--sip functions
|
||||||
|
|
||||||
|
local bfs = require "meizu.bfs"
|
||||||
|
local cjson = require "cjson"
|
||||||
|
local disk = require "meizu.disk"
|
||||||
|
local dlfs = require "meizu.dlfs"
|
||||||
|
local nwfs = require "meizu.nwfs"
|
||||||
|
local RC = require "meizu.r10config"
|
||||||
|
local sipfs = require "meizu.sipfs"
|
||||||
|
local upgdfs = require "meizu.upgdfs"
|
||||||
|
local dbfs = require "meizu.dbfs"
|
||||||
|
local btfs = require "meizu.btfs"
|
||||||
|
|
||||||
|
local b64dec = bfs.b64dec
|
||||||
|
local batchfile_checklist = bfs.batchfile_checklist
|
||||||
|
local batchfile_compare_upload = bfs.batchfile_compare_upload
|
||||||
|
local bind_router = bfs.bind_router
|
||||||
|
local data_to_json = bfs.data_to_json
|
||||||
|
local exec_cmd_in_sh = bfs.exec_cmd_in_sh
|
||||||
|
local exec_reboot = bfs.exec_reboot
|
||||||
|
local findInDir = bfs.findInDir
|
||||||
|
local get_device_SN = bfs.get_device_SN
|
||||||
|
local get_device_version = bfs.get_device_version
|
||||||
|
local get_https_data = bfs.get_https_data
|
||||||
|
local factory_reset = bfs.factory_reset
|
||||||
|
local rts_get_access_token = bfs.rts_get_access_token
|
||||||
|
local set_passwd = bfs.set_passwd
|
||||||
|
local silent_upgrade = bfs.silent_upgrade
|
||||||
|
local get_files_list = bfs.get_files_list
|
||||||
|
|
||||||
|
local ww_get_disk_info = disk.ww_get_disk_info
|
||||||
|
|
||||||
|
local get_smb_switch = nwfs.get_smb_switch
|
||||||
|
local real_time_net_speed = nwfs.real_time_net_speed
|
||||||
|
local set_device_name = nwfs.set_device_name
|
||||||
|
local set_disk_access = nwfs.set_disk_access
|
||||||
|
local set_smb_switch = nwfs.set_smb_switch
|
||||||
|
local set_wan_switch = nwfs.set_wan_switch
|
||||||
|
local wifi_settings = nwfs.wifi_settings
|
||||||
|
local ww_get_connect_device_list = nwfs.ww_get_connect_device_list
|
||||||
|
local ww_get_device_details = nwfs.ww_get_device_details
|
||||||
|
local ww_get_wifi_settings = nwfs.ww_get_wifi_settings
|
||||||
|
local ww_get_tx_power_mode = nwfs.ww_get_tx_power_mode
|
||||||
|
local ww_set_tx_power_mode = nwfs.ww_set_tx_power_mode
|
||||||
|
local ww_get_wireless_channel = nwfs.ww_get_wireless_channel
|
||||||
|
local ww_set_wireless_channel = nwfs.ww_set_wireless_channel
|
||||||
|
|
||||||
|
local ww_scan_ble_switch = btfs.ww_scan_ble_switch
|
||||||
|
local ww_add_ble_mesh_device = btfs.ww_add_ble_mesh_device
|
||||||
|
local ww_get_ble_device_list = btfs.ww_get_ble_device_list
|
||||||
|
local ww_get_ble_device_status = btfs.ww_get_ble_device_status
|
||||||
|
local ww_set_mesh_device_attr = btfs.ww_set_mesh_device_attr
|
||||||
|
local ww_get_mesh_device_list = btfs.ww_get_mesh_device_list
|
||||||
|
local ww_unmesh_all_device = btfs.ww_unmesh_all_device
|
||||||
|
local ww_set_mesh_network_pwd = btfs.ww_set_mesh_network_pwd
|
||||||
|
local ww_set_lamp_brightness = btfs.ww_set_lamp_brightness
|
||||||
|
|
||||||
|
local check_upgrade = upgdfs.check_upgrade
|
||||||
|
local do_upgrade = upgdfs.do_upgrade
|
||||||
|
local local_upgrade = upgdfs.local_upgrade
|
||||||
|
|
||||||
|
local download_task_operate = dlfs.download_task_operate
|
||||||
|
local get_active_list = dlfs.get_active_list
|
||||||
|
local get_history_list = dlfs.get_history_list
|
||||||
|
local get_pause_list = dlfs.get_pause_list
|
||||||
|
local remove_download_result = dlfs.remove_download_result
|
||||||
|
local download_task_start = dlfs.download_task_start
|
||||||
|
local start_download_intranet = dlfs.start_download_intranet
|
||||||
|
local ww_thunder_get_bind_code = dlfs.ww_thunder_get_bind_code
|
||||||
|
|
||||||
|
local table_merge = bfs.table_merge
|
||||||
|
|
||||||
|
local delete_access_token = dbfs.delete_access_token
|
||||||
|
|
||||||
|
function sip_get_parameters(commandId)
|
||||||
|
local url = "https://router.meizu.com/oauth/router/command/routerRequest?"
|
||||||
|
local https = require("ssl.https")
|
||||||
|
local access_token = rts_get_access_token()
|
||||||
|
local newurl = url.."access_token="..access_token
|
||||||
|
newurl = newurl.."&commandId="..commandId
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, url)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local res, code, headers, status = https.request(newurl)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, code)
|
||||||
|
require "MZLog".log(3, status)
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if code == 401 then
|
||||||
|
delete_access_token()
|
||||||
|
access_token = rts_get_access_token()
|
||||||
|
local newurl = url.."access_token="..access_token
|
||||||
|
newurl = newurl.."&commandId="..commandId
|
||||||
|
res, code, headers, status = https.request(newurl)
|
||||||
|
end
|
||||||
|
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function sip_response_uploader(cmd, commandId, data, finishstatus)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
if data == nil or data == "" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local data = data
|
||||||
|
if (type(data) == "string") then
|
||||||
|
data = require("luci.http").urlencode(data)
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local url="https://router.meizu.com/oauth/router/command/updateResponse"
|
||||||
|
local https = require("ssl.https")
|
||||||
|
local timemini = os.date("%s")
|
||||||
|
local access_token = rts_get_access_token()
|
||||||
|
local pd = init_update_resp_pd(access_token, commandId, data, finishstatus, timemini)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, url)
|
||||||
|
require "MZLog".log(3, "sip_response_uploader data len:"..string.len(pd))
|
||||||
|
require "MZLog".log(3, pd)
|
||||||
|
local res, code, headers, status = https.request(url, pd)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, code)
|
||||||
|
require "MZLog".log(3, status)
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if code == 401 then
|
||||||
|
delete_access_token()
|
||||||
|
access_token = rts_get_access_token()
|
||||||
|
pd = init_update_resp_pd(access_token, commandId, data, finishstatus, timemini)
|
||||||
|
res, code, headers, status = https.request(url, pd)
|
||||||
|
end
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function init_update_resp_pd(access_token, commandId, data, finishstatus, timemini)
|
||||||
|
local pd = "access_token="..access_token
|
||||||
|
pd = pd.."&commandId="..commandId
|
||||||
|
pd = pd.."&commandResponse="..(data or "")
|
||||||
|
local status = 2
|
||||||
|
if finishstatus then
|
||||||
|
status = finishstatus
|
||||||
|
end
|
||||||
|
pd = pd.."&status="..status
|
||||||
|
pd = pd.."&lastExcuteTime="..timemini
|
||||||
|
return pd
|
||||||
|
end
|
||||||
|
|
||||||
|
function download_list_post_process(data, refine_cnt)
|
||||||
|
local new_data = {}
|
||||||
|
local jsd = cjson.decode(data)
|
||||||
|
local nd_msg = {}
|
||||||
|
if type(jsd) == "table" then
|
||||||
|
local msg = ""
|
||||||
|
for k, v in pairs(jsd) do
|
||||||
|
if k and k == "message" then
|
||||||
|
msg = v
|
||||||
|
else
|
||||||
|
new_data[k] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if type(msg) == "table" and _G.next(msg) ~= nil then
|
||||||
|
local cnt = 0
|
||||||
|
for k, v in pairs(msg) do
|
||||||
|
if cnt < refine_cnt then
|
||||||
|
table.insert(nd_msg, v)
|
||||||
|
cnt = cnt + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if _G.next(nd_msg) ~= nil then
|
||||||
|
new_data["message"] = nd_msg
|
||||||
|
else
|
||||||
|
new_data["message"] = "[]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nd_msg
|
||||||
|
end
|
||||||
|
|
||||||
|
function download_task_operate_process(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local gid = jsr.gid
|
||||||
|
ret = download_task_operate(gid, cmd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ww_exec_reboot(cmd, cmdid)
|
||||||
|
local ret = {}
|
||||||
|
ret["result"] = true
|
||||||
|
sip_response_uploader(cmd, cmdid, data_to_json(ret))
|
||||||
|
exec_reboot()
|
||||||
|
end
|
||||||
|
|
||||||
|
sip_cmd_process_action = {
|
||||||
|
["getFilesList"] = function (cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local path = nil
|
||||||
|
local start = nil
|
||||||
|
local count = nil
|
||||||
|
local IMEI = nil
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
require "MZLog".log(3, v)
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
path = jsr.path
|
||||||
|
start = jsr.start
|
||||||
|
count = jsr.count
|
||||||
|
IMEI = jsr.IMEI
|
||||||
|
require "MZLog".log(3, path)
|
||||||
|
require "MZLog".log(3, start)
|
||||||
|
require "MZLog".log(3, count)
|
||||||
|
require "MZLog".log(3, IMEI)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
path = string.gsub(path, "router", "mnt")
|
||||||
|
require "MZLog".log(3, path)
|
||||||
|
local data = get_files_list(path, start, count, IMEI)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
--luci.http.write(data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["downloadstart"] = function (cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local url_jsr = cjson.decode(v)
|
||||||
|
local url = url_jsr.url
|
||||||
|
local dltype = url_jsr.type
|
||||||
|
require "MZLog".log(3, url)
|
||||||
|
require "MZLog".log(3, dltype)
|
||||||
|
ret = download_task_start(url, dltype)
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["downloadpause"] = function (cmd, cmdid)
|
||||||
|
download_task_operate_process(cmd, cmdid)
|
||||||
|
end,
|
||||||
|
["downloadunpause"] = function (cmd, cmdid)
|
||||||
|
download_task_operate_process(cmd, cmdid)
|
||||||
|
end,
|
||||||
|
["downloadremove"] = function (cmd, cmdid)
|
||||||
|
download_task_operate_process(cmd, cmdid)
|
||||||
|
end,
|
||||||
|
["getPauseList"] = function (cmd, cmdid)
|
||||||
|
local data = get_pause_list()
|
||||||
|
--data = download_list_post_process(data, 4)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["getActiveList"] = function (cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local cr_jsr = cjson.decode(v)
|
||||||
|
local start = cr_jsr.start
|
||||||
|
local count = cr_jsr.count
|
||||||
|
ret = get_active_list(start, count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["getHistoryList"] = function (cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local cr_jsr = cjson.decode(v)
|
||||||
|
local start = cr_jsr.start
|
||||||
|
local count = cr_jsr.count
|
||||||
|
ret = get_history_list(start, count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["thundergetbindcode"] = function (cmd, cmdid)
|
||||||
|
local data = ww_thunder_get_bind_code()
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["realtimenetspeed"] = function(cmd, cmdid)
|
||||||
|
local data = data_to_json(real_time_net_speed())
|
||||||
|
sip_response_uploader(cmd, cmdid, data, 2)
|
||||||
|
end,
|
||||||
|
["factoryreset"] = function(cmd, cmdid)
|
||||||
|
local data = '{'..'status:"reset factory ok."'..'}'
|
||||||
|
local data = factory_reset()
|
||||||
|
sip_response_uploader(cmd, cmdid, data_to_json(data))
|
||||||
|
end,
|
||||||
|
["getDeviceList"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = ww_get_connect_device_list()
|
||||||
|
data = data_to_json(data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["getwifisettings"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
local app_version = nil
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
if #v > 1 then
|
||||||
|
local value = cjson.decode(v)
|
||||||
|
app_version = value.appVer
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if app_version == nil then
|
||||||
|
app_version = 0
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, app_version)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = ww_get_wifi_settings(app_version)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["setwifisettings"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
|
||||||
|
local value = jsr.value
|
||||||
|
local switch_2g = nil
|
||||||
|
local switch_5g = nil
|
||||||
|
local switch_guest = nil
|
||||||
|
local ssid_2g = nil
|
||||||
|
local ssid_5g = nil
|
||||||
|
local ssid_guest = nil
|
||||||
|
local pwd_2g = nil
|
||||||
|
local pwd_5g = nil
|
||||||
|
local pwd_guest = nil
|
||||||
|
local encry_2g = nil
|
||||||
|
local encry_5g = nil
|
||||||
|
local encry_guest = nil
|
||||||
|
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, v)
|
||||||
|
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local value = cjson.decode(v)
|
||||||
|
require "MZLog".log(3, value)
|
||||||
|
local base64 = value.base64
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, base64)
|
||||||
|
local app_version = value.appVer
|
||||||
|
if app_version == nil then
|
||||||
|
app_version = 0
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, app_version)
|
||||||
|
|
||||||
|
if tonumber(app_version) >= 5 then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, base64)
|
||||||
|
v = b64dec(base64)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, v)
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
for key, value in pairs(jsr) do
|
||||||
|
if value.name == "wl0" then
|
||||||
|
switch_2g = value.on
|
||||||
|
ssid_2g = value.ssid
|
||||||
|
pwd_2g = value.pwd
|
||||||
|
encry_2g = value.encryption
|
||||||
|
elseif value.name == "wl1" then
|
||||||
|
switch_5g = value.on
|
||||||
|
ssid_5g = value.ssid
|
||||||
|
pwd_5g = value.pwd
|
||||||
|
encry_5g = value.encryption
|
||||||
|
else
|
||||||
|
switch_guest = value.on
|
||||||
|
ssid_guest = value.ssid
|
||||||
|
pwd_guest = value.pwd
|
||||||
|
encry_guest = value.encryption
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local value = cjson.decode(v)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, value)
|
||||||
|
switch_2g = value.on1
|
||||||
|
ssid_2g = value.ssid1
|
||||||
|
pwd_2g = value.pwd1
|
||||||
|
encry_2g = value.encryption1
|
||||||
|
switch_5g = value.on2
|
||||||
|
ssid_5g = value.ssid2
|
||||||
|
pwd_5g = value.pwd2
|
||||||
|
encry_5g = value.encryption2
|
||||||
|
switch_guest = value.on3
|
||||||
|
ssid_guest = value.ssid3
|
||||||
|
pwd_guest = value.pwd3
|
||||||
|
encry_guest = value.encryption3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local data = wifi_settings(switch_2g, ssid_2g, pwd_2g, encry_2g, switch_5g, ssid_5g, pwd_5g, encry_5g, switch_guest, ssid_guest, pwd_guest, encry_guest)
|
||||||
|
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
data = cjson.encode(data)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["checkRouterUpdate"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = check_upgrade()
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["executeRouterUpdate"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = do_upgrade()
|
||||||
|
if data ~= "" then
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
["setDeviceName"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local mac = nil
|
||||||
|
local devicename = nil
|
||||||
|
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
mac = jsr.mac
|
||||||
|
devicename = jsr.devicename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = set_device_name(mac, devicename)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["setWanSwitch"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local mac = nil
|
||||||
|
local mode = nil
|
||||||
|
local enable = nil
|
||||||
|
local value = jsr.value
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
mac = jsr.mac
|
||||||
|
mode = jsr.mode
|
||||||
|
enable = jsr.enable
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local data = set_wan_switch(mac, mode, enable)
|
||||||
|
data = data_to_json(data)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["setDiskAccess"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local mac = nil
|
||||||
|
local enable = nil
|
||||||
|
local value = jsr.value
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
mac = jsr.mac
|
||||||
|
enable = jsr.enable
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local data = set_disk_access(mac, enable)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
data = data_to_json(data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["getSmbSwitch"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = get_smb_switch()
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["setSmbSwitch"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local smbswitch = nil
|
||||||
|
local value = jsr.value
|
||||||
|
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
smbswitch = jsr.smbswitch
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local data = set_smb_switch(smbswitch)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["setReboot"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
ww_exec_reboot(cmd, cmdid)
|
||||||
|
end,
|
||||||
|
["getdevicedetails"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
ret = data_to_json(ww_get_device_details(mac))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["getDiskInfo"] = function(cmd, cmdid)
|
||||||
|
local data = ww_get_disk_info()
|
||||||
|
data = data_to_json(data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["getsysinfo"] = function(cmd, cmdid)
|
||||||
|
local data = require "meizu.bfs".sysinfo()
|
||||||
|
data = data_to_json(data)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["gettxpowermode"] = function(cmd, cmdid)
|
||||||
|
local ret = ww_get_tx_power_mode()
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["settxpowermode"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mode = jsr.mode
|
||||||
|
ret = data_to_json(ww_set_tx_power_mode(mode))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["getWirelessChannel"] = function(cmd, cmdid)
|
||||||
|
local ret = ww_get_wireless_channel()
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["setWirelessChannel"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local channel = jsr.channel
|
||||||
|
ret = data_to_json(ww_set_wireless_channel(channel))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
["scanBleSwitch"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local status = jsr.status
|
||||||
|
ret = ww_scan_ble_switch(status)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["getBleDeviceList"] = function(cmd, cmdid)
|
||||||
|
local data = ww_get_ble_device_list()
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["addMeshDevice"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
ret = ww_add_ble_mesh_device(mac)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["getMeshDeviceDetail"] = function(cmd, cmdid)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, value)
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, mac)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
ret = ww_get_ble_device_status(mac)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["removeblefrommesh"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
ret = ww_remove_ble_from_mesh(mac)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["getMeshDeviceList"] = function(cmd, cmdid)
|
||||||
|
local data = ww_get_mesh_device_list()
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["setMeshDeviceAttr"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
local key = jsr.key
|
||||||
|
local value = jsr.value
|
||||||
|
ret = ww_set_mesh_device_attr(mac, key, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["rebootmeshdevice"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
ret = ww_reboot_mesh_device(mac)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["unmeshalldevice"] = function(cmd, cmdid)
|
||||||
|
local data = ww_unmesh_all_device()
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, data)
|
||||||
|
end,
|
||||||
|
["setmeshdevicetimer"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
local timer_id = jsr.timerId
|
||||||
|
local flag = jsr.flag
|
||||||
|
local start = jsr.start
|
||||||
|
local ends = jsr.ends
|
||||||
|
ret = ww_set_mesh_device_timer(mac, timer_id, flag, start, ends)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["setMeshNetWorkPassword"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local old_key = jsr.oldkey
|
||||||
|
local new_key = jsr.newkey
|
||||||
|
ret = ww_set_mesh_network_pwd(old_key, new_key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["setLampBrightness"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
local timer_id = jsr.timerId
|
||||||
|
local flag = jsr.flag
|
||||||
|
local start = jsr.start
|
||||||
|
local ends = jsr.ends
|
||||||
|
ret = ww_set_lamp_brightness(mac, timer_id, flag, start, ends)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
["delmeshdevicetimer"] = function(cmd, cmdid)
|
||||||
|
local data = sip_get_parameters(cmdid)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
local value = jsr.value
|
||||||
|
local ret = ""
|
||||||
|
if (jsr.code) == "200" then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "commandRequest" then
|
||||||
|
local jsr = cjson.decode(v)
|
||||||
|
local mac = jsr.mac
|
||||||
|
local timer_id = jsr.timerId
|
||||||
|
ret = ww_del_mesh_device_timer(mac, timer_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sip_response_uploader(cmd, cmdid, ret)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
--"{ \"size\": \"14.12MB\", \"version\": \"1.0.10\" }"
|
||||||
|
function OTA_process_action(vs_info)
|
||||||
|
require "MZLog".log(3, "get OTA new Version:")
|
||||||
|
require "MZLog".log(3, vs_info)
|
||||||
|
require "meizu.upgdfs".push_new_version_msg()
|
||||||
|
end
|
||||||
|
|
||||||
|
--sip data format:
|
||||||
|
--{ "push_event": [ { "appid": "com.meizu.router", "data": { "business": "1", "commandId": "54", "type": "realtimenetspeed" } } ] }
|
||||||
|
--post d = '{"business":"1","commandId":"53","type":"speed"}'
|
||||||
|
function sip()
|
||||||
|
local ret;
|
||||||
|
--local data = '{"business":"1","commandId":"53","type":"speed"}'
|
||||||
|
local data = luci.http.formvalue("d")
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
if data ~= nil then
|
||||||
|
local data = b64dec(data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local jsr = cjson.decode(data)
|
||||||
|
if jsr.type ~= nil then
|
||||||
|
ret = sip_cmd_process_action[jsr.type](jsr.type, jsr.commandId)
|
||||||
|
else
|
||||||
|
if jsr["com.meizu.router"] ~= nil then
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, "OTA push message:")
|
||||||
|
require "MZLog".log(3, data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
OTA_process_action(jsr["com.meizu.router"])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
luci.http.write_json("sip done.")
|
||||||
|
end
|
||||||
|
|
||||||
|
function pysip()
|
||||||
|
local ret;
|
||||||
|
local cmd = luci.http.formvalue("cmd")
|
||||||
|
local commandId = luci.http.formvalue("commandId")
|
||||||
|
if cmd ~= nil then
|
||||||
|
ret = sip_cmd_process_action[cmd](cmd, commandId)
|
||||||
|
end
|
||||||
|
luci.http.write_json("pysip: "..cmd.." "..commandId.." done.")
|
||||||
|
luci.http.close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function upload_router_log(logdata, logtype)
|
||||||
|
local https = require("ssl.https")
|
||||||
|
local url="https://router.meizu.com/oauth/router/upLog"
|
||||||
|
local access_token = rts_get_access_token()
|
||||||
|
local pd = init_upload_router_log_pd(access_token, logtype, logdata)
|
||||||
|
local res, code, headers, status = https.request(url, pd)
|
||||||
|
if code == 401 then
|
||||||
|
delete_access_token()
|
||||||
|
access_token = rts_get_access_token()
|
||||||
|
pd = init_upload_router_log_pd(access_token, logtype, logdata)
|
||||||
|
res, code, headers, status = https.request(url, pd)
|
||||||
|
end
|
||||||
|
return res, code, headers, status
|
||||||
|
end
|
||||||
|
|
||||||
|
function init_upload_router_log_pd(access_token, logtype, logdata)
|
||||||
|
local pd = "access_token="..access_token
|
||||||
|
if logtype then
|
||||||
|
pd = pd.."&type="..logtype
|
||||||
|
else
|
||||||
|
pd = pd.."&type=".."4"
|
||||||
|
end
|
||||||
|
pd = pd.."&content="..(logdata or "")
|
||||||
|
return pd
|
||||||
|
end
|
256
Me_Lua/h10/meizu/upgdfs.lua
Normal file
256
Me_Lua/h10/meizu/upgdfs.lua
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
module("meizu.upgdfs", package.seeall)
|
||||||
|
|
||||||
|
local cjson = require "cjson"
|
||||||
|
local bfs = require "meizu.bfs"
|
||||||
|
local sipfs = require "meizu.sipfs"
|
||||||
|
|
||||||
|
local b64dec = bfs.b64dec
|
||||||
|
local batchfile_checklist = bfs.batchfile_checklist
|
||||||
|
local batchfile_compare_upload = bfs.batchfile_compare_upload
|
||||||
|
local bind_router = bfs.bind_router
|
||||||
|
local cal_str_md5 = bfs.cal_str_md5
|
||||||
|
local data_to_json = bfs.data_to_json
|
||||||
|
local exec_cmd_in_sh = bfs.exec_cmd_in_sh
|
||||||
|
local exec_reboot = bfs.exec_reboot
|
||||||
|
local findInDir = bfs.findInDir
|
||||||
|
local get_device_SN = bfs.get_device_SN
|
||||||
|
local get_device_version = bfs.get_device_version
|
||||||
|
local get_https_data = bfs.get_https_data
|
||||||
|
local rts_get_access_token = bfs.rts_get_access_token
|
||||||
|
local set_passwd = bfs.set_passwd
|
||||||
|
local silent_upgrade = bfs.silent_upgrade
|
||||||
|
local table_merge = bfs.table_merge
|
||||||
|
|
||||||
|
function upgrade_lock()
|
||||||
|
return os.execute(RC.upgrade_lock)
|
||||||
|
end
|
||||||
|
|
||||||
|
function upgrade_unlock()
|
||||||
|
return os.execute(RC.upgrade_unlock)
|
||||||
|
end
|
||||||
|
|
||||||
|
function push_new_version_msg()
|
||||||
|
--type:4 (有新固件更新)
|
||||||
|
--msg = "{\"size\": \"14.12MB\", \"version\": \"1.0.10\" }"
|
||||||
|
local logtype = 4
|
||||||
|
local msg = check_upgrade()
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, "OTA push_new_version_msg:"..data)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
sipfs.upload_router_log(msg, logtype)
|
||||||
|
end
|
||||||
|
|
||||||
|
function push_fw_upgrading_msg(url)
|
||||||
|
local logtype = 6
|
||||||
|
local msg = {}
|
||||||
|
msg["code"] = 2005
|
||||||
|
msg["result"] = "upgrading...."
|
||||||
|
msg = data_to_json(msg)
|
||||||
|
local res, code, headers, status = sipfs.upload_router_log(msg, logtype)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, code)
|
||||||
|
require "MZLog".log(3, headers)
|
||||||
|
require "MZLog".log(3, status)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
end
|
||||||
|
|
||||||
|
function push_upgrade_finish_msg()
|
||||||
|
--(5) type:5 (固件更新完成)
|
||||||
|
local logtype = 5
|
||||||
|
local msg = {}
|
||||||
|
--"content": "{ \"version\": \"5.0\", \"size\": \"14088999\" }"
|
||||||
|
msg["version"] = get_device_version()
|
||||||
|
msg["size"] = 0
|
||||||
|
msg = data_to_json(msg)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, "push_upgrade_finish_msg:"..msg)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
local res, code, headers, status = sipfs.upload_router_log(msg, logtype)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, code)
|
||||||
|
require "MZLog".log(3, headers)
|
||||||
|
require "MZLog".log(3, status)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
end
|
||||||
|
|
||||||
|
function subscribe_auto_upgrade()
|
||||||
|
local http = require("socket.http")
|
||||||
|
local url = "http://u.meizu.com/api/v1/upgrade/subscribe"
|
||||||
|
local serviceCode = "com.meizu.router"
|
||||||
|
local pd = "serviceCode="..serviceCode
|
||||||
|
local sn = get_device_SN()
|
||||||
|
local sipToken = sn.."100032"
|
||||||
|
pd = pd.."&sipToken="..sipToken
|
||||||
|
local device = sn
|
||||||
|
pd = pd.."&device="..device
|
||||||
|
local version = get_device_version()
|
||||||
|
pd = pd.."&version="..version
|
||||||
|
local deviceModel = "R10"
|
||||||
|
pd = pd.."&deviceModel="..deviceModel
|
||||||
|
local key = "2635881a7ab0593849fe89e685fc56cd"
|
||||||
|
local toSignStr = serviceCode..sipToken..version..key
|
||||||
|
require "MZLog".log(3, url)
|
||||||
|
require "MZLog".log(3, pd)
|
||||||
|
pd = pd.."&sign="..cal_str_md5(toSignStr)
|
||||||
|
local res, code, headers, status = http.request(url, pd)
|
||||||
|
|
||||||
|
require "MZLog".log(3, res, code, headers, status)
|
||||||
|
return res, code, headers, status
|
||||||
|
end
|
||||||
|
|
||||||
|
function gen_check_fw_url_pd()
|
||||||
|
local serviceCode = "com.meizu.router"
|
||||||
|
local pd = "serviceCode="..serviceCode
|
||||||
|
local sn = get_device_SN()
|
||||||
|
local device = sn
|
||||||
|
pd = pd.."&device="..device
|
||||||
|
local deviceModel = "R10"
|
||||||
|
pd = pd.."&deviceModel="..deviceModel
|
||||||
|
local root = "true"
|
||||||
|
pd = pd.."&root="..root
|
||||||
|
local version = get_device_version()
|
||||||
|
pd = pd.."&version="..version
|
||||||
|
local key = "2635881a7ab0593849fe89e685fc56cd"
|
||||||
|
local toSignStr = serviceCode..device..deviceModel..root..version..key
|
||||||
|
pd = pd.."&sign="..cal_str_md5(toSignStr)
|
||||||
|
|
||||||
|
return pd
|
||||||
|
end
|
||||||
|
|
||||||
|
function check_upgrade()
|
||||||
|
local ret = {}
|
||||||
|
local http = require("socket.http")
|
||||||
|
local url = "http://u.meizu.com/api/v1/upgrade/check/router"
|
||||||
|
local pd = gen_check_fw_url_pd()
|
||||||
|
local res, code, headers, status = http.request(url, pd)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, pd)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if res == nil then
|
||||||
|
require "MZLog".log(3, "get "..url.." failed!")
|
||||||
|
ret["code"] = code;
|
||||||
|
return data_to_json(ret)
|
||||||
|
else
|
||||||
|
return res;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function do_upgrade()
|
||||||
|
local ret = {}
|
||||||
|
local http = require("socket.http")
|
||||||
|
local url = "http://u.meizu.com/api/v1/upgrade/check/router"
|
||||||
|
local serviceCode = "com.meizu.router"
|
||||||
|
local pd = gen_check_fw_url_pd()
|
||||||
|
local res, code, headers, status = http.request(url, pd)
|
||||||
|
if res == nil then
|
||||||
|
require "MZLog".log(3, "do_upgrade get "..url.." failed!")
|
||||||
|
ret["result"] = code;
|
||||||
|
return data_to_json(ret)
|
||||||
|
end
|
||||||
|
local data = cjson.decode(res)
|
||||||
|
local value = data.value
|
||||||
|
local digest = ""
|
||||||
|
local filesize = 0
|
||||||
|
local upgrade_url = ""
|
||||||
|
if (data.code) == 200 then
|
||||||
|
for k,v in pairs(value) do
|
||||||
|
if k == "size" then
|
||||||
|
filesize = v
|
||||||
|
end
|
||||||
|
if k == "url" then
|
||||||
|
upgrade_url = v
|
||||||
|
end
|
||||||
|
if k == "digest" then
|
||||||
|
digest = v
|
||||||
|
end
|
||||||
|
if k == "version" then
|
||||||
|
version = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if upgrade_url ~= "" then
|
||||||
|
require "MZLog".log(3, upgrade_urogtype)
|
||||||
|
push_fw_upgrading_msg(upgrade_url)
|
||||||
|
local ota_img = "/tmp/ota.trx"
|
||||||
|
local cmd = "wget '"..upgrade_url.."' -O "..ota_img..[[;]]
|
||||||
|
cmd = cmd..[[nvram set upgrading=1;nvram commit;]]
|
||||||
|
cmd = cmd..[[killall dropbear uhttpd; sleep 1;]]
|
||||||
|
cmd = cmd..[[/sbin/sysupgrade -v ]]..ota_img..[[|tee -a /tmp/ota.log;]]
|
||||||
|
ret = exec_cmd_in_sh(cmd)
|
||||||
|
--to do : add UCI set upgrade flag .
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function check_mandatory_upgrade()
|
||||||
|
local ret = {}
|
||||||
|
local http = require("socket.http")
|
||||||
|
local url = "http://u.meizu.com/api/v1/upgrade/check/router"
|
||||||
|
local pd = gen_check_fw_url_pd()
|
||||||
|
local res, code, headers, status = http.request(url, pd)
|
||||||
|
local upgrade_url = ""
|
||||||
|
local flag = false
|
||||||
|
if code == 200 then
|
||||||
|
local data = cjson.decode(res)
|
||||||
|
local value = data.value
|
||||||
|
if (data.code) == 200 then
|
||||||
|
for k, v in pairs(value) do
|
||||||
|
if k == "url" then
|
||||||
|
upgrade_url = v
|
||||||
|
end
|
||||||
|
if k == "mandatoryClear" and v == true then
|
||||||
|
flag = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if flag then
|
||||||
|
do_upgrade()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function local_upgrade()
|
||||||
|
local fd = nil
|
||||||
|
local nixio = require "nixio"
|
||||||
|
local image = "/tmp/ota.trx"
|
||||||
|
local touchcmd = "touch "..image
|
||||||
|
exec_cmd_in_sh(touchcmd)
|
||||||
|
local function image_supported()
|
||||||
|
return ( 0 == os.execute(
|
||||||
|
". /lib/functions.sh; " ..
|
||||||
|
"include /lib/upgrade; " ..
|
||||||
|
"platform_check_image %q >/dev/null"
|
||||||
|
% image
|
||||||
|
))
|
||||||
|
end
|
||||||
|
luci.http.setfilehandler(
|
||||||
|
function(field, chunk, eof)
|
||||||
|
if not fd then
|
||||||
|
fd = nixio.open(image, "w")
|
||||||
|
end
|
||||||
|
fd:write(chunk)
|
||||||
|
if eof and fd then
|
||||||
|
fd:close()
|
||||||
|
fd = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
)
|
||||||
|
local clean = (luci.http.formvalue("clean") == "1") and "-n" or ""
|
||||||
|
if image_supported() then
|
||||||
|
local lue = require"luci.util".exec
|
||||||
|
local cmd = [[nvram set upgrading=1;nvram commit;]]
|
||||||
|
lue(cmd)
|
||||||
|
luci.http.write("updating")
|
||||||
|
exec_cmd_in_sh("killall dropbear uhttpd; sleep 1; /sbin/sysupgrade -v %s %q" %{ clean, image })
|
||||||
|
luci.http.write("update finished!")
|
||||||
|
else
|
||||||
|
luci.http.write("image_supported check failed!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--push_new_version_msg("test")
|
||||||
|
--subscribe_auto_upgrade()
|
||||||
|
--local res = check_upgrade()
|
||||||
|
--print(res)
|
||||||
|
--do_upgrade()
|
90
Me_Lua/h10/mime.lua
Normal file
90
Me_Lua/h10/mime.lua
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- MIME support for the Lua language.
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-- Conforming to RFCs 2045-2049
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Declare module and import dependencies
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local base = _G
|
||||||
|
local ltn12 = require("ltn12")
|
||||||
|
local mime = require("mime.core")
|
||||||
|
local io = require("io")
|
||||||
|
local string = require("string")
|
||||||
|
local _M = mime
|
||||||
|
|
||||||
|
-- encode, decode and wrap algorithm tables
|
||||||
|
local encodet, decodet, wrapt = {},{},{}
|
||||||
|
|
||||||
|
_M.encodet = encodet
|
||||||
|
_M.decodet = decodet
|
||||||
|
_M.wrapt = wrapt
|
||||||
|
|
||||||
|
-- creates a function that chooses a filter by name from a given table
|
||||||
|
local function choose(table)
|
||||||
|
return function(name, opt1, opt2)
|
||||||
|
if base.type(name) ~= "string" then
|
||||||
|
name, opt1, opt2 = "default", name, opt1
|
||||||
|
end
|
||||||
|
local f = table[name or "nil"]
|
||||||
|
if not f then
|
||||||
|
base.error("unknown key (" .. base.tostring(name) .. ")", 3)
|
||||||
|
else return f(opt1, opt2) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- define the encoding filters
|
||||||
|
encodet['base64'] = function()
|
||||||
|
return ltn12.filter.cycle(_M.b64, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
encodet['quoted-printable'] = function(mode)
|
||||||
|
return ltn12.filter.cycle(_M.qp, "",
|
||||||
|
(mode == "binary") and "=0D=0A" or "\r\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- define the decoding filters
|
||||||
|
decodet['base64'] = function()
|
||||||
|
return ltn12.filter.cycle(_M.unb64, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
decodet['quoted-printable'] = function()
|
||||||
|
return ltn12.filter.cycle(_M.unqp, "")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function format(chunk)
|
||||||
|
if chunk then
|
||||||
|
if chunk == "" then return "''"
|
||||||
|
else return string.len(chunk) end
|
||||||
|
else return "nil" end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- define the line-wrap filters
|
||||||
|
wrapt['text'] = function(length)
|
||||||
|
length = length or 76
|
||||||
|
return ltn12.filter.cycle(_M.wrp, length, length)
|
||||||
|
end
|
||||||
|
wrapt['base64'] = wrapt['text']
|
||||||
|
wrapt['default'] = wrapt['text']
|
||||||
|
|
||||||
|
wrapt['quoted-printable'] = function()
|
||||||
|
return ltn12.filter.cycle(_M.qpwrp, 76, 76)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- function that choose the encoding, decoding or wrap algorithm
|
||||||
|
_M.encode = choose(encodet)
|
||||||
|
_M.decode = choose(decodet)
|
||||||
|
_M.wrap = choose(wrapt)
|
||||||
|
|
||||||
|
-- define the end-of-line normalization filter
|
||||||
|
function _M.normalize(marker)
|
||||||
|
return ltn12.filter.cycle(_M.eol, 0, marker)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- high level stuffing filter
|
||||||
|
function _M.stuff()
|
||||||
|
return ltn12.filter.cycle(_M.dot, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
return _M
|
BIN
Me_Lua/h10/mime.so.1.0.3
Normal file
BIN
Me_Lua/h10/mime.so.1.0.3
Normal file
Binary file not shown.
BIN
Me_Lua/h10/mime/core.so
Normal file
BIN
Me_Lua/h10/mime/core.so
Normal file
Binary file not shown.
BIN
Me_Lua/h10/posix.so
Normal file
BIN
Me_Lua/h10/posix.so
Normal file
Binary file not shown.
144
Me_Lua/h10/routerReport.lua
Normal file
144
Me_Lua/h10/routerReport.lua
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
local bfs = require("meizu.bfs")
|
||||||
|
local dbfs = require("meizu.dbfs")
|
||||||
|
local upgdfs = require("meizu.upgdfs")
|
||||||
|
|
||||||
|
local get_device_SN = bfs.get_device_SN
|
||||||
|
local get_device_version = bfs.get_device_version
|
||||||
|
local get_https_data = bfs.get_https_data
|
||||||
|
local rts_get_access_token = bfs.rts_get_access_token
|
||||||
|
|
||||||
|
local delete_access_token = dbfs.delete_access_token
|
||||||
|
|
||||||
|
function getBasicInfo()
|
||||||
|
local sn = get_device_SN()
|
||||||
|
local url = "https://router.meizu.com/oauth/router/getBasicInfo?access_token="
|
||||||
|
local access_token = rts_get_access_token()
|
||||||
|
local newurl = url..access_token.."&device="..sn
|
||||||
|
local res, code, headers, status = get_https_data(newurl)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, newurl)
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if code == 401 then
|
||||||
|
delete_access_token()
|
||||||
|
access_token = rts_get_access_token()
|
||||||
|
newurl = url..access_token.."&device="..sn
|
||||||
|
res, code, headers, status = get_https_data(newurl)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function upRouterPushId()
|
||||||
|
local sn = get_device_SN()
|
||||||
|
local pushId = sn.."100032"
|
||||||
|
local url="https://router.meizu.com/oauth/router/upRouterPushId"
|
||||||
|
local access_token = rts_get_access_token()
|
||||||
|
local postData = "access_token="..access_token.."&pushId="..pushId
|
||||||
|
local res, code, headers, status = get_https_data(url, postData)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, url)
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if code == 401 then
|
||||||
|
delete_access_token()
|
||||||
|
access_token = rts_get_access_token()
|
||||||
|
postData = "access_token="..access_token.."&pushId="..pushId
|
||||||
|
res, code, headers, status = get_https_data(url, postData)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function report_rom_version()
|
||||||
|
local ver = get_device_version()
|
||||||
|
local url="https://router.meizu.com/oauth/router/updateStatus"
|
||||||
|
local access_token = rts_get_access_token()
|
||||||
|
local data = "&name=romversion&value="..ver
|
||||||
|
local pd = "access_token="..access_token..data
|
||||||
|
local res, code, headers, status = get_https_data(url, pd)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, url)
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if code == 401 then
|
||||||
|
delete_access_token()
|
||||||
|
access_token = rts_get_access_token()
|
||||||
|
pd = "access_token="..access_token..data
|
||||||
|
res, code, headers, status = get_https_data(url, pd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function report_uptime()
|
||||||
|
local timestamp = os.time()
|
||||||
|
local url="https://router.meizu.com/oauth/router/updateStatus"
|
||||||
|
local access_token = rts_get_access_token()
|
||||||
|
local data = "&name=uptime&value="..timestamp
|
||||||
|
local pd = "access_token="..access_token..data
|
||||||
|
local res, code, headers, status = get_https_data(url, pd)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, url)
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
if code == 401 then
|
||||||
|
delete_access_token()
|
||||||
|
access_token = rts_get_access_token()
|
||||||
|
pd = "access_token="..access_token..data
|
||||||
|
res, code, headers, status = get_https_data(url, pd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function check_upgrade_status()
|
||||||
|
local lu = require("luci.util")
|
||||||
|
local cmd = [[nvram get upgrading|awk '{printf $1}']]
|
||||||
|
local ret = lu.exec(cmd)
|
||||||
|
if ret == "1" then
|
||||||
|
local res, code, headers, status = upgdfs.push_upgrade_finish_msg()
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
require "MZLog".log(3, "check_upgrade_status")
|
||||||
|
require "MZLog".log(3, res)
|
||||||
|
require "MZLog".log(3, code)
|
||||||
|
require "MZLog".log(3, headers)
|
||||||
|
require "MZLog".log(3, status)
|
||||||
|
require "MZLog".log(3, debug.getinfo(1).currentline)
|
||||||
|
cmd = [[nvram unset upgrading;nvram commit;]]
|
||||||
|
lu.exec(cmd)
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function ping_rts_server()
|
||||||
|
local lu = require("luci.util")
|
||||||
|
local cmd = "sleep 2;ping -W 2 -c 1 router.meizu.com > /dev/null ;echo -n $?"
|
||||||
|
local ret = lu.exec(cmd)
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
function ut()
|
||||||
|
local lu = require("luci.util")
|
||||||
|
local cmd = "uptime"
|
||||||
|
local ret = lu.exec(cmd)
|
||||||
|
require "MZLog".log(3, ret)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
ut()
|
||||||
|
|
||||||
|
dbfs.init_wireless_device_table()
|
||||||
|
dbfs.init_wire_device_table()
|
||||||
|
|
||||||
|
require "MZLog".log(3, "start ping_rts_server()")
|
||||||
|
local ret = ping_rts_server()
|
||||||
|
while ret ~= "0" do
|
||||||
|
ret = ping_rts_server()
|
||||||
|
end
|
||||||
|
ut()
|
||||||
|
require "MZLog".log(3, "end ping_rts_server()")
|
||||||
|
require "MZLog".log(3, "getBasicInfo()")
|
||||||
|
getBasicInfo()
|
||||||
|
report_rom_version()
|
||||||
|
report_uptime()
|
||||||
|
require "MZLog".log(3, "upRouterPushId()")
|
||||||
|
upRouterPushId()
|
||||||
|
ut()
|
||||||
|
require "MZLog".log(3, "upgdfs.subscribe_auto_upgrade")
|
||||||
|
local res, code, headers, status = upgdfs.subscribe_auto_upgrade()
|
||||||
|
ut()
|
||||||
|
require "MZLog".log(3, res, code, headers, status)
|
||||||
|
ut()
|
||||||
|
check_upgrade_status()
|
149
Me_Lua/h10/socket.lua
Normal file
149
Me_Lua/h10/socket.lua
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- LuaSocket helper module
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Declare module and import dependencies
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local base = _G
|
||||||
|
local string = require("string")
|
||||||
|
local math = require("math")
|
||||||
|
local socket = require("socket.core")
|
||||||
|
|
||||||
|
local _M = socket
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Exported auxiliar functions
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
function _M.connect4(address, port, laddress, lport)
|
||||||
|
return socket.connect(address, port, laddress, lport, "inet")
|
||||||
|
end
|
||||||
|
|
||||||
|
function _M.connect6(address, port, laddress, lport)
|
||||||
|
return socket.connect(address, port, laddress, lport, "inet6")
|
||||||
|
end
|
||||||
|
|
||||||
|
function _M.bind(host, port, backlog)
|
||||||
|
if host == "*" then host = "0.0.0.0" end
|
||||||
|
local addrinfo, err = socket.dns.getaddrinfo(host);
|
||||||
|
if not addrinfo then return nil, err end
|
||||||
|
local sock, res
|
||||||
|
err = "no info on address"
|
||||||
|
for i, alt in base.ipairs(addrinfo) do
|
||||||
|
if alt.family == "inet" then
|
||||||
|
sock, err = socket.tcp()
|
||||||
|
else
|
||||||
|
sock, err = socket.tcp6()
|
||||||
|
end
|
||||||
|
if not sock then return nil, err end
|
||||||
|
sock:setoption("reuseaddr", true)
|
||||||
|
res, err = sock:bind(alt.addr, port)
|
||||||
|
if not res then
|
||||||
|
sock:close()
|
||||||
|
else
|
||||||
|
res, err = sock:listen(backlog)
|
||||||
|
if not res then
|
||||||
|
sock:close()
|
||||||
|
else
|
||||||
|
return sock
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
|
||||||
|
_M.try = _M.newtry()
|
||||||
|
|
||||||
|
function _M.choose(table)
|
||||||
|
return function(name, opt1, opt2)
|
||||||
|
if base.type(name) ~= "string" then
|
||||||
|
name, opt1, opt2 = "default", name, opt1
|
||||||
|
end
|
||||||
|
local f = table[name or "nil"]
|
||||||
|
if not f then base.error("unknown key (".. base.tostring(name) ..")", 3)
|
||||||
|
else return f(opt1, opt2) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Socket sources and sinks, conforming to LTN12
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- create namespaces inside LuaSocket namespace
|
||||||
|
local sourcet, sinkt = {}, {}
|
||||||
|
_M.sourcet = sourcet
|
||||||
|
_M.sinkt = sinkt
|
||||||
|
|
||||||
|
_M.BLOCKSIZE = 2048
|
||||||
|
|
||||||
|
sinkt["close-when-done"] = function(sock)
|
||||||
|
return base.setmetatable({
|
||||||
|
getfd = function() return sock:getfd() end,
|
||||||
|
dirty = function() return sock:dirty() end
|
||||||
|
}, {
|
||||||
|
__call = function(self, chunk, err)
|
||||||
|
if not chunk then
|
||||||
|
sock:close()
|
||||||
|
return 1
|
||||||
|
else return sock:send(chunk) end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
sinkt["keep-open"] = function(sock)
|
||||||
|
return base.setmetatable({
|
||||||
|
getfd = function() return sock:getfd() end,
|
||||||
|
dirty = function() return sock:dirty() end
|
||||||
|
}, {
|
||||||
|
__call = function(self, chunk, err)
|
||||||
|
if chunk then return sock:send(chunk)
|
||||||
|
else return 1 end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
sinkt["default"] = sinkt["keep-open"]
|
||||||
|
|
||||||
|
_M.sink = _M.choose(sinkt)
|
||||||
|
|
||||||
|
sourcet["by-length"] = function(sock, length)
|
||||||
|
return base.setmetatable({
|
||||||
|
getfd = function() return sock:getfd() end,
|
||||||
|
dirty = function() return sock:dirty() end
|
||||||
|
}, {
|
||||||
|
__call = function()
|
||||||
|
if length <= 0 then return nil end
|
||||||
|
local size = math.min(socket.BLOCKSIZE, length)
|
||||||
|
local chunk, err = sock:receive(size)
|
||||||
|
if err then return nil, err end
|
||||||
|
length = length - string.len(chunk)
|
||||||
|
return chunk
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
sourcet["until-closed"] = function(sock)
|
||||||
|
local done
|
||||||
|
return base.setmetatable({
|
||||||
|
getfd = function() return sock:getfd() end,
|
||||||
|
dirty = function() return sock:dirty() end
|
||||||
|
}, {
|
||||||
|
__call = function()
|
||||||
|
if done then return nil end
|
||||||
|
local chunk, err, partial = sock:receive(socket.BLOCKSIZE)
|
||||||
|
if not err then return chunk
|
||||||
|
elseif err == "closed" then
|
||||||
|
sock:close()
|
||||||
|
done = 1
|
||||||
|
return partial
|
||||||
|
else return nil, err end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
sourcet["default"] = sourcet["until-closed"]
|
||||||
|
|
||||||
|
_M.source = _M.choose(sourcet)
|
||||||
|
|
||||||
|
return _M
|
BIN
Me_Lua/h10/socket.so.3.0-rc1
Normal file
BIN
Me_Lua/h10/socket.so.3.0-rc1
Normal file
Binary file not shown.
BIN
Me_Lua/h10/socket/core.so
Normal file
BIN
Me_Lua/h10/socket/core.so
Normal file
Binary file not shown.
285
Me_Lua/h10/socket/ftp.lua
Normal file
285
Me_Lua/h10/socket/ftp.lua
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- FTP support for the Lua language
|
||||||
|
-- LuaSocket toolkit.
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Declare module and import dependencies
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local base = _G
|
||||||
|
local table = require("table")
|
||||||
|
local string = require("string")
|
||||||
|
local math = require("math")
|
||||||
|
local socket = require("socket")
|
||||||
|
local url = require("socket.url")
|
||||||
|
local tp = require("socket.tp")
|
||||||
|
local ltn12 = require("ltn12")
|
||||||
|
socket.ftp = {}
|
||||||
|
local _M = socket.ftp
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Program constants
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- timeout in seconds before the program gives up on a connection
|
||||||
|
_M.TIMEOUT = 60
|
||||||
|
-- default port for ftp service
|
||||||
|
_M.PORT = 21
|
||||||
|
-- this is the default anonymous password. used when no password is
|
||||||
|
-- provided in url. should be changed to your e-mail.
|
||||||
|
_M.USER = "ftp"
|
||||||
|
_M.PASSWORD = "anonymous@anonymous.org"
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Low level FTP API
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local metat = { __index = {} }
|
||||||
|
|
||||||
|
function _M.open(server, port, create)
|
||||||
|
local tp = socket.try(tp.connect(server, port or _M.PORT, _M.TIMEOUT, create))
|
||||||
|
local f = base.setmetatable({ tp = tp }, metat)
|
||||||
|
-- make sure everything gets closed in an exception
|
||||||
|
f.try = socket.newtry(function() f:close() end)
|
||||||
|
return f
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:portconnect()
|
||||||
|
self.try(self.server:settimeout(_M.TIMEOUT))
|
||||||
|
self.data = self.try(self.server:accept())
|
||||||
|
self.try(self.data:settimeout(_M.TIMEOUT))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:pasvconnect()
|
||||||
|
self.data = self.try(socket.tcp())
|
||||||
|
self.try(self.data:settimeout(_M.TIMEOUT))
|
||||||
|
self.try(self.data:connect(self.pasvt.ip, self.pasvt.port))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:login(user, password)
|
||||||
|
self.try(self.tp:command("user", user or _M.USER))
|
||||||
|
local code, reply = self.try(self.tp:check{"2..", 331})
|
||||||
|
if code == 331 then
|
||||||
|
self.try(self.tp:command("pass", password or _M.PASSWORD))
|
||||||
|
self.try(self.tp:check("2.."))
|
||||||
|
end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:pasv()
|
||||||
|
self.try(self.tp:command("pasv"))
|
||||||
|
local code, reply = self.try(self.tp:check("2.."))
|
||||||
|
local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)"
|
||||||
|
local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern))
|
||||||
|
self.try(a and b and c and d and p1 and p2, reply)
|
||||||
|
self.pasvt = {
|
||||||
|
ip = string.format("%d.%d.%d.%d", a, b, c, d),
|
||||||
|
port = p1*256 + p2
|
||||||
|
}
|
||||||
|
if self.server then
|
||||||
|
self.server:close()
|
||||||
|
self.server = nil
|
||||||
|
end
|
||||||
|
return self.pasvt.ip, self.pasvt.port
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:port(ip, port)
|
||||||
|
self.pasvt = nil
|
||||||
|
if not ip then
|
||||||
|
ip, port = self.try(self.tp:getcontrol():getsockname())
|
||||||
|
self.server = self.try(socket.bind(ip, 0))
|
||||||
|
ip, port = self.try(self.server:getsockname())
|
||||||
|
self.try(self.server:settimeout(_M.TIMEOUT))
|
||||||
|
end
|
||||||
|
local pl = math.mod(port, 256)
|
||||||
|
local ph = (port - pl)/256
|
||||||
|
local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",")
|
||||||
|
self.try(self.tp:command("port", arg))
|
||||||
|
self.try(self.tp:check("2.."))
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:send(sendt)
|
||||||
|
self.try(self.pasvt or self.server, "need port or pasv first")
|
||||||
|
-- if there is a pasvt table, we already sent a PASV command
|
||||||
|
-- we just get the data connection into self.data
|
||||||
|
if self.pasvt then self:pasvconnect() end
|
||||||
|
-- get the transfer argument and command
|
||||||
|
local argument = sendt.argument or
|
||||||
|
url.unescape(string.gsub(sendt.path or "", "^[/\\]", ""))
|
||||||
|
if argument == "" then argument = nil end
|
||||||
|
local command = sendt.command or "stor"
|
||||||
|
-- send the transfer command and check the reply
|
||||||
|
self.try(self.tp:command(command, argument))
|
||||||
|
local code, reply = self.try(self.tp:check{"2..", "1.."})
|
||||||
|
-- if there is not a a pasvt table, then there is a server
|
||||||
|
-- and we already sent a PORT command
|
||||||
|
if not self.pasvt then self:portconnect() end
|
||||||
|
-- get the sink, source and step for the transfer
|
||||||
|
local step = sendt.step or ltn12.pump.step
|
||||||
|
local readt = {self.tp.c}
|
||||||
|
local checkstep = function(src, snk)
|
||||||
|
-- check status in control connection while downloading
|
||||||
|
local readyt = socket.select(readt, nil, 0)
|
||||||
|
if readyt[tp] then code = self.try(self.tp:check("2..")) end
|
||||||
|
return step(src, snk)
|
||||||
|
end
|
||||||
|
local sink = socket.sink("close-when-done", self.data)
|
||||||
|
-- transfer all data and check error
|
||||||
|
self.try(ltn12.pump.all(sendt.source, sink, checkstep))
|
||||||
|
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
|
||||||
|
-- done with data connection
|
||||||
|
self.data:close()
|
||||||
|
-- find out how many bytes were sent
|
||||||
|
local sent = socket.skip(1, self.data:getstats())
|
||||||
|
self.data = nil
|
||||||
|
return sent
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:receive(recvt)
|
||||||
|
self.try(self.pasvt or self.server, "need port or pasv first")
|
||||||
|
if self.pasvt then self:pasvconnect() end
|
||||||
|
local argument = recvt.argument or
|
||||||
|
url.unescape(string.gsub(recvt.path or "", "^[/\\]", ""))
|
||||||
|
if argument == "" then argument = nil end
|
||||||
|
local command = recvt.command or "retr"
|
||||||
|
self.try(self.tp:command(command, argument))
|
||||||
|
local code,reply = self.try(self.tp:check{"1..", "2.."})
|
||||||
|
if (code >= 200) and (code <= 299) then
|
||||||
|
recvt.sink(reply)
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
if not self.pasvt then self:portconnect() end
|
||||||
|
local source = socket.source("until-closed", self.data)
|
||||||
|
local step = recvt.step or ltn12.pump.step
|
||||||
|
self.try(ltn12.pump.all(source, recvt.sink, step))
|
||||||
|
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
|
||||||
|
self.data:close()
|
||||||
|
self.data = nil
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:cwd(dir)
|
||||||
|
self.try(self.tp:command("cwd", dir))
|
||||||
|
self.try(self.tp:check(250))
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:type(type)
|
||||||
|
self.try(self.tp:command("type", type))
|
||||||
|
self.try(self.tp:check(200))
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:greet()
|
||||||
|
local code = self.try(self.tp:check{"1..", "2.."})
|
||||||
|
if string.find(code, "1..") then self.try(self.tp:check("2..")) end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:quit()
|
||||||
|
self.try(self.tp:command("quit"))
|
||||||
|
self.try(self.tp:check("2.."))
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:close()
|
||||||
|
if self.data then self.data:close() end
|
||||||
|
if self.server then self.server:close() end
|
||||||
|
return self.tp:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- High level FTP API
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local function override(t)
|
||||||
|
if t.url then
|
||||||
|
local u = url.parse(t.url)
|
||||||
|
for i,v in base.pairs(t) do
|
||||||
|
u[i] = v
|
||||||
|
end
|
||||||
|
return u
|
||||||
|
else return t end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tput(putt)
|
||||||
|
putt = override(putt)
|
||||||
|
socket.try(putt.host, "missing hostname")
|
||||||
|
local f = _M.open(putt.host, putt.port, putt.create)
|
||||||
|
f:greet()
|
||||||
|
f:login(putt.user, putt.password)
|
||||||
|
if putt.type then f:type(putt.type) end
|
||||||
|
f:pasv()
|
||||||
|
local sent = f:send(putt)
|
||||||
|
f:quit()
|
||||||
|
f:close()
|
||||||
|
return sent
|
||||||
|
end
|
||||||
|
|
||||||
|
local default = {
|
||||||
|
path = "/",
|
||||||
|
scheme = "ftp"
|
||||||
|
}
|
||||||
|
|
||||||
|
local function parse(u)
|
||||||
|
local t = socket.try(url.parse(u, default))
|
||||||
|
socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'")
|
||||||
|
socket.try(t.host, "missing hostname")
|
||||||
|
local pat = "^type=(.)$"
|
||||||
|
if t.params then
|
||||||
|
t.type = socket.skip(2, string.find(t.params, pat))
|
||||||
|
socket.try(t.type == "a" or t.type == "i",
|
||||||
|
"invalid type '" .. t.type .. "'")
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
local function sput(u, body)
|
||||||
|
local putt = parse(u)
|
||||||
|
putt.source = ltn12.source.string(body)
|
||||||
|
return tput(putt)
|
||||||
|
end
|
||||||
|
|
||||||
|
_M.put = socket.protect(function(putt, body)
|
||||||
|
if base.type(putt) == "string" then return sput(putt, body)
|
||||||
|
else return tput(putt) end
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function tget(gett)
|
||||||
|
gett = override(gett)
|
||||||
|
socket.try(gett.host, "missing hostname")
|
||||||
|
local f = _M.open(gett.host, gett.port, gett.create)
|
||||||
|
f:greet()
|
||||||
|
f:login(gett.user, gett.password)
|
||||||
|
if gett.type then f:type(gett.type) end
|
||||||
|
f:pasv()
|
||||||
|
f:receive(gett)
|
||||||
|
f:quit()
|
||||||
|
return f:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function sget(u)
|
||||||
|
local gett = parse(u)
|
||||||
|
local t = {}
|
||||||
|
gett.sink = ltn12.sink.table(t)
|
||||||
|
tget(gett)
|
||||||
|
return table.concat(t)
|
||||||
|
end
|
||||||
|
|
||||||
|
_M.command = socket.protect(function(cmdt)
|
||||||
|
cmdt = override(cmdt)
|
||||||
|
socket.try(cmdt.host, "missing hostname")
|
||||||
|
socket.try(cmdt.command, "missing command")
|
||||||
|
local f = open(cmdt.host, cmdt.port, cmdt.create)
|
||||||
|
f:greet()
|
||||||
|
f:login(cmdt.user, cmdt.password)
|
||||||
|
f.try(f.tp:command(cmdt.command, cmdt.argument))
|
||||||
|
if cmdt.check then f.try(f.tp:check(cmdt.check)) end
|
||||||
|
f:quit()
|
||||||
|
return f:close()
|
||||||
|
end)
|
||||||
|
|
||||||
|
_M.get = socket.protect(function(gett)
|
||||||
|
if base.type(gett) == "string" then return sget(gett)
|
||||||
|
else return tget(gett) end
|
||||||
|
end)
|
||||||
|
|
||||||
|
return _M
|
104
Me_Lua/h10/socket/headers.lua
Normal file
104
Me_Lua/h10/socket/headers.lua
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Canonic header field capitalization
|
||||||
|
-- LuaSocket toolkit.
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local socket = require("socket")
|
||||||
|
socket.headers = {}
|
||||||
|
local _M = socket.headers
|
||||||
|
|
||||||
|
_M.canonic = {
|
||||||
|
["accept"] = "Accept",
|
||||||
|
["accept-charset"] = "Accept-Charset",
|
||||||
|
["accept-encoding"] = "Accept-Encoding",
|
||||||
|
["accept-language"] = "Accept-Language",
|
||||||
|
["accept-ranges"] = "Accept-Ranges",
|
||||||
|
["action"] = "Action",
|
||||||
|
["alternate-recipient"] = "Alternate-Recipient",
|
||||||
|
["age"] = "Age",
|
||||||
|
["allow"] = "Allow",
|
||||||
|
["arrival-date"] = "Arrival-Date",
|
||||||
|
["authorization"] = "Authorization",
|
||||||
|
["bcc"] = "Bcc",
|
||||||
|
["cache-control"] = "Cache-Control",
|
||||||
|
["cc"] = "Cc",
|
||||||
|
["comments"] = "Comments",
|
||||||
|
["connection"] = "Connection",
|
||||||
|
["content-description"] = "Content-Description",
|
||||||
|
["content-disposition"] = "Content-Disposition",
|
||||||
|
["content-encoding"] = "Content-Encoding",
|
||||||
|
["content-id"] = "Content-ID",
|
||||||
|
["content-language"] = "Content-Language",
|
||||||
|
["content-length"] = "Content-Length",
|
||||||
|
["content-location"] = "Content-Location",
|
||||||
|
["content-md5"] = "Content-MD5",
|
||||||
|
["content-range"] = "Content-Range",
|
||||||
|
["content-transfer-encoding"] = "Content-Transfer-Encoding",
|
||||||
|
["content-type"] = "Content-Type",
|
||||||
|
["cookie"] = "Cookie",
|
||||||
|
["date"] = "Date",
|
||||||
|
["diagnostic-code"] = "Diagnostic-Code",
|
||||||
|
["dsn-gateway"] = "DSN-Gateway",
|
||||||
|
["etag"] = "ETag",
|
||||||
|
["expect"] = "Expect",
|
||||||
|
["expires"] = "Expires",
|
||||||
|
["final-log-id"] = "Final-Log-ID",
|
||||||
|
["final-recipient"] = "Final-Recipient",
|
||||||
|
["from"] = "From",
|
||||||
|
["host"] = "Host",
|
||||||
|
["if-match"] = "If-Match",
|
||||||
|
["if-modified-since"] = "If-Modified-Since",
|
||||||
|
["if-none-match"] = "If-None-Match",
|
||||||
|
["if-range"] = "If-Range",
|
||||||
|
["if-unmodified-since"] = "If-Unmodified-Since",
|
||||||
|
["in-reply-to"] = "In-Reply-To",
|
||||||
|
["keywords"] = "Keywords",
|
||||||
|
["last-attempt-date"] = "Last-Attempt-Date",
|
||||||
|
["last-modified"] = "Last-Modified",
|
||||||
|
["location"] = "Location",
|
||||||
|
["max-forwards"] = "Max-Forwards",
|
||||||
|
["message-id"] = "Message-ID",
|
||||||
|
["mime-version"] = "MIME-Version",
|
||||||
|
["original-envelope-id"] = "Original-Envelope-ID",
|
||||||
|
["original-recipient"] = "Original-Recipient",
|
||||||
|
["pragma"] = "Pragma",
|
||||||
|
["proxy-authenticate"] = "Proxy-Authenticate",
|
||||||
|
["proxy-authorization"] = "Proxy-Authorization",
|
||||||
|
["range"] = "Range",
|
||||||
|
["received"] = "Received",
|
||||||
|
["received-from-mta"] = "Received-From-MTA",
|
||||||
|
["references"] = "References",
|
||||||
|
["referer"] = "Referer",
|
||||||
|
["remote-mta"] = "Remote-MTA",
|
||||||
|
["reply-to"] = "Reply-To",
|
||||||
|
["reporting-mta"] = "Reporting-MTA",
|
||||||
|
["resent-bcc"] = "Resent-Bcc",
|
||||||
|
["resent-cc"] = "Resent-Cc",
|
||||||
|
["resent-date"] = "Resent-Date",
|
||||||
|
["resent-from"] = "Resent-From",
|
||||||
|
["resent-message-id"] = "Resent-Message-ID",
|
||||||
|
["resent-reply-to"] = "Resent-Reply-To",
|
||||||
|
["resent-sender"] = "Resent-Sender",
|
||||||
|
["resent-to"] = "Resent-To",
|
||||||
|
["retry-after"] = "Retry-After",
|
||||||
|
["return-path"] = "Return-Path",
|
||||||
|
["sender"] = "Sender",
|
||||||
|
["server"] = "Server",
|
||||||
|
["smtp-remote-recipient"] = "SMTP-Remote-Recipient",
|
||||||
|
["status"] = "Status",
|
||||||
|
["subject"] = "Subject",
|
||||||
|
["te"] = "TE",
|
||||||
|
["to"] = "To",
|
||||||
|
["trailer"] = "Trailer",
|
||||||
|
["transfer-encoding"] = "Transfer-Encoding",
|
||||||
|
["upgrade"] = "Upgrade",
|
||||||
|
["user-agent"] = "User-Agent",
|
||||||
|
["vary"] = "Vary",
|
||||||
|
["via"] = "Via",
|
||||||
|
["warning"] = "Warning",
|
||||||
|
["will-retry-until"] = "Will-Retry-Until",
|
||||||
|
["www-authenticate"] = "WWW-Authenticate",
|
||||||
|
["x-mailer"] = "X-Mailer",
|
||||||
|
}
|
||||||
|
|
||||||
|
return _M
|
356
Me_Lua/h10/socket/http.lua
Normal file
356
Me_Lua/h10/socket/http.lua
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- HTTP/1.1 client support for the Lua language.
|
||||||
|
-- LuaSocket toolkit.
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Declare module and import dependencies
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
local socket = require("socket")
|
||||||
|
local url = require("socket.url")
|
||||||
|
local ltn12 = require("ltn12")
|
||||||
|
local mime = require("mime")
|
||||||
|
local string = require("string")
|
||||||
|
local headers = require("socket.headers")
|
||||||
|
local base = _G
|
||||||
|
local table = require("table")
|
||||||
|
socket.http = {}
|
||||||
|
local _M = socket.http
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Program constants
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- connection timeout in seconds
|
||||||
|
_M.TIMEOUT = 60
|
||||||
|
-- default port for document retrieval
|
||||||
|
_M.PORT = 80
|
||||||
|
-- user agent field sent in request
|
||||||
|
_M.USERAGENT = socket._VERSION
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Reads MIME headers from a connection, unfolding where needed
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local function receiveheaders(sock, headers)
|
||||||
|
local line, name, value, err
|
||||||
|
headers = headers or {}
|
||||||
|
-- get first line
|
||||||
|
line, err = sock:receive()
|
||||||
|
if err then return nil, err end
|
||||||
|
-- headers go until a blank line is found
|
||||||
|
while line ~= "" do
|
||||||
|
-- get field-name and value
|
||||||
|
name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)"))
|
||||||
|
if not (name and value) then return nil, "malformed reponse headers" end
|
||||||
|
name = string.lower(name)
|
||||||
|
-- get next line (value might be folded)
|
||||||
|
line, err = sock:receive()
|
||||||
|
if err then return nil, err end
|
||||||
|
-- unfold any folded values
|
||||||
|
while string.find(line, "^%s") do
|
||||||
|
value = value .. line
|
||||||
|
line = sock:receive()
|
||||||
|
if err then return nil, err end
|
||||||
|
end
|
||||||
|
-- save pair in table
|
||||||
|
if headers[name] then headers[name] = headers[name] .. ", " .. value
|
||||||
|
else headers[name] = value end
|
||||||
|
end
|
||||||
|
return headers
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Extra sources and sinks
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
socket.sourcet["http-chunked"] = function(sock, headers)
|
||||||
|
return base.setmetatable({
|
||||||
|
getfd = function() return sock:getfd() end,
|
||||||
|
dirty = function() return sock:dirty() end
|
||||||
|
}, {
|
||||||
|
__call = function()
|
||||||
|
-- get chunk size, skip extention
|
||||||
|
local line, err = sock:receive()
|
||||||
|
if err then return nil, err end
|
||||||
|
local size = base.tonumber(string.gsub(line, ";.*", ""), 16)
|
||||||
|
if not size then return nil, "invalid chunk size" end
|
||||||
|
-- was it the last chunk?
|
||||||
|
if size > 0 then
|
||||||
|
-- if not, get chunk and skip terminating CRLF
|
||||||
|
local chunk, err, part = sock:receive(size)
|
||||||
|
if chunk then sock:receive() end
|
||||||
|
return chunk, err
|
||||||
|
else
|
||||||
|
-- if it was, read trailers into headers table
|
||||||
|
headers, err = receiveheaders(sock, headers)
|
||||||
|
if not headers then return nil, err end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
socket.sinkt["http-chunked"] = function(sock)
|
||||||
|
return base.setmetatable({
|
||||||
|
getfd = function() return sock:getfd() end,
|
||||||
|
dirty = function() return sock:dirty() end
|
||||||
|
}, {
|
||||||
|
__call = function(self, chunk, err)
|
||||||
|
if not chunk then return sock:send("0\r\n\r\n") end
|
||||||
|
local size = string.format("%X\r\n", string.len(chunk))
|
||||||
|
return sock:send(size .. chunk .. "\r\n")
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Low level HTTP API
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local metat = { __index = {} }
|
||||||
|
|
||||||
|
function _M.open(host, port, create)
|
||||||
|
-- create socket with user connect function, or with default
|
||||||
|
local c = socket.try((create or socket.tcp)())
|
||||||
|
local h = base.setmetatable({ c = c }, metat)
|
||||||
|
-- create finalized try
|
||||||
|
h.try = socket.newtry(function() h:close() end)
|
||||||
|
-- set timeout before connecting
|
||||||
|
h.try(c:settimeout(_M.TIMEOUT))
|
||||||
|
h.try(c:connect(host, port or _M.PORT))
|
||||||
|
-- here everything worked
|
||||||
|
return h
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:sendrequestline(method, uri)
|
||||||
|
local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri)
|
||||||
|
return self.try(self.c:send(reqline))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:sendheaders(tosend)
|
||||||
|
local canonic = headers.canonic
|
||||||
|
local h = "\r\n"
|
||||||
|
for f, v in base.pairs(tosend) do
|
||||||
|
h = (canonic[f] or f) .. ": " .. v .. "\r\n" .. h
|
||||||
|
end
|
||||||
|
self.try(self.c:send(h))
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:sendbody(headers, source, step)
|
||||||
|
source = source or ltn12.source.empty()
|
||||||
|
step = step or ltn12.pump.step
|
||||||
|
-- if we don't know the size in advance, send chunked and hope for the best
|
||||||
|
local mode = "http-chunked"
|
||||||
|
if headers["content-length"] then mode = "keep-open" end
|
||||||
|
return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:receivestatusline()
|
||||||
|
local status = self.try(self.c:receive(5))
|
||||||
|
-- identify HTTP/0.9 responses, which do not contain a status line
|
||||||
|
-- this is just a heuristic, but is what the RFC recommends
|
||||||
|
if status ~= "HTTP/" then return nil, status end
|
||||||
|
-- otherwise proceed reading a status line
|
||||||
|
status = self.try(self.c:receive("*l", status))
|
||||||
|
local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
|
||||||
|
return self.try(base.tonumber(code), status)
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:receiveheaders()
|
||||||
|
return self.try(receiveheaders(self.c))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:receivebody(headers, sink, step)
|
||||||
|
sink = sink or ltn12.sink.null()
|
||||||
|
step = step or ltn12.pump.step
|
||||||
|
local length = base.tonumber(headers["content-length"])
|
||||||
|
local t = headers["transfer-encoding"] -- shortcut
|
||||||
|
local mode = "default" -- connection close
|
||||||
|
if t and t ~= "identity" then mode = "http-chunked"
|
||||||
|
elseif base.tonumber(headers["content-length"]) then mode = "by-length" end
|
||||||
|
return self.try(ltn12.pump.all(socket.source(mode, self.c, length),
|
||||||
|
sink, step))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:receive09body(status, sink, step)
|
||||||
|
local source = ltn12.source.rewind(socket.source("until-closed", self.c))
|
||||||
|
source(status)
|
||||||
|
return self.try(ltn12.pump.all(source, sink, step))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:close()
|
||||||
|
return self.c:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- High level HTTP API
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local function adjusturi(reqt)
|
||||||
|
local u = reqt
|
||||||
|
-- if there is a proxy, we need the full url. otherwise, just a part.
|
||||||
|
if not reqt.proxy and not _M.PROXY then
|
||||||
|
u = {
|
||||||
|
path = socket.try(reqt.path, "invalid path 'nil'"),
|
||||||
|
params = reqt.params,
|
||||||
|
query = reqt.query,
|
||||||
|
fragment = reqt.fragment
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return url.build(u)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function adjustproxy(reqt)
|
||||||
|
local proxy = reqt.proxy or _M.PROXY
|
||||||
|
if proxy then
|
||||||
|
proxy = url.parse(proxy)
|
||||||
|
return proxy.host, proxy.port or 3128
|
||||||
|
else
|
||||||
|
return reqt.host, reqt.port
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function adjustheaders(reqt)
|
||||||
|
-- default headers
|
||||||
|
local host = reqt.host
|
||||||
|
if reqt.port then host = host .. ":" .. reqt.port end
|
||||||
|
local lower = {
|
||||||
|
["user-agent"] = _M.USERAGENT,
|
||||||
|
["host"] = host,
|
||||||
|
["connection"] = "close, TE",
|
||||||
|
["te"] = "trailers"
|
||||||
|
}
|
||||||
|
-- if we have authentication information, pass it along
|
||||||
|
if reqt.user and reqt.password then
|
||||||
|
lower["authorization"] =
|
||||||
|
"Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password))
|
||||||
|
end
|
||||||
|
-- override with user headers
|
||||||
|
for i,v in base.pairs(reqt.headers or lower) do
|
||||||
|
lower[string.lower(i)] = v
|
||||||
|
end
|
||||||
|
return lower
|
||||||
|
end
|
||||||
|
|
||||||
|
-- default url parts
|
||||||
|
local default = {
|
||||||
|
host = "",
|
||||||
|
port = _M.PORT,
|
||||||
|
path ="/",
|
||||||
|
scheme = "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
local function adjustrequest(reqt)
|
||||||
|
-- parse url if provided
|
||||||
|
local nreqt = reqt.url and url.parse(reqt.url, default) or {}
|
||||||
|
-- explicit components override url
|
||||||
|
for i,v in base.pairs(reqt) do nreqt[i] = v end
|
||||||
|
if nreqt.port == "" then nreqt.port = 80 end
|
||||||
|
socket.try(nreqt.host and nreqt.host ~= "",
|
||||||
|
"invalid host '" .. base.tostring(nreqt.host) .. "'")
|
||||||
|
-- compute uri if user hasn't overriden
|
||||||
|
nreqt.uri = reqt.uri or adjusturi(nreqt)
|
||||||
|
-- ajust host and port if there is a proxy
|
||||||
|
nreqt.host, nreqt.port = adjustproxy(nreqt)
|
||||||
|
-- adjust headers in request
|
||||||
|
nreqt.headers = adjustheaders(nreqt)
|
||||||
|
return nreqt
|
||||||
|
end
|
||||||
|
|
||||||
|
local function shouldredirect(reqt, code, headers)
|
||||||
|
return headers.location and
|
||||||
|
string.gsub(headers.location, "%s", "") ~= "" and
|
||||||
|
(reqt.redirect ~= false) and
|
||||||
|
(code == 301 or code == 302 or code == 303 or code == 307) and
|
||||||
|
(not reqt.method or reqt.method == "GET" or reqt.method == "HEAD")
|
||||||
|
and (not reqt.nredirects or reqt.nredirects < 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function shouldreceivebody(reqt, code)
|
||||||
|
if reqt.method == "HEAD" then return nil end
|
||||||
|
if code == 204 or code == 304 then return nil end
|
||||||
|
if code >= 100 and code < 200 then return nil end
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- forward declarations
|
||||||
|
local trequest, tredirect
|
||||||
|
|
||||||
|
--[[local]] function tredirect(reqt, location)
|
||||||
|
local result, code, headers, status = trequest {
|
||||||
|
-- the RFC says the redirect URL has to be absolute, but some
|
||||||
|
-- servers do not respect that
|
||||||
|
url = url.absolute(reqt.url, location),
|
||||||
|
source = reqt.source,
|
||||||
|
sink = reqt.sink,
|
||||||
|
headers = reqt.headers,
|
||||||
|
proxy = reqt.proxy,
|
||||||
|
nredirects = (reqt.nredirects or 0) + 1,
|
||||||
|
create = reqt.create
|
||||||
|
}
|
||||||
|
-- pass location header back as a hint we redirected
|
||||||
|
headers = headers or {}
|
||||||
|
headers.location = headers.location or location
|
||||||
|
return result, code, headers, status
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[local]] function trequest(reqt)
|
||||||
|
-- we loop until we get what we want, or
|
||||||
|
-- until we are sure there is no way to get it
|
||||||
|
local nreqt = adjustrequest(reqt)
|
||||||
|
local h = _M.open(nreqt.host, nreqt.port, nreqt.create)
|
||||||
|
-- send request line and headers
|
||||||
|
h:sendrequestline(nreqt.method, nreqt.uri)
|
||||||
|
h:sendheaders(nreqt.headers)
|
||||||
|
-- if there is a body, send it
|
||||||
|
if nreqt.source then
|
||||||
|
h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
|
||||||
|
end
|
||||||
|
local code, status = h:receivestatusline()
|
||||||
|
-- if it is an HTTP/0.9 server, simply get the body and we are done
|
||||||
|
if not code then
|
||||||
|
h:receive09body(status, nreqt.sink, nreqt.step)
|
||||||
|
return 1, 200
|
||||||
|
end
|
||||||
|
local headers
|
||||||
|
-- ignore any 100-continue messages
|
||||||
|
while code == 100 do
|
||||||
|
headers = h:receiveheaders()
|
||||||
|
code, status = h:receivestatusline()
|
||||||
|
end
|
||||||
|
headers = h:receiveheaders()
|
||||||
|
-- at this point we should have a honest reply from the server
|
||||||
|
-- we can't redirect if we already used the source, so we report the error
|
||||||
|
if shouldredirect(nreqt, code, headers) and not nreqt.source then
|
||||||
|
h:close()
|
||||||
|
return tredirect(reqt, headers.location)
|
||||||
|
end
|
||||||
|
-- here we are finally done
|
||||||
|
if shouldreceivebody(nreqt, code) then
|
||||||
|
h:receivebody(headers, nreqt.sink, nreqt.step)
|
||||||
|
end
|
||||||
|
h:close()
|
||||||
|
return 1, code, headers, status
|
||||||
|
end
|
||||||
|
|
||||||
|
local function srequest(u, b)
|
||||||
|
local t = {}
|
||||||
|
local reqt = {
|
||||||
|
url = u,
|
||||||
|
sink = ltn12.sink.table(t)
|
||||||
|
}
|
||||||
|
if b then
|
||||||
|
reqt.source = ltn12.source.string(b)
|
||||||
|
reqt.headers = {
|
||||||
|
["content-length"] = string.len(b),
|
||||||
|
["content-type"] = "application/x-www-form-urlencoded"
|
||||||
|
}
|
||||||
|
reqt.method = "POST"
|
||||||
|
end
|
||||||
|
local code, headers, status = socket.skip(1, trequest(reqt))
|
||||||
|
return table.concat(t), code, headers, status
|
||||||
|
end
|
||||||
|
|
||||||
|
_M.request = socket.protect(function(reqt, body)
|
||||||
|
if base.type(reqt) == "string" then return srequest(reqt, body)
|
||||||
|
else return trequest(reqt) end
|
||||||
|
end)
|
||||||
|
|
||||||
|
return _M
|
256
Me_Lua/h10/socket/smtp.lua
Normal file
256
Me_Lua/h10/socket/smtp.lua
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- SMTP client support for the Lua language.
|
||||||
|
-- LuaSocket toolkit.
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Declare module and import dependencies
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local base = _G
|
||||||
|
local coroutine = require("coroutine")
|
||||||
|
local string = require("string")
|
||||||
|
local math = require("math")
|
||||||
|
local os = require("os")
|
||||||
|
local socket = require("socket")
|
||||||
|
local tp = require("socket.tp")
|
||||||
|
local ltn12 = require("ltn12")
|
||||||
|
local headers = require("socket.headers")
|
||||||
|
local mime = require("mime")
|
||||||
|
|
||||||
|
socket.smtp = {}
|
||||||
|
local _M = socket.smtp
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Program constants
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- timeout for connection
|
||||||
|
_M.TIMEOUT = 60
|
||||||
|
-- default server used to send e-mails
|
||||||
|
_M.SERVER = "localhost"
|
||||||
|
-- default port
|
||||||
|
_M.PORT = 25
|
||||||
|
-- domain used in HELO command and default sendmail
|
||||||
|
-- If we are under a CGI, try to get from environment
|
||||||
|
_M.DOMAIN = os.getenv("SERVER_NAME") or "localhost"
|
||||||
|
-- default time zone (means we don't know)
|
||||||
|
_M.ZONE = "-0000"
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- Low level SMTP API
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local metat = { __index = {} }
|
||||||
|
|
||||||
|
function metat.__index:greet(domain)
|
||||||
|
self.try(self.tp:check("2.."))
|
||||||
|
self.try(self.tp:command("EHLO", domain or _M.DOMAIN))
|
||||||
|
return socket.skip(1, self.try(self.tp:check("2..")))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:mail(from)
|
||||||
|
self.try(self.tp:command("MAIL", "FROM:" .. from))
|
||||||
|
return self.try(self.tp:check("2.."))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:rcpt(to)
|
||||||
|
self.try(self.tp:command("RCPT", "TO:" .. to))
|
||||||
|
return self.try(self.tp:check("2.."))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:data(src, step)
|
||||||
|
self.try(self.tp:command("DATA"))
|
||||||
|
self.try(self.tp:check("3.."))
|
||||||
|
self.try(self.tp:source(src, step))
|
||||||
|
self.try(self.tp:send("\r\n.\r\n"))
|
||||||
|
return self.try(self.tp:check("2.."))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:quit()
|
||||||
|
self.try(self.tp:command("QUIT"))
|
||||||
|
return self.try(self.tp:check("2.."))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:close()
|
||||||
|
return self.tp:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:login(user, password)
|
||||||
|
self.try(self.tp:command("AUTH", "LOGIN"))
|
||||||
|
self.try(self.tp:check("3.."))
|
||||||
|
self.try(self.tp:send(mime.b64(user) .. "\r\n"))
|
||||||
|
self.try(self.tp:check("3.."))
|
||||||
|
self.try(self.tp:send(mime.b64(password) .. "\r\n"))
|
||||||
|
return self.try(self.tp:check("2.."))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:plain(user, password)
|
||||||
|
local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password)
|
||||||
|
self.try(self.tp:command("AUTH", auth))
|
||||||
|
return self.try(self.tp:check("2.."))
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:auth(user, password, ext)
|
||||||
|
if not user or not password then return 1 end
|
||||||
|
if string.find(ext, "AUTH[^\n]+LOGIN") then
|
||||||
|
return self:login(user, password)
|
||||||
|
elseif string.find(ext, "AUTH[^\n]+PLAIN") then
|
||||||
|
return self:plain(user, password)
|
||||||
|
else
|
||||||
|
self.try(nil, "authentication not supported")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- send message or throw an exception
|
||||||
|
function metat.__index:send(mailt)
|
||||||
|
self:mail(mailt.from)
|
||||||
|
if base.type(mailt.rcpt) == "table" then
|
||||||
|
for i,v in base.ipairs(mailt.rcpt) do
|
||||||
|
self:rcpt(v)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:rcpt(mailt.rcpt)
|
||||||
|
end
|
||||||
|
self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step)
|
||||||
|
end
|
||||||
|
|
||||||
|
function _M.open(server, port, create)
|
||||||
|
local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT,
|
||||||
|
_M.TIMEOUT, create))
|
||||||
|
local s = base.setmetatable({tp = tp}, metat)
|
||||||
|
-- make sure tp is closed if we get an exception
|
||||||
|
s.try = socket.newtry(function()
|
||||||
|
s:close()
|
||||||
|
end)
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
-- convert headers to lowercase
|
||||||
|
local function lower_headers(headers)
|
||||||
|
local lower = {}
|
||||||
|
for i,v in base.pairs(headers or lower) do
|
||||||
|
lower[string.lower(i)] = v
|
||||||
|
end
|
||||||
|
return lower
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- Multipart message source
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- returns a hopefully unique mime boundary
|
||||||
|
local seqno = 0
|
||||||
|
local function newboundary()
|
||||||
|
seqno = seqno + 1
|
||||||
|
return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'),
|
||||||
|
math.random(0, 99999), seqno)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- send_message forward declaration
|
||||||
|
local send_message
|
||||||
|
|
||||||
|
-- yield the headers all at once, it's faster
|
||||||
|
local function send_headers(tosend)
|
||||||
|
local canonic = headers.canonic
|
||||||
|
local h = "\r\n"
|
||||||
|
for f,v in base.pairs(tosend) do
|
||||||
|
h = (canonic[f] or f) .. ': ' .. v .. "\r\n" .. h
|
||||||
|
end
|
||||||
|
coroutine.yield(h)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- yield multipart message body from a multipart message table
|
||||||
|
local function send_multipart(mesgt)
|
||||||
|
-- make sure we have our boundary and send headers
|
||||||
|
local bd = newboundary()
|
||||||
|
local headers = lower_headers(mesgt.headers or {})
|
||||||
|
headers['content-type'] = headers['content-type'] or 'multipart/mixed'
|
||||||
|
headers['content-type'] = headers['content-type'] ..
|
||||||
|
'; boundary="' .. bd .. '"'
|
||||||
|
send_headers(headers)
|
||||||
|
-- send preamble
|
||||||
|
if mesgt.body.preamble then
|
||||||
|
coroutine.yield(mesgt.body.preamble)
|
||||||
|
coroutine.yield("\r\n")
|
||||||
|
end
|
||||||
|
-- send each part separated by a boundary
|
||||||
|
for i, m in base.ipairs(mesgt.body) do
|
||||||
|
coroutine.yield("\r\n--" .. bd .. "\r\n")
|
||||||
|
send_message(m)
|
||||||
|
end
|
||||||
|
-- send last boundary
|
||||||
|
coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n")
|
||||||
|
-- send epilogue
|
||||||
|
if mesgt.body.epilogue then
|
||||||
|
coroutine.yield(mesgt.body.epilogue)
|
||||||
|
coroutine.yield("\r\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- yield message body from a source
|
||||||
|
local function send_source(mesgt)
|
||||||
|
-- make sure we have a content-type
|
||||||
|
local headers = lower_headers(mesgt.headers or {})
|
||||||
|
headers['content-type'] = headers['content-type'] or
|
||||||
|
'text/plain; charset="iso-8859-1"'
|
||||||
|
send_headers(headers)
|
||||||
|
-- send body from source
|
||||||
|
while true do
|
||||||
|
local chunk, err = mesgt.body()
|
||||||
|
if err then coroutine.yield(nil, err)
|
||||||
|
elseif chunk then coroutine.yield(chunk)
|
||||||
|
else break end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- yield message body from a string
|
||||||
|
local function send_string(mesgt)
|
||||||
|
-- make sure we have a content-type
|
||||||
|
local headers = lower_headers(mesgt.headers or {})
|
||||||
|
headers['content-type'] = headers['content-type'] or
|
||||||
|
'text/plain; charset="iso-8859-1"'
|
||||||
|
send_headers(headers)
|
||||||
|
-- send body from string
|
||||||
|
coroutine.yield(mesgt.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- message source
|
||||||
|
function send_message(mesgt)
|
||||||
|
if base.type(mesgt.body) == "table" then send_multipart(mesgt)
|
||||||
|
elseif base.type(mesgt.body) == "function" then send_source(mesgt)
|
||||||
|
else send_string(mesgt) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set defaul headers
|
||||||
|
local function adjust_headers(mesgt)
|
||||||
|
local lower = lower_headers(mesgt.headers)
|
||||||
|
lower["date"] = lower["date"] or
|
||||||
|
os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or _M.ZONE)
|
||||||
|
lower["x-mailer"] = lower["x-mailer"] or socket._VERSION
|
||||||
|
-- this can't be overriden
|
||||||
|
lower["mime-version"] = "1.0"
|
||||||
|
return lower
|
||||||
|
end
|
||||||
|
|
||||||
|
function _M.message(mesgt)
|
||||||
|
mesgt.headers = adjust_headers(mesgt)
|
||||||
|
-- create and return message source
|
||||||
|
local co = coroutine.create(function() send_message(mesgt) end)
|
||||||
|
return function()
|
||||||
|
local ret, a, b = coroutine.resume(co)
|
||||||
|
if ret then return a, b
|
||||||
|
else return nil, a end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
-- High level SMTP API
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
_M.send = socket.protect(function(mailt)
|
||||||
|
local s = _M.open(mailt.server, mailt.port, mailt.create)
|
||||||
|
local ext = s:greet(mailt.domain)
|
||||||
|
s:auth(mailt.user, mailt.password, ext)
|
||||||
|
s:send(mailt)
|
||||||
|
s:quit()
|
||||||
|
return s:close()
|
||||||
|
end)
|
||||||
|
|
||||||
|
return _M
|
126
Me_Lua/h10/socket/tp.lua
Normal file
126
Me_Lua/h10/socket/tp.lua
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Unified SMTP/FTP subsystem
|
||||||
|
-- LuaSocket toolkit.
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Declare module and import dependencies
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local base = _G
|
||||||
|
local string = require("string")
|
||||||
|
local socket = require("socket")
|
||||||
|
local ltn12 = require("ltn12")
|
||||||
|
|
||||||
|
socket.tp = {}
|
||||||
|
local _M = socket.tp
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Program constants
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
_M.TIMEOUT = 60
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Implementation
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- gets server reply (works for SMTP and FTP)
|
||||||
|
local function get_reply(c)
|
||||||
|
local code, current, sep
|
||||||
|
local line, err = c:receive()
|
||||||
|
local reply = line
|
||||||
|
if err then return nil, err end
|
||||||
|
code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
|
||||||
|
if not code then return nil, "invalid server reply" end
|
||||||
|
if sep == "-" then -- reply is multiline
|
||||||
|
repeat
|
||||||
|
line, err = c:receive()
|
||||||
|
if err then return nil, err end
|
||||||
|
current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
|
||||||
|
reply = reply .. "\n" .. line
|
||||||
|
-- reply ends with same code
|
||||||
|
until code == current and sep == " "
|
||||||
|
end
|
||||||
|
return code, reply
|
||||||
|
end
|
||||||
|
|
||||||
|
-- metatable for sock object
|
||||||
|
local metat = { __index = {} }
|
||||||
|
|
||||||
|
function metat.__index:check(ok)
|
||||||
|
local code, reply = get_reply(self.c)
|
||||||
|
if not code then return nil, reply end
|
||||||
|
if base.type(ok) ~= "function" then
|
||||||
|
if base.type(ok) == "table" then
|
||||||
|
for i, v in base.ipairs(ok) do
|
||||||
|
if string.find(code, v) then
|
||||||
|
return base.tonumber(code), reply
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil, reply
|
||||||
|
else
|
||||||
|
if string.find(code, ok) then return base.tonumber(code), reply
|
||||||
|
else return nil, reply end
|
||||||
|
end
|
||||||
|
else return ok(base.tonumber(code), reply) end
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:command(cmd, arg)
|
||||||
|
cmd = string.upper(cmd)
|
||||||
|
if arg then
|
||||||
|
return self.c:send(cmd .. " " .. arg.. "\r\n")
|
||||||
|
else
|
||||||
|
return self.c:send(cmd .. "\r\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:sink(snk, pat)
|
||||||
|
local chunk, err = c:receive(pat)
|
||||||
|
return snk(chunk, err)
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:send(data)
|
||||||
|
return self.c:send(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:receive(pat)
|
||||||
|
return self.c:receive(pat)
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:getfd()
|
||||||
|
return self.c:getfd()
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:dirty()
|
||||||
|
return self.c:dirty()
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:getcontrol()
|
||||||
|
return self.c
|
||||||
|
end
|
||||||
|
|
||||||
|
function metat.__index:source(source, step)
|
||||||
|
local sink = socket.sink("keep-open", self.c)
|
||||||
|
local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step)
|
||||||
|
return ret, err
|
||||||
|
end
|
||||||
|
|
||||||
|
-- closes the underlying c
|
||||||
|
function metat.__index:close()
|
||||||
|
self.c:close()
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- connect with server and return c object
|
||||||
|
function _M.connect(host, port, timeout, create)
|
||||||
|
local c, e = (create or socket.tcp)()
|
||||||
|
if not c then return nil, e end
|
||||||
|
c:settimeout(timeout or _M.TIMEOUT)
|
||||||
|
local r, e = c:connect(host, port)
|
||||||
|
if not r then
|
||||||
|
c:close()
|
||||||
|
return nil, e
|
||||||
|
end
|
||||||
|
return base.setmetatable({c = c}, metat)
|
||||||
|
end
|
||||||
|
|
||||||
|
return _M
|
307
Me_Lua/h10/socket/url.lua
Normal file
307
Me_Lua/h10/socket/url.lua
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- URI parsing, composition and relative URL resolution
|
||||||
|
-- LuaSocket toolkit.
|
||||||
|
-- Author: Diego Nehab
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Declare module
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local string = require("string")
|
||||||
|
local base = _G
|
||||||
|
local table = require("table")
|
||||||
|
local socket = require("socket")
|
||||||
|
|
||||||
|
socket.url = {}
|
||||||
|
local _M = socket.url
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Module version
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
_M._VERSION = "URL 1.0.3"
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Encodes a string into its escaped hexadecimal representation
|
||||||
|
-- Input
|
||||||
|
-- s: binary string to be encoded
|
||||||
|
-- Returns
|
||||||
|
-- escaped representation of string binary
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
function _M.escape(s)
|
||||||
|
return (string.gsub(s, "([^A-Za-z0-9_])", function(c)
|
||||||
|
return string.format("%%%02x", string.byte(c))
|
||||||
|
end))
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Protects a path segment, to prevent it from interfering with the
|
||||||
|
-- url parsing.
|
||||||
|
-- Input
|
||||||
|
-- s: binary string to be encoded
|
||||||
|
-- Returns
|
||||||
|
-- escaped representation of string binary
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local function make_set(t)
|
||||||
|
local s = {}
|
||||||
|
for i,v in base.ipairs(t) do
|
||||||
|
s[t[i]] = 1
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
-- these are allowed withing a path segment, along with alphanum
|
||||||
|
-- other characters must be escaped
|
||||||
|
local segment_set = make_set {
|
||||||
|
"-", "_", ".", "!", "~", "*", "'", "(",
|
||||||
|
")", ":", "@", "&", "=", "+", "$", ",",
|
||||||
|
}
|
||||||
|
|
||||||
|
local function protect_segment(s)
|
||||||
|
return string.gsub(s, "([^A-Za-z0-9_])", function (c)
|
||||||
|
if segment_set[c] then return c
|
||||||
|
else return string.format("%%%02x", string.byte(c)) end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Encodes a string into its escaped hexadecimal representation
|
||||||
|
-- Input
|
||||||
|
-- s: binary string to be encoded
|
||||||
|
-- Returns
|
||||||
|
-- escaped representation of string binary
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
function _M.unescape(s)
|
||||||
|
return (string.gsub(s, "%%(%x%x)", function(hex)
|
||||||
|
return string.char(base.tonumber(hex, 16))
|
||||||
|
end))
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Builds a path from a base path and a relative path
|
||||||
|
-- Input
|
||||||
|
-- base_path
|
||||||
|
-- relative_path
|
||||||
|
-- Returns
|
||||||
|
-- corresponding absolute path
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
local function absolute_path(base_path, relative_path)
|
||||||
|
if string.sub(relative_path, 1, 1) == "/" then return relative_path end
|
||||||
|
local path = string.gsub(base_path, "[^/]*$", "")
|
||||||
|
path = path .. relative_path
|
||||||
|
path = string.gsub(path, "([^/]*%./)", function (s)
|
||||||
|
if s ~= "./" then return s else return "" end
|
||||||
|
end)
|
||||||
|
path = string.gsub(path, "/%.$", "/")
|
||||||
|
local reduced
|
||||||
|
while reduced ~= path do
|
||||||
|
reduced = path
|
||||||
|
path = string.gsub(reduced, "([^/]*/%.%./)", function (s)
|
||||||
|
if s ~= "../../" then return "" else return s end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
path = string.gsub(reduced, "([^/]*/%.%.)$", function (s)
|
||||||
|
if s ~= "../.." then return "" else return s end
|
||||||
|
end)
|
||||||
|
return path
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Parses a url and returns a table with all its parts according to RFC 2396
|
||||||
|
-- The following grammar describes the names given to the URL parts
|
||||||
|
-- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment>
|
||||||
|
-- <authority> ::= <userinfo>@<host>:<port>
|
||||||
|
-- <userinfo> ::= <user>[:<password>]
|
||||||
|
-- <path> :: = {<segment>/}<segment>
|
||||||
|
-- Input
|
||||||
|
-- url: uniform resource locator of request
|
||||||
|
-- default: table with default values for each field
|
||||||
|
-- Returns
|
||||||
|
-- table with the following fields, where RFC naming conventions have
|
||||||
|
-- been preserved:
|
||||||
|
-- scheme, authority, userinfo, user, password, host, port,
|
||||||
|
-- path, params, query, fragment
|
||||||
|
-- Obs:
|
||||||
|
-- the leading '/' in {/<path>} is considered part of <path>
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
function _M.parse(url, default)
|
||||||
|
-- initialize default parameters
|
||||||
|
local parsed = {}
|
||||||
|
for i,v in base.pairs(default or parsed) do parsed[i] = v end
|
||||||
|
-- empty url is parsed to nil
|
||||||
|
if not url or url == "" then return nil, "invalid url" end
|
||||||
|
-- remove whitespace
|
||||||
|
-- url = string.gsub(url, "%s", "")
|
||||||
|
-- get fragment
|
||||||
|
url = string.gsub(url, "#(.*)$", function(f)
|
||||||
|
parsed.fragment = f
|
||||||
|
return ""
|
||||||
|
end)
|
||||||
|
-- get scheme
|
||||||
|
url = string.gsub(url, "^([%w][%w%+%-%.]*)%:",
|
||||||
|
function(s) parsed.scheme = s; return "" end)
|
||||||
|
-- get authority
|
||||||
|
url = string.gsub(url, "^//([^/]*)", function(n)
|
||||||
|
parsed.authority = n
|
||||||
|
return ""
|
||||||
|
end)
|
||||||
|
-- get query string
|
||||||
|
url = string.gsub(url, "%?(.*)", function(q)
|
||||||
|
parsed.query = q
|
||||||
|
return ""
|
||||||
|
end)
|
||||||
|
-- get params
|
||||||
|
url = string.gsub(url, "%;(.*)", function(p)
|
||||||
|
parsed.params = p
|
||||||
|
return ""
|
||||||
|
end)
|
||||||
|
-- path is whatever was left
|
||||||
|
if url ~= "" then parsed.path = url end
|
||||||
|
local authority = parsed.authority
|
||||||
|
if not authority then return parsed end
|
||||||
|
authority = string.gsub(authority,"^([^@]*)@",
|
||||||
|
function(u) parsed.userinfo = u; return "" end)
|
||||||
|
authority = string.gsub(authority, ":([^:%]]*)$",
|
||||||
|
function(p) parsed.port = p; return "" end)
|
||||||
|
if authority ~= "" then
|
||||||
|
-- IPv6?
|
||||||
|
parsed.host = string.match(authority, "^%[(.+)%]$") or authority
|
||||||
|
end
|
||||||
|
local userinfo = parsed.userinfo
|
||||||
|
if not userinfo then return parsed end
|
||||||
|
userinfo = string.gsub(userinfo, ":([^:]*)$",
|
||||||
|
function(p) parsed.password = p; return "" end)
|
||||||
|
parsed.user = userinfo
|
||||||
|
return parsed
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Rebuilds a parsed URL from its components.
|
||||||
|
-- Components are protected if any reserved or unallowed characters are found
|
||||||
|
-- Input
|
||||||
|
-- parsed: parsed URL, as returned by parse
|
||||||
|
-- Returns
|
||||||
|
-- a stringing with the corresponding URL
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
function _M.build(parsed)
|
||||||
|
local ppath = _M.parse_path(parsed.path or "")
|
||||||
|
local url = _M.build_path(ppath)
|
||||||
|
if parsed.params then url = url .. ";" .. parsed.params end
|
||||||
|
if parsed.query then url = url .. "?" .. parsed.query end
|
||||||
|
local authority = parsed.authority
|
||||||
|
if parsed.host then
|
||||||
|
authority = parsed.host
|
||||||
|
if string.find(authority, ":") then -- IPv6?
|
||||||
|
authority = "[" .. authority .. "]"
|
||||||
|
end
|
||||||
|
if parsed.port then authority = authority .. ":" .. parsed.port end
|
||||||
|
local userinfo = parsed.userinfo
|
||||||
|
if parsed.user then
|
||||||
|
userinfo = parsed.user
|
||||||
|
if parsed.password then
|
||||||
|
userinfo = userinfo .. ":" .. parsed.password
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if userinfo then authority = userinfo .. "@" .. authority end
|
||||||
|
end
|
||||||
|
if authority then url = "//" .. authority .. url end
|
||||||
|
if parsed.scheme then url = parsed.scheme .. ":" .. url end
|
||||||
|
if parsed.fragment then url = url .. "#" .. parsed.fragment end
|
||||||
|
-- url = string.gsub(url, "%s", "")
|
||||||
|
return url
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Builds a absolute URL from a base and a relative URL according to RFC 2396
|
||||||
|
-- Input
|
||||||
|
-- base_url
|
||||||
|
-- relative_url
|
||||||
|
-- Returns
|
||||||
|
-- corresponding absolute url
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
function _M.absolute(base_url, relative_url)
|
||||||
|
if base.type(base_url) == "table" then
|
||||||
|
base_parsed = base_url
|
||||||
|
base_url = _M.build(base_parsed)
|
||||||
|
else
|
||||||
|
base_parsed = _M.parse(base_url)
|
||||||
|
end
|
||||||
|
local relative_parsed = _M.parse(relative_url)
|
||||||
|
if not base_parsed then return relative_url
|
||||||
|
elseif not relative_parsed then return base_url
|
||||||
|
elseif relative_parsed.scheme then return relative_url
|
||||||
|
else
|
||||||
|
relative_parsed.scheme = base_parsed.scheme
|
||||||
|
if not relative_parsed.authority then
|
||||||
|
relative_parsed.authority = base_parsed.authority
|
||||||
|
if not relative_parsed.path then
|
||||||
|
relative_parsed.path = base_parsed.path
|
||||||
|
if not relative_parsed.params then
|
||||||
|
relative_parsed.params = base_parsed.params
|
||||||
|
if not relative_parsed.query then
|
||||||
|
relative_parsed.query = base_parsed.query
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
relative_parsed.path = absolute_path(base_parsed.path or "",
|
||||||
|
relative_parsed.path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return _M.build(relative_parsed)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Breaks a path into its segments, unescaping the segments
|
||||||
|
-- Input
|
||||||
|
-- path
|
||||||
|
-- Returns
|
||||||
|
-- segment: a table with one entry per segment
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
function _M.parse_path(path)
|
||||||
|
local parsed = {}
|
||||||
|
path = path or ""
|
||||||
|
--path = string.gsub(path, "%s", "")
|
||||||
|
string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end)
|
||||||
|
for i = 1, #parsed do
|
||||||
|
parsed[i] = _M.unescape(parsed[i])
|
||||||
|
end
|
||||||
|
if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end
|
||||||
|
if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end
|
||||||
|
return parsed
|
||||||
|
end
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- Builds a path component from its segments, escaping protected characters.
|
||||||
|
-- Input
|
||||||
|
-- parsed: path segments
|
||||||
|
-- unsafe: if true, segments are not protected before path is built
|
||||||
|
-- Returns
|
||||||
|
-- path: corresponding path stringing
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
function _M.build_path(parsed, unsafe)
|
||||||
|
local path = ""
|
||||||
|
local n = #parsed
|
||||||
|
if unsafe then
|
||||||
|
for i = 1, n-1 do
|
||||||
|
path = path .. parsed[i]
|
||||||
|
path = path .. "/"
|
||||||
|
end
|
||||||
|
if n > 0 then
|
||||||
|
path = path .. parsed[n]
|
||||||
|
if parsed.is_directory then path = path .. "/" end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
for i = 1, n-1 do
|
||||||
|
path = path .. protect_segment(parsed[i])
|
||||||
|
path = path .. "/"
|
||||||
|
end
|
||||||
|
if n > 0 then
|
||||||
|
path = path .. protect_segment(parsed[n])
|
||||||
|
if parsed.is_directory then path = path .. "/" end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if parsed.is_absolute then path = "/" .. path end
|
||||||
|
return path
|
||||||
|
end
|
||||||
|
|
||||||
|
return _M
|
168
Me_Lua/h10/ssl.lua
Normal file
168
Me_Lua/h10/ssl.lua
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
------------------------------------------------------------------------------
|
||||||
|
-- LuaSec 0.5
|
||||||
|
-- Copyright (C) 2006-2014 Bruno Silvestre
|
||||||
|
--
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local core = require("ssl.core")
|
||||||
|
local context = require("ssl.context")
|
||||||
|
local x509 = require("ssl.x509")
|
||||||
|
|
||||||
|
module("ssl", package.seeall)
|
||||||
|
|
||||||
|
_VERSION = "0.5.PR"
|
||||||
|
_COPYRIGHT = core.copyright()
|
||||||
|
|
||||||
|
-- Export
|
||||||
|
loadcertificate = x509.load
|
||||||
|
|
||||||
|
-- We must prevent the contexts to be collected before the connections,
|
||||||
|
-- otherwise the C registry will be cleared.
|
||||||
|
local registry = setmetatable({}, {__mode="k"})
|
||||||
|
|
||||||
|
--
|
||||||
|
--
|
||||||
|
--
|
||||||
|
local function optexec(func, param, ctx)
|
||||||
|
if param then
|
||||||
|
if type(param) == "table" then
|
||||||
|
return func(ctx, unpack(param))
|
||||||
|
else
|
||||||
|
return func(ctx, param)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
--
|
||||||
|
--
|
||||||
|
function newcontext(cfg)
|
||||||
|
local succ, msg, ctx
|
||||||
|
-- Create the context
|
||||||
|
ctx, msg = context.create(cfg.protocol)
|
||||||
|
if not ctx then return nil, msg end
|
||||||
|
-- Mode
|
||||||
|
succ, msg = context.setmode(ctx, cfg.mode)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
-- Load the key
|
||||||
|
if cfg.key then
|
||||||
|
if cfg.password and
|
||||||
|
type(cfg.password) ~= "function" and
|
||||||
|
type(cfg.password) ~= "string"
|
||||||
|
then
|
||||||
|
return nil, "invalid password type"
|
||||||
|
end
|
||||||
|
succ, msg = context.loadkey(ctx, cfg.key, cfg.password)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
end
|
||||||
|
-- Load the certificate
|
||||||
|
if cfg.certificate then
|
||||||
|
succ, msg = context.loadcert(ctx, cfg.certificate)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
end
|
||||||
|
-- Load the CA certificates
|
||||||
|
if cfg.cafile or cfg.capath then
|
||||||
|
succ, msg = context.locations(ctx, cfg.cafile, cfg.capath)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
end
|
||||||
|
-- Set SSL ciphers
|
||||||
|
if cfg.ciphers then
|
||||||
|
succ, msg = context.setcipher(ctx, cfg.ciphers)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
end
|
||||||
|
-- Set the verification options
|
||||||
|
succ, msg = optexec(context.setverify, cfg.verify, ctx)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
-- Set SSL options
|
||||||
|
succ, msg = optexec(context.setoptions, cfg.options, ctx)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
-- Set the depth for certificate verification
|
||||||
|
if cfg.depth then
|
||||||
|
succ, msg = context.setdepth(ctx, cfg.depth)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- NOTE: Setting DH parameters and elliptic curves needs to come after
|
||||||
|
-- setoptions(), in case the user has specified the single_{dh,ecdh}_use
|
||||||
|
-- options.
|
||||||
|
|
||||||
|
-- Set DH parameters
|
||||||
|
if cfg.dhparam then
|
||||||
|
if type(cfg.dhparam) ~= "function" then
|
||||||
|
return nil, "invalid DH parameter type"
|
||||||
|
end
|
||||||
|
context.setdhparam(ctx, cfg.dhparam)
|
||||||
|
end
|
||||||
|
-- Set elliptic curve
|
||||||
|
if cfg.curve then
|
||||||
|
succ, msg = context.setcurve(ctx, cfg.curve)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
end
|
||||||
|
-- Set extra verification options
|
||||||
|
if cfg.verifyext and ctx.setverifyext then
|
||||||
|
succ, msg = optexec(ctx.setverifyext, cfg.verifyext, ctx)
|
||||||
|
if not succ then return nil, msg end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
--
|
||||||
|
--
|
||||||
|
function wrap(sock, cfg)
|
||||||
|
local ctx, msg
|
||||||
|
if type(cfg) == "table" then
|
||||||
|
ctx, msg = newcontext(cfg)
|
||||||
|
if not ctx then return nil, msg end
|
||||||
|
else
|
||||||
|
ctx = cfg
|
||||||
|
end
|
||||||
|
local s, msg = core.create(ctx)
|
||||||
|
if s then
|
||||||
|
core.setfd(s, sock:getfd())
|
||||||
|
sock:setfd(core.invalidfd)
|
||||||
|
registry[s] = ctx
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
return nil, msg
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Extract connection information.
|
||||||
|
--
|
||||||
|
local function info(ssl, field)
|
||||||
|
local str, comp, err, protocol
|
||||||
|
comp, err = core.compression(ssl)
|
||||||
|
if err then
|
||||||
|
return comp, err
|
||||||
|
end
|
||||||
|
-- Avoid parser
|
||||||
|
if field == "compression" then
|
||||||
|
return comp
|
||||||
|
end
|
||||||
|
local info = {compression = comp}
|
||||||
|
str, info.bits, info.algbits, protocol = core.info(ssl)
|
||||||
|
if str then
|
||||||
|
info.cipher, info.protocol, info.key,
|
||||||
|
info.authentication, info.encryption, info.mac =
|
||||||
|
string.match(str,
|
||||||
|
"^(%S+)%s+(%S+)%s+Kx=(%S+)%s+Au=(%S+)%s+Enc=(%S+)%s+Mac=(%S+)")
|
||||||
|
info.export = (string.match(str, "%sexport%s*$") ~= nil)
|
||||||
|
end
|
||||||
|
if protocol then
|
||||||
|
info.protocol = protocol
|
||||||
|
end
|
||||||
|
if field then
|
||||||
|
return info[field]
|
||||||
|
end
|
||||||
|
-- Empty?
|
||||||
|
return ( (next(info)) and info )
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Set method for SSL connections.
|
||||||
|
--
|
||||||
|
core.setmethod("info", info)
|
||||||
|
|
BIN
Me_Lua/h10/ssl.so
Normal file
BIN
Me_Lua/h10/ssl.so
Normal file
Binary file not shown.
138
Me_Lua/h10/ssl/https.lua
Normal file
138
Me_Lua/h10/ssl/https.lua
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
----------------------------------------------------------------------------
|
||||||
|
-- LuaSec 0.5
|
||||||
|
-- Copyright (C) 2009-2014 PUC-Rio
|
||||||
|
--
|
||||||
|
-- Author: Pablo Musa
|
||||||
|
-- Author: Tomas Guisasola
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local socket = require("socket")
|
||||||
|
local ssl = require("ssl")
|
||||||
|
local ltn12 = require("ltn12")
|
||||||
|
local http = require("socket.http")
|
||||||
|
local url = require("socket.url")
|
||||||
|
|
||||||
|
local table = require("table")
|
||||||
|
local string = require("string")
|
||||||
|
|
||||||
|
local try = socket.try
|
||||||
|
local type = type
|
||||||
|
local pairs = pairs
|
||||||
|
local getmetatable = getmetatable
|
||||||
|
|
||||||
|
module("ssl.https")
|
||||||
|
|
||||||
|
_VERSION = "0.5"
|
||||||
|
_COPYRIGHT = "LuaSec 0.5 - Copyright (C) 2009-2014 PUC-Rio"
|
||||||
|
|
||||||
|
-- Default settings
|
||||||
|
PORT = 443
|
||||||
|
|
||||||
|
local cfg = {
|
||||||
|
protocol = "tlsv1",
|
||||||
|
options = "all",
|
||||||
|
verify = "none",
|
||||||
|
}
|
||||||
|
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
-- Auxiliar Functions
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Insert default HTTPS port.
|
||||||
|
local function default_https_port(u)
|
||||||
|
return url.build(url.parse(u, {port = PORT}))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Convert an URL to a table according to Luasocket needs.
|
||||||
|
local function urlstring_totable(url, body, result_table)
|
||||||
|
url = {
|
||||||
|
url = default_https_port(url),
|
||||||
|
method = body and "POST" or "GET",
|
||||||
|
sink = ltn12.sink.table(result_table)
|
||||||
|
}
|
||||||
|
if body then
|
||||||
|
url.source = ltn12.source.string(body)
|
||||||
|
url.headers = {
|
||||||
|
["content-length"] = #body,
|
||||||
|
["content-type"] = "application/x-www-form-urlencoded",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return url
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Forward calls to the real connection object.
|
||||||
|
local function reg(conn)
|
||||||
|
local mt = getmetatable(conn.sock).__index
|
||||||
|
for name, method in pairs(mt) do
|
||||||
|
if type(method) == "function" then
|
||||||
|
conn[name] = function (self, ...)
|
||||||
|
return method(self.sock, ...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return a function which performs the SSL/TLS connection.
|
||||||
|
local function tcp(params)
|
||||||
|
params = params or {}
|
||||||
|
-- Default settings
|
||||||
|
for k, v in pairs(cfg) do
|
||||||
|
params[k] = params[k] or v
|
||||||
|
end
|
||||||
|
-- Force client mode
|
||||||
|
params.mode = "client"
|
||||||
|
-- 'create' function for LuaSocket
|
||||||
|
return function ()
|
||||||
|
local conn = {}
|
||||||
|
conn.sock = try(socket.tcp())
|
||||||
|
local st = getmetatable(conn.sock).__index.settimeout
|
||||||
|
function conn:settimeout(...)
|
||||||
|
return st(self.sock, ...)
|
||||||
|
end
|
||||||
|
-- Replace TCP's connection function
|
||||||
|
function conn:connect(host, port)
|
||||||
|
try(self.sock:connect(host, port))
|
||||||
|
self.sock = try(ssl.wrap(self.sock, params))
|
||||||
|
try(self.sock:dohandshake())
|
||||||
|
reg(self, getmetatable(self.sock))
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
return conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
-- Main Function
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- Make a HTTP request over secure connection. This function receives
|
||||||
|
-- the same parameters of LuaSocket's HTTP module (except 'proxy' and
|
||||||
|
-- 'redirect') plus LuaSec parameters.
|
||||||
|
--
|
||||||
|
-- @param url mandatory (string or table)
|
||||||
|
-- @param body optional (string)
|
||||||
|
-- @return (string if url == string or 1), code, headers, status
|
||||||
|
--
|
||||||
|
function request(url, body)
|
||||||
|
local result_table = {}
|
||||||
|
local stringrequest = type(url) == "string"
|
||||||
|
if stringrequest then
|
||||||
|
url = urlstring_totable(url, body, result_table)
|
||||||
|
else
|
||||||
|
url.url = default_https_port(url.url)
|
||||||
|
end
|
||||||
|
if http.PROXY or url.proxy then
|
||||||
|
return nil, "proxy not supported"
|
||||||
|
elseif url.redirect then
|
||||||
|
return nil, "redirect not supported"
|
||||||
|
elseif url.create then
|
||||||
|
return nil, "create function not permitted"
|
||||||
|
end
|
||||||
|
-- New 'create' function to establish a secure connection
|
||||||
|
url.create = tcp(url)
|
||||||
|
local res, code, headers, status = http.request(url)
|
||||||
|
if res and stringrequest then
|
||||||
|
return table.concat(result_table), code, headers, status
|
||||||
|
end
|
||||||
|
return res, code, headers, status
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user