create luci frame

This commit is contained in:
JamesonHuang 2015-05-09 18:48:46 +08:00
parent 42317d1f67
commit daa1b5684b
292 changed files with 60930 additions and 0 deletions

14
Me_Lua/r13/MZLog.lua Normal file
View 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/r13/Posix.lua Normal file
View 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/r13/cjson.so Normal file

Binary file not shown.

BIN
Me_Lua/r13/lfs.so Normal file

Binary file not shown.

BIN
Me_Lua/r13/lsqlite3.so Normal file

Binary file not shown.

305
Me_Lua/r13/ltn12.lua Normal file
View 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

View File

@ -0,0 +1,611 @@
--[[
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
--wifi重连 &开关基础函数
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
--wifi重连
function wifi_reconnect(wnet)
wifi_reconnect_shutdown(false, wnet)
end
--wifi开关
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

View File

@ -0,0 +1,238 @@
module("luci.controller.api.index", package.seeall)
--import lua_file路径问题
local bfs = require "meizu.bfs"
local cjson = require "cjson"
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"
--replace
--bind_router流程如何
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
factory_reset = bfs.factory_reset
set_passwd = bfs.set_passwd
silent_upgrade = bfs.silent_upgrade
sip = sipfs.sip
pysip = sipfs.pysip
upload_router_log = sipfs.upload_router_log
--network
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_wifi_settings = nwfs.nw_get_wifi_settings
nw_set_device_name = nwfs.nw_set_device_name
nw_set_wan_switch = nwfs.nw_set_wan_switch
nw_set_wan_type = nwfs.nw_set_wan_type
nw_wifi_settings = nwfs.nw_wifi_settings
nw_get_wireless_channel = nwfs.nw_get_wireless_channel
nw_set_wireless_channel = nwfs.nw_set_wireless_channel
nw_scan_ble_switch = nwfs.nw_scan_ble_switch
nw_get_ble_device_list = nwfs.nw_get_ble_device_list
nw_add_ble_mesh_device = nwfs.nw_add_ble_mesh_device
nw_get_ble_device_status = nwfs.nw_get_ble_device_status
nw_get_mesh_device_list = nwfs.nw_get_mesh_device_list
nw_remove_ble_from_mesh = nwfs.nw_remove_ble_from_mesh
nw_dismiss_mesh = nwfs.nw_dismiss_mesh
nw_set_mesh_device_attr = nwfs.nw_set_mesh_device_attr
nw_reboot_mesh_device = nwfs.nw_reboot_mesh_device
nw_unmesh_all_device = nwfs.nw_unmesh_all_device
nw_set_mesh_device_timer = nwfs.nw_set_mesh_device_timer
nw_del_mesh_device_timer = nwfs.nw_del_mesh_device_timer
nw_set_mesh_network_pwd = nwfs.nw_set_mesh_network_pwd
nw_set_lamp_brightness = nwfs.nw_set_lamp_brightness
get_net_device = nwfs.get_net_device
real_time_net_speed = nwfs.real_time_net_speed
check_upgrade = upgdfs.check_upgrade
do_upgrade = upgdfs.do_upgrade
local_upgrade = upgdfs.local_upgrade
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", "searchrouter"}, call("nw_search_router"), nil)
--leaf属性具体?
page.leaf = true
page = entry({"api", "bindRouter"}, call("bind_router"), 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", "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", "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", "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", "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", "doupgrade"}, call("nw_do_upgrade"), nil)
page.leaf = true
page = entry({"api", "checkupgrade"}, call("nw_check_upgrade"), 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) --输出到html页面结果
end
--升级nw全称是
function nw_do_upgrade()
local ret = {} --这是一个数组还是哈希?
luci.http.status(200, "upgrading....")
ret["code"] = 2004
ret["result"] = "upgrading...."
luci.http.write(data_to_json(ret)) --把ret转成json并输出到页面
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 nw_exec_reboot()
local ret = {}
ret["result"] = true
luci.http.write_json(ret)
exec_reboot()
end
--搜索路由器具体功能实现?
function nw_search_router()
local wl_type_val = luci.http.formvalue("type")
local wireless_dev = "ra0"
local wireless_type = "2.4G"
if wl_type_val == "2" then
wireless_type = "5G"
wireless_dev = "rai0"
end
--MZLog.log??
require "MZLog".log(3, wl_type_val)
require "MZLog".log(3, wireless_type)
local sub = require "string".sub
local trim = require "string".trim
local ssid_table = {}
local cmd = [[ap_scan.sh ]]..wireless_dev..[[| grep "^[0-9]"]]
local ssids = io.popen(cmd)
local ln = 1
require "MZLog".log(3, debug.getinfo(1).currentline)
for line in ssids:lines() do
require "MZLog".log(3, debug.getinfo(1).currentline)
require "MZLog".log(3, line)
require "MZLog".log(3, debug.getinfo(1).currentline)
local assid = {}
local channel = trim(sub(line, 1, 4))
local ssid = trim(sub(line, 5, 37))
local mac = trim(sub(line, 38, 54))
local sec = trim(sub(line, 58, 79))
local rss = trim(sub(line, 81, 82))
local extch = trim(sub(line, 98, 103))
assid["mac"] = mac
assid["rss"] = rss
assid["sec"] = sec
assid["ssid"] = ssid
assid["type"] = wireless_type
assid["channel"] = channel
assid["extch"] = extch
ssid_table[ln] = assid
ln = ln + 1
end
ssids:close()
require "MZLog".log(3, debug.getinfo(1).currentline)
luci.http.write_json(ssid_table)
end

View File

@ -0,0 +1,105 @@
module("luci.controller.bs.index", package.seeall)
local arpmon = require "meizu.arpmon"
local bfs = require "meizu.bfs"
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
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 sauth = require "luci.sauth"
local token = sauth.noAuthGetToken()
if token then
luci.http.write_json(token)
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

View 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

File diff suppressed because it is too large Load Diff

200
Me_Lua/r13/luci/sauth.lua Normal file
View 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

103
Me_Lua/r13/meizu/arpmon.lua Normal file
View File

@ -0,0 +1,103 @@
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 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
local fetch_all_arp = dbfs.fetch_all_arp
local update_arp = dbfs.update_arp
local getAllWifiConnetDeviceDict = nwfs.getAllWifiConnetDeviceDict
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
ipmacs[#ipmacs] = nil
local new_devs = {}
local allarp = fetch_all_arp()
local wifiDeviceDict = getAllWifiConnetDeviceDict()
if nil == allarp then
new_devs = ipmacs
else
for k, v in pairs(ipmacs) do
local ipmac = strsplit(v, ',')
local ip = ipmac[1]
local mac = ipmac[2]
mac = string.upper(mac)
local isnew = true
local wf = 0
for index, value in pairs(allarp) do
if mac == string.upper(value["mac"]) then
isnew = false
wf = value["wifi"]
break
end
end
if isnew == true then
table.insert(new_devs,v)
else
local wdd = wifiDeviceDict[mac]
if nil ~= wdd then
wf = wdd.wifiIndex
end
update_arp(mac, ip, wf)
end
end
end
for k, v in pairs(new_devs) do
local ipmac = strsplit(v, ',')
local ip = ipmac[1]
local mac = string.upper(ipmac[2])
if ip ~= "" then
local wifi = 0
local wdd = wifiDeviceDict[mac]
if nil ~= wdd then
wifi = wdd.wifiIndex
end
if "00:00:00:00:00:00" ~= mac then
insert_arp_macip(mac, ip, wifi)
end
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

370
Me_Lua/r13/meizu/bfs.lua Normal file
View File

@ -0,0 +1,370 @@
module("meizu.bfs", package.seeall)
--API base functions
local cjson = require "cjson"
local dbfs = require "meizu.dbfs"
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")
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; /usr/bin/router_reset;/sbin/reboot -f")
end
function set_passwd()
local result = {}
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)
result["result"] = true
luci.http.write_json(result)
end
end
result["result"] = false
luci.http.write_json(result)
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 = "R13WZLCZ7AC1001"
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 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 sysinfo()
local LuciNetwork = require("luci.model.network").init()
local lanNetwork = LuciNetwork:get_network("lan")
local wanNetwork = LuciNetwork:get_network("wan")
local wanType = "dhcp"
if wanNetwork and lanNetwork then
local apc = lanNetwork:get_option_value("apclient")
if nil ~= apc and "" ~= apc then
wanType = "apclient"
else
wanType = wanNetwork:proto()
end
end
local lue = require("luci.util").exec
local ret = {}
ret["wanType"] = wanType
ret["romversion"] = get_device_version()
ret["SN"] = get_device_SN()
ret["deviceModel"] = "R13"
ret["routername"] = "mzrt"..get_device_SN()
local ssid1, ssid2 = require "meizu.nwfs".get_wifi_ssids()
ret["ssid1"] = ssid2
ret["ssid2"] = ssid1
local cmd = [[df /mnt|grep -q sda;echo -n $?]]
ret["diskstatus"] = lue(cmd)
cmd = [[echo -n $(ifconfig br-lan |grep HWaddr|sed 's/.*HWaddr //' | sed 's/\ .*//')]]
ret["brlanmac"] = lue(cmd)
cmd = [[echo -n $(ifconfig br-lan |grep 'inet addr'|awk -F':' '{print $2}' |awk '{printf $1}')]]
ret["brlanip"] = lue(cmd)
return ret
end

View File

@ -0,0 +1,5 @@
#!/bin/sh
/etc/init.d/uhttpd stop
rm -rf /tmp/luci-indexcache /tmp/luci-modulecache
rm -rf /tmp/luci-sessions
/etc/init.d/uhttpd start

410
Me_Lua/r13/meizu/dbfs.lua Normal file
View File

@ -0,0 +1,410 @@
module("meizu.dbfs", package.seeall)
local sqlite3 = require("lsqlite3")
local r13db = "/etc/r13db"
function database_busy()
return true
end
function updateDeviceNickname(mac, nickname)
local db = sqlite3.open(r13db)
local sqlStr = string.format("update maclist set devicename = '%s' where mac = '%s'", nickname, mac)
db:exec(sqlStr)
return db:close()
end
function get_dev_nick_name(mac)
local db = sqlite3.open(r13db)
local sqlStr = string.format("select devicename, orgname from maclist where mac like '%s'", mac)
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 fetchDenyDeviceInfo(mac)
local db = sqlite3.open(r13db)
local sqlStr = string.format("select * from maclist where mac = '%s'", mac)
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(r13db)
local sqlStr = string.format("ALTER TABLE maclist ADD COLUMN ip varchar(100)")
db:exec(sqlStr)
return db:close()
end
function fetchAllDeviceInfo()
local db = sqlite3.open(r13db)
local sqlStr = string.format("select * from maclist")
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(r13db)
local sqlStr = string.format("update maclist set orgname = '%s' where mac = '%s'", orgname, mac)
db:exec(sqlStr)
return db:close()
end
function saveDeviceInfo(mac, orgname, devicename, deviceip)
local db = sqlite3.open(r13db)
local fetch = string.format("select * from maclist where mac = '%s'", mac)
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 init_arp_table()
local db = sqlite3.open(r13db)
local sqlStr = string.format("create table if not exists arp(mac varchar(18), ip varchar(16), wifi integer)")
db:exec(sqlStr)
return db:close()
end
function fetch_all_arp()
local db = sqlite3.open(r13db)
local sqlStr = string.format("select * from arp")
local result = {}
for row in db:rows(sqlStr) do
if row then
table.insert(result,{
["mac"] = row[1],
["ip"] = row[2],
["wifi"] = row[3]
})
end
end
db:close()
return result
end
function fetch_arp(mac)
local db = sqlite3.open(r13db)
local sqlStr = string.format("select * from arp where mac = '%s' limit 1", mac)
local result = {}
for row in db:rows(sqlStr) do
if row then
table.insert(result,{
["mac"] = row[1],
["ip"] = row[2],
["wifi"] = row[3]
})
end
end
db:close()
return result
end
function insert_arp_macip(mac, ip, wifi)
local db = sqlite3.open(r13db)
local sqlStr = string.format("delete from ")
sqlStr = string.format("insert into arp values('%s', '%s', %d)", mac, ip, wifi)
db:exec(sqlStr)
return db:close()
end
function delete_arp_all_mac()
local db = sqlite3.open(r13db)
local sqlStr = string.format("delete from arp")
db:exec(sqlStr)
return db:close()
end
function update_arp(mac, ip, wifi)
local db = sqlite3.open(r13db)
local sqlStr = string.format("update arp set ip = '%s', wifi = %d where mac = '%s'", ip, wifi, mac)
db:exec(sqlStr)
return db:close()
end
function init_access_token_table()
local db = sqlite3.open(r13db)
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(r13db)
local sqlStr = string.format("insert into accessTokenTable values('%s', %d)", token, expireTime)
db:exec(sqlStr)
return db:close()
end
function fetch_access_token()
local db = sqlite3.open(r13db)
local sqlStr = string.format("select * from accessTokenTable")
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(r13db)
local sqlStr = string.format("update accessTokenTable set token = '%s', expireTime = %d where token = '%s'", newToken, expireTime, oldToken)
db:exec(sqlStr)
return db:close()
end
function delete_access_token()
local db = sqlite3.open(r13db)
local sqlStr = string.format("delete from accessTokenTable")
db:exec(sqlStr)
return db:close()
end
function init_deny_mac_table()
local db = sqlite3.open(r13db)
local sqlStr = string.format("create table if not exists denymac(mac varchar(50))")
db:exec(sqlStr)
return db:close()
end
function add_deny_mac(mac)
local db = sqlite3.open(r13db)
local sqlStr = string.format("insert into denymac values('%s')", mac)
db:exec(sqlStr)
return db:close()
end
function fetch_all_deny_mac()
local db = sqlite3.open(r13db)
local sqlStr = string.format("select * from denymac")
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 delete_deny_mac(mac)
local db = sqlite3.open(r13db)
local sqlStr = string.format("delete from denymac where mac = '%s'", mac)
db:exec(sqlStr)
return db:close()
end
function init_ssid_table()
local db = sqlite3.open(r13db)
local sqlStr = string.format("create table if not exists ssid(ssid24 varchar(50), ssid5 varchar(50))")
db:exec(sqlStr)
return db:close()
end
function add_ssid(ssid24, ssid5)
local db = sqlite3.open(r13db)
local sqlStr = string.format("insert into ssid values('%s', '%s')", ssid24, ssid5)
db:exec(sqlStr)
return db:close()
end
function fetch_ssid()
local db = sqlite3.open(r13db)
local sqlStr = string.format("select ssid24,ssid5 from ssid limit 1")
local result = {}
for row in db:rows(sqlStr) do
if row then
table.insert(result,{
["ssid24"] = row[1],
["ssid5"] = row[2]
})
end
end
db:close()
return result
end
function update_ssid(ssid24, ssid5)
local db = sqlite3.open(r13db)
local sqlStr = string.format("update ssid set ssid24 = '%s', ssid5 = '%s'", ssid24, ssid5)
db:exec(sqlStr)
return db:close()
end
function initBluetoothTable()
local db = sqlite3.open(r13db)
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(r13db)
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(r13db)
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(r13db)
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(r13db)
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(r13db)
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(r13db)
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(r13db)
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(r13db)
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(r13db)
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

2804
Me_Lua/r13/meizu/nwfs.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
upgradeFlagFile = "/tmp/upgradeFlagFile"
upgradeLOCK = "/bin/touch "..upgradeFlagFile
upgradeUNLOCK = "/bin/rm "..upgradeFlagFile

690
Me_Lua/r13/meizu/sipfs.lua Normal file
View File

@ -0,0 +1,690 @@
module("meizu.sipfs", package.seeall)
--sip functions
local bfs = require "meizu.bfs"
local cjson = require "cjson"
local nwfs = require "meizu.nwfs"
local RC = require "meizu.r10config"
local sipfs = require "meizu.sipfs"
local upgdfs = require "meizu.upgdfs"
local b64dec = bfs.b64dec
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 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 real_time_net_speed = nwfs.real_time_net_speed
local set_device_name = nwfs.set_device_name
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_wireless_channel = nwfs.ww_get_wireless_channel
local ww_set_wireless_channel = nwfs.ww_set_wireless_channel
local ww_scan_ble_switch = nwfs.ww_scan_ble_switch
local ww_add_ble_mesh_device = nwfs.ww_add_ble_mesh_device
local ww_get_ble_device_list = nwfs.ww_get_ble_device_list
local ww_get_ble_device_status = nwfs.ww_get_ble_device_status
local ww_set_mesh_device_attr = nwfs.ww_set_mesh_device_attr
local ww_get_mesh_device_list = nwfs.ww_get_mesh_device_list
local ww_reboot_mesh_device = nwfs.ww_reboot_mesh_device
local ww_remove_ble_from_mesh = nwfs.ww_remove_ble_from_mesh
local ww_unmesh_all_device = nwfs.ww_unmesh_all_device
local ww_set_mesh_device_timer = nwfs.ww_set_mesh_device_timer
local ww_del_mesh_device_timer = nwfs.ww_del_mesh_device_timer
local check_upgrade = upgdfs.check_upgrade
local do_upgrade = upgdfs.do_upgrade
local local_upgrade = upgdfs.local_upgrade
local table_merge = bfs.table_merge
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
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, pd)
require "MZLog".log(3, debug.getinfo(1).currentline)
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 = {
["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 ssid_2g = nil
local ssid_5g = nil
local pwd_2g = nil
local pwd_5g = nil
local encry_2g = nil
local encry_5g = 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
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
end
end
end
local data = wifi_settings(switch_2g, ssid_2g, pwd_2g, encry_2g, switch_5g, ssid_5g, pwd_5g, encry_5g)
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,
["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,
["getsysinfo"] = function(cmd, cmdid)
local data = require "meizu.bfs".sysinfo()
data = data_to_json(data)
sip_response_uploader(cmd, cmdid, data)
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
sip_response_uploader(cmd, cmdid, ret)
end,
["scanBleSwitch"] = function(cmd, cmdid) --scanBleSwitch getMeshDeviceList getBleDeviceList
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,
["setMeashNetWorkPassword"] = 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_device_timer(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_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,
["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

231
Me_Lua/r13/meizu/upgdfs.lua Normal file
View File

@ -0,0 +1,231 @@
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 = "R13"
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 = "R13"
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/router_reset; sleep 2;]]
--cmd = cmd..[[/sbin/sysupgrade -n -v ]]..ota_img..[[|tee -a /tmp/ota.log;]]
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 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/r13/mime.lua Normal file
View 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/r13/mime.so.1.0.3 Normal file

Binary file not shown.

BIN
Me_Lua/r13/mime/core.so Normal file

Binary file not shown.

BIN
Me_Lua/r13/posix.so Normal file

Binary file not shown.

136
Me_Lua/r13/routerReport.lua Normal file
View File

@ -0,0 +1,136 @@
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 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
function init_ssid_dbdata()
dbfs.init_ssid_table()
local ssidtable = dbfs.fetch_ssid()
if nil == ssidtable or 0 == #ssidtable then
local network = require "luci.model.network".init()
local wifi_net_ra0 = network:get_wifinet('mt7628.network1')
local ssid24 = wifi_net_ra0:get("ssid")
local wifi_net_rai0 = network:get_wifinet('mt7610e.network1')
local ssid5 = wifi_net_rai0:get("ssid")
dbfs.add_ssid(ssid24, ssid5)
end
end
init_ssid_dbdata()
dbfs.init_deny_mac_table()
ut()
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()
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()
report_rom_version()

149
Me_Lua/r13/socket.lua Normal file
View 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

Binary file not shown.

BIN
Me_Lua/r13/socket/core.so Normal file

Binary file not shown.

285
Me_Lua/r13/socket/ftp.lua Normal file
View 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

View 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/r13/socket/http.lua Normal file
View 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/r13/socket/smtp.lua Normal file
View 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/r13/socket/tp.lua Normal file
View 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/r13/socket/url.lua Normal file
View 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/r13/ssl.lua Normal file
View 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/r13/ssl.so Normal file

Binary file not shown.

138
Me_Lua/r13/ssl/https.lua Normal file
View 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

669
Me_Lua/r13/tags Normal file
View File

@ -0,0 +1,669 @@
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
"Failed to execute " .. (type(c.target) ./luci/dispatcher.lua /^ "Failed to execute " .. (type(c.target) == "function" and "function" or c.target.type or "unknown") ..$/;" f
M.strsplit ./Posix.lua /^function M.strsplit(str, delim, maxNb)$/;" f
M.timeradd ./Posix.lua /^function M.timeradd (x,y)$/;" f
M.timercmp ./Posix.lua /^function M.timercmp (x, y)$/;" f
M.timersub ./Posix.lua /^function M.timersub (x,y)$/;" f
M.timesleep ./Posix.lua /^function M.timesleep (x)$/;" f
M.var_dump ./Posix.lua /^function M.var_dump(data, max_level, prefix)$/;" f
OTA_process_action ./meizu/sipfs.lua /^function OTA_process_action(vs_info)$/;" f
["addMeshDevice"] ./meizu/sipfs.lua /^ ["addMeshDevice"] = function(cmd, cmdid) $/;" f
["checkRouterUpdate"] ./meizu/sipfs.lua /^ ["checkRouterUpdate"] = function(cmd, cmdid)$/;" f
["delmeshdevicetimer"] ./meizu/sipfs.lua /^ ["delmeshdevicetimer"] = function(cmd, cmdid)$/;" f
["executeRouterUpdate"] ./meizu/sipfs.lua /^ ["executeRouterUpdate"] = function(cmd, cmdid)$/;" f
["factoryreset"] ./meizu/sipfs.lua /^ ["factoryreset"] = function(cmd, cmdid)$/;" f
["getBleDeviceList"] ./meizu/sipfs.lua /^ ["getBleDeviceList"] = function(cmd, cmdid)$/;" f
["getDeviceList"] ./meizu/sipfs.lua /^ ["getDeviceList"] = function(cmd, cmdid)$/;" f
["getMeshDeviceDetail"] ./meizu/sipfs.lua /^ ["getMeshDeviceDetail"] = function(cmd, cmdid) $/;" f
["getMeshDeviceList"] ./meizu/sipfs.lua /^ ["getMeshDeviceList"] = function(cmd, cmdid)$/;" f
["getWirelessChannel"] ./meizu/sipfs.lua /^ ["getWirelessChannel"] = function(cmd, cmdid)$/;" f
["getdevicedetails"] ./meizu/sipfs.lua /^ ["getdevicedetails"] = function(cmd, cmdid)$/;" f
["getsysinfo"] ./meizu/sipfs.lua /^ ["getsysinfo"] = function(cmd, cmdid)$/;" f
["getwifisettings"] ./meizu/sipfs.lua /^ ["getwifisettings"] = function(cmd, cmdid)$/;" f
["realtimenetspeed"] ./meizu/sipfs.lua /^ ["realtimenetspeed"] = function(cmd, cmdid)$/;" f
["rebootmeshdevice"] ./meizu/sipfs.lua /^ ["rebootmeshdevice"] = function(cmd, cmdid)$/;" f
["removeblefrommesh"] ./meizu/sipfs.lua /^ ["removeblefrommesh"] = function(cmd, cmdid)$/;" f
["scanBleSwitch"] ./meizu/sipfs.lua /^ ["scanBleSwitch"] = function(cmd, cmdid) --scanBleSwitch getMeshDeviceList getBleDeviceList$/;" f
["setDeviceName"] ./meizu/sipfs.lua /^ ["setDeviceName"] = function(cmd, cmdid)$/;" f
["setLampBrightness"] ./meizu/sipfs.lua /^ ["setLampBrightness"] = function(cmd, cmdid)$/;" f
["setMeashNetWorkPassword"] ./meizu/sipfs.lua /^ ["setMeashNetWorkPassword"] = function(cmd, cmdid)$/;" f
["setMeshDeviceAttr"] ./meizu/sipfs.lua /^ ["setMeshDeviceAttr"] = function(cmd, cmdid)$/;" f
["setReboot"] ./meizu/sipfs.lua /^ ["setReboot"] = function(cmd, cmdid)$/;" f
["setWanSwitch"] ./meizu/sipfs.lua /^ ["setWanSwitch"] = function(cmd, cmdid)$/;" f
["setWirelessChannel"] ./meizu/sipfs.lua /^ ["setWirelessChannel"] = function(cmd, cmdid)$/;" f
["setmeshdevicetimer"] ./meizu/sipfs.lua /^ ["setmeshdevicetimer"] = function(cmd, cmdid)$/;" f
["setwifisettings"] ./meizu/sipfs.lua /^ ["setwifisettings"] = function(cmd, cmdid)$/;" f
["unmeshalldevice"] ./meizu/sipfs.lua /^ ["unmeshalldevice"] = function(cmd, cmdid)$/;" f
_ ./luci/dispatcher.lua /^function _(text)$/;" f
_M.absolute ./socket/url.lua /^function _M.absolute(base_url, relative_url)$/;" f
_M.bind ./socket.lua /^function _M.bind(host, port, backlog)$/;" f
_M.build ./socket/url.lua /^function _M.build(parsed)$/;" f
_M.build_path ./socket/url.lua /^function _M.build_path(parsed, unsafe)$/;" f
_M.choose ./socket.lua /^function _M.choose(table)$/;" f
_M.command ./socket/ftp.lua /^_M.command = socket.protect(function(cmdt)$/;" f
_M.connect ./socket/tp.lua /^function _M.connect(host, port, timeout, create)$/;" f
_M.connect4 ./socket.lua /^function _M.connect4(address, port, laddress, lport)$/;" f
_M.connect6 ./socket.lua /^function _M.connect6(address, port, laddress, lport)$/;" f
_M.escape ./socket/url.lua /^function _M.escape(s)$/;" f
_M.get ./socket/ftp.lua /^_M.get = socket.protect(function(gett)$/;" f
_M.message ./socket/smtp.lua /^function _M.message(mesgt)$/;" f
_M.normalize ./mime.lua /^function _M.normalize(marker)$/;" f
_M.open ./socket/ftp.lua /^function _M.open(server, port, create)$/;" f
_M.open ./socket/http.lua /^function _M.open(host, port, create)$/;" f
_M.open ./socket/smtp.lua /^function _M.open(server, port, create)$/;" f
_M.parse ./socket/url.lua /^function _M.parse(url, default)$/;" f
_M.parse_path ./socket/url.lua /^function _M.parse_path(path)$/;" f
_M.put ./socket/ftp.lua /^_M.put = socket.protect(function(putt, body)$/;" f
_M.request ./socket/http.lua /^_M.request = socket.protect(function(reqt, body)$/;" f
_M.send ./socket/smtp.lua /^_M.send = socket.protect(function(mailt)$/;" f
_M.stuff ./mime.lua /^function _M.stuff()$/;" f
_M.unescape ./socket/url.lua /^function _M.unescape(s)$/;" f
__call ./socket.lua /^ __call = function()$/;" f
__call ./socket.lua /^ __call = function(self, chunk, err)$/;" f
__call ./socket/http.lua /^ __call = function()$/;" f
__call ./socket/http.lua /^ __call = function(self, chunk, err)$/;" f
_append ./luci/model/network.lua /^function _append(c, s, o, a)$/;" f
_arcombine ./luci/dispatcher.lua /^local function _arcombine(self, ...)$/;" f
_call ./luci/dispatcher.lua /^local function _call(self, ...)$/;" f
_cbi ./luci/dispatcher.lua /^local function _cbi(self, ...)$/;" f
_checkid ./luci/sauth.lua /^local function _checkid(id)$/;" f
_create_node ./luci/dispatcher.lua /^function _create_node(path)$/;" f
_filter ./luci/model/network.lua /^function _filter(c, s, o, r)$/;" f
_firstchild ./luci/dispatcher.lua /^function _firstchild()$/;" f
_form ./luci/dispatcher.lua /^local function _form(self, ...)$/;" f
_get ./luci/model/network.lua /^function _get(c, s, o)$/;" f
_iface_ignore ./luci/model/network.lua /^function _iface_ignore(x)$/;" f
_iface_virtual ./luci/model/network.lua /^function _iface_virtual(x)$/;" f
_ifattr ./luci/dispatcher.lua /^ local function _ifattr(cond, key, val)$/;" f
_read ./luci/sauth.lua /^local function _read(id)$/;" f
_resolve_path ./luci/dispatcher.lua /^ local function _resolve_path(path)$/;" f
_set ./luci/model/network.lua /^function _set(c, s, o, v)$/;" f
_stror ./luci/model/network.lua /^function _stror(s1, s2)$/;" f
_wifi_iface ./luci/model/network.lua /^function _wifi_iface(x)$/;" f
_wifi_lookup ./luci/model/network.lua /^function _wifi_lookup(ifn)$/;" f
_wifi_state ./luci/model/network.lua /^function _wifi_state(key, val, field)$/;" f
_write ./luci/sauth.lua /^local function _write(id, data)$/;" f
absolute_path ./socket/url.lua /^local function absolute_path(base_path, relative_path)$/;" f
addBluetoothDevice ./meizu/dbfs.lua /^function addBluetoothDevice(id, mac, key, name, deviceType, len)$/;" f
add_access_token ./meizu/dbfs.lua /^function add_access_token(token, expireTime)$/;" f
add_ble_mesh_device ./meizu/nwfs.lua /^function add_ble_mesh_device(mac)$/;" f
add_deny_mac ./meizu/dbfs.lua /^function add_deny_mac(mac)$/;" f
add_network ./luci/model/network.lua /^function add_network(self, n, options)$/;" f
add_ssid ./meizu/dbfs.lua /^function add_ssid(ssid24, ssid5)$/;" f
add_wifinet ./luci/model/network.lua /^function add_wifinet(self, net, options)$/;" f
adjust_headers ./socket/smtp.lua /^local function adjust_headers(mesgt)$/;" f
adjustheaders ./socket/http.lua /^local function adjustheaders(reqt)$/;" f
adjustproxy ./socket/http.lua /^local function adjustproxy(reqt)$/;" f
adjustrequest ./socket/http.lua /^local function adjustrequest(reqt)$/;" f
adjusturi ./socket/http.lua /^local function adjusturi(reqt)$/;" f
alias ./luci/dispatcher.lua /^function alias(...)$/;" f
apk ./luci/controller/bs/index.lua /^function apk()$/;" f
arcombine ./luci/dispatcher.lua /^function arcombine(trg1, trg2)$/;" f
assert(type(func) ./luci/dispatcher.lua /^ assert(type(func) == "function",$/;" f
assert(type(idx) ./luci/dispatcher.lua /^ assert(type(idx) == "function",$/;" f
assign ./luci/dispatcher.lua /^function assign(path, clone, title, order)$/;" f
attr ./luci/dispatcher.lua /^ attr = function(...) return _ifattr(true, ...) end;$/;" f
authen ./luci/dispatcher.lua /^ authen = function() return eu end$/;" f
authenticator.htmlauth ./luci/dispatcher.lua /^function authenticator.htmlauth(validator, accs, default)$/;" f
available ./luci/sauth.lua /^function available()$/;" f
b64dec ./meizu/bfs.lua /^function b64dec(data)$/;" f
b64enc ./meizu/bfs.lua /^function b64enc(data)$/;" f
bind_router ./meizu/bfs.lua /^function bind_router()$/;" f
bluetooth_info ./meizu/nwfs.lua /^function bluetooth_info()$/;" f
buf ./meizu/bfs.lua /^ buf = buf..string.format('"%s"' % tostring(x):gsub('[%z\\1-\\31]', function(c) return '\\\\u%04x' % c:byte(1) end))$/;" f
build_url ./luci/dispatcher.lua /^function build_url(...)$/;" f
cal_str_md5 ./meizu/bfs.lua /^function cal_str_md5(str)$/;" f
call ./luci/dispatcher.lua /^function call(name, ...)$/;" f
cancelapclient ./meizu/nwfs.lua /^function cancelapclient()$/;" f
cbi ./luci/dispatcher.lua /^function cbi(model, config)$/;" f
change_maclist_table ./meizu/dbfs.lua /^function change_maclist_table()$/;" f
check_ssid ./meizu/nwfs.lua /^function check_ssid(ssid)$/;" f
check_sys_password ./meizu/nwfs.lua /^function check_sys_password(password)$/;" f
check_sys_pwd ./meizu/nwfs.lua /^function check_sys_pwd(oldPassword)$/;" f
check_upgrade ./meizu/upgdfs.lua /^function check_upgrade()$/;" f
check_upgrade_status ./routerReport.lua /^function check_upgrade_status()$/;" f
check_wifi_passwd ./meizu/nwfs.lua /^function check_wifi_passwd(passwd,encryption)$/;" f
choose ./mime.lua /^local function choose(table)$/;" f
commit ./luci/model/network.lua /^function commit(self, ...)$/;" f
conn:connect ./ssl/https.lua /^ function conn:connect(host, port)$/;" f
conn:settimeout ./ssl/https.lua /^ function conn:settimeout(...)$/;" f
conn[name] ./ssl/https.lua /^ conn[name] = function (self, ...)$/;" f
createindex ./luci/dispatcher.lua /^function createindex()$/;" f
createindex_fastindex ./luci/dispatcher.lua /^function createindex_fastindex(path, suffixes)$/;" f
createindex_plain ./luci/dispatcher.lua /^function createindex_plain(path, suffixes)$/;" f
createtree ./luci/dispatcher.lua /^function createtree()$/;" f
data_to_json ./meizu/bfs.lua /^function data_to_json(x)$/;" f
database_busy ./meizu/dbfs.lua /^function database_busy()$/;" f
decodeURI ./meizu/bfs.lua /^function decodeURI(s)$/;" f
decodet['base64'] ./mime.lua /^decodet['base64'] = function()$/;" f
decodet['quoted-printable'] ./mime.lua /^decodet['quoted-printable'] = function()$/;" f
default_https_port ./ssl/https.lua /^local function default_https_port(u)$/;" f
del_mesh_device_timer ./meizu/nwfs.lua /^function del_mesh_device_timer(mac, timer_id)$/;" f
del_network ./luci/model/network.lua /^function del_network(self, n)$/;" f
del_wifinet ./luci/model/network.lua /^function del_wifinet(self, net)$/;" f
deleteBluetoothDevice ./meizu/dbfs.lua /^function deleteBluetoothDevice(mac)$/;" f
delete_access_token ./meizu/dbfs.lua /^function delete_access_token()$/;" f
delete_arp_all_mac ./meizu/dbfs.lua /^function delete_arp_all_mac()$/;" f
delete_deny_mac ./meizu/dbfs.lua /^function delete_deny_mac(mac)$/;" f
devip ./luci/controller/bs/index.lua /^function devip()$/;" f
diag_command ./luci/controller/admin/network.lua /^function diag_command(cmd, addr)$/;" f
diag_nslookup ./luci/controller/admin/network.lua /^function diag_nslookup(addr)$/;" f
diag_ping ./luci/controller/admin/network.lua /^function diag_ping(addr)$/;" f
diag_ping6 ./luci/controller/admin/network.lua /^function diag_ping6(addr)$/;" f
diag_traceroute ./luci/controller/admin/network.lua /^function diag_traceroute(addr)$/;" f
diag_traceroute6 ./luci/controller/admin/network.lua /^function diag_traceroute6(addr)$/;" f
dirty ./socket.lua /^ dirty = function() return sock:dirty() end$/;" f
dirty ./socket/http.lua /^ dirty = function() return sock:dirty() end$/;" f
dismiss_mesh ./meizu/nwfs.lua /^function dismiss_mesh()$/;" f
dispatch ./luci/dispatcher.lua /^function dispatch(request)$/;" f
do_upgrade ./meizu/upgdfs.lua /^function do_upgrade()$/;" f
download_list_post_process ./meizu/sipfs.lua /^function download_list_post_process(data, refine_cnt)$/;" f
download_task_operate_process ./meizu/sipfs.lua /^function download_task_operate_process(cmd, cmdid)$/;" f
elseif base.type(mesgt.body) ./socket/smtp.lua /^ elseif base.type(mesgt.body) == "function" then send_source(mesgt)$/;" f
empty ./ltn12.lua /^local function empty()$/;" f
encodeURI ./meizu/bfs.lua /^function encodeURI(s)$/;" f
encodet['base64'] ./mime.lua /^encodet['base64'] = function()$/;" f
encodet['quoted-printable'] ./mime.lua /^encodet['quoted-printable'] = function(mode)$/;" f
entry ./luci/dispatcher.lua /^function entry(path, target, title, order)$/;" f
error404 ./luci/dispatcher.lua /^function error404(message)$/;" f
error500 ./luci/dispatcher.lua /^function error500(message)$/;" f
exec_cmd_in_sh ./meizu/bfs.lua /^function exec_cmd_in_sh(command)$/;" f
exec_reboot ./meizu/bfs.lua /^function exec_reboot()$/;" f
export ./luci/dispatcher.lua /^ export = function(k, v) if tpl.context.viewns[k] == nil then tpl.context.viewns[k] = v end end;$/;" f
f.try ./socket/ftp.lua /^ f.try = socket.newtry(function() f:close() end)$/;" f
factory_reset ./meizu/bfs.lua /^function factory_reset()$/;" f
fetchAllBleMeshDevice ./meizu/dbfs.lua /^function fetchAllBleMeshDevice()$/;" f
fetchAllBluetoothDevice ./meizu/dbfs.lua /^function fetchAllBluetoothDevice()$/;" f
fetchAllDeviceInfo ./meizu/dbfs.lua /^function fetchAllDeviceInfo()$/;" f
fetchBluetoothDevice ./meizu/dbfs.lua /^function fetchBluetoothDevice(mac)$/;" f
fetchBluetoothDeviceKey ./meizu/dbfs.lua /^function fetchBluetoothDeviceKey()$/;" f
fetchDenyDeviceInfo ./meizu/dbfs.lua /^function fetchDenyDeviceInfo(mac)$/;" f
fetch_access_token ./meizu/dbfs.lua /^function fetch_access_token()$/;" f
fetch_all_arp ./meizu/dbfs.lua /^function fetch_all_arp()$/;" f
fetch_all_deny_mac ./meizu/dbfs.lua /^function fetch_all_deny_mac()$/;" f
fetch_arp ./meizu/dbfs.lua /^function fetch_arp(mac)$/;" f
fetch_ssid ./meizu/dbfs.lua /^function fetch_ssid()$/;" f
filter.chain ./ltn12.lua /^function filter.chain(...)$/;" f
filter.cycle ./ltn12.lua /^function filter.cycle(low, ctx, extra)$/;" f
firstchild ./luci/dispatcher.lua /^function firstchild()$/;" f
fork_restart_network ./meizu/nwfs.lua /^function fork_restart_network()$/;" f
fork_restart_wifi ./meizu/nwfs.lua /^function fork_restart_wifi()$/;" f
form ./luci/dispatcher.lua /^function form(model)$/;" f
format ./mime.lua /^local function format(chunk)$/;" f
function(p) parsed.password ./socket/url.lua /^ function(p) parsed.password = p; return "" end)$/;" f
function(p) parsed.port ./socket/url.lua /^ function(p) parsed.port = p; return "" end)$/;" f
function(s) parsed.scheme ./socket/url.lua /^ function(s) parsed.scheme = s; return "" end)$/;" f
function(s) return (s.interface ./luci/model/network.lua /^ function(s) return (s.interface == n) end)$/;" f
function(s) wfd[#wfd+1] ./luci/model/network.lua /^ function(s) wfd[#wfd+1] = s['.name'] end)$/;" f
function(u) parsed.userinfo ./socket/url.lua /^ function(u) parsed.userinfo = u; return "" end)$/;" f
genAuthToken ./luci/sauth.lua /^function genAuthToken()$/;" f
gen_check_fw_url_pd ./meizu/upgdfs.lua /^function gen_check_fw_url_pd()$/;" f
get ./luci/dispatcher.lua /^function get(...)$/;" f
getAllWifiConnetDeviceDict ./meizu/nwfs.lua /^function getAllWifiConnetDeviceDict()$/;" f
getBasicInfo ./routerReport.lua /^function getBasicInfo()$/;" f
getBleDeviceNameLength ./meizu/dbfs.lua /^function getBleDeviceNameLength(id)$/;" f
getBluetoothDevice ./meizu/dbfs.lua /^function getBluetoothDevice(id)$/;" f
getDHCPDict ./meizu/nwfs.lua /^function getDHCPDict()$/;" f
getDHCPIpDicts ./meizu/nwfs.lua /^function getDHCPIpDicts()$/;" f
getDHCPLists ./meizu/nwfs.lua /^function getDHCPLists()$/;" f
getDeviceInfoFromDB ./meizu/nwfs.lua /^function getDeviceInfoFromDB()$/;" f
getNetConnect ./meizu/nwfs.lua /^function getNetConnect(ip)$/;" f
getWanEth ./meizu/nwfs.lua /^function getWanEth()$/;" f
getWifiConnectDeviceList ./meizu/nwfs.lua /^function getWifiConnectDeviceList(wifiIndex)$/;" f
getWifiSettings ./luci/controller/admin/network.lua /^function getWifiSettings()$/;" f
get_ble_device_key ./meizu/nwfs.lua /^function get_ble_device_key()$/;" f
get_ble_device_list ./meizu/nwfs.lua /^function get_ble_device_list()$/;" f
get_ble_device_status ./meizu/nwfs.lua /^function get_ble_device_status(mac)$/;" f
get_bluetooth_info ./meizu/nwfs.lua /^function get_bluetooth_info()$/;" f
get_connect_device_list ./meizu/nwfs.lua /^function get_connect_device_list()$/;" f
get_connect_device_list_router ./meizu/nwfs.lua /^function get_connect_device_list_router()$/;" f
get_dev_nick_name ./meizu/dbfs.lua /^function get_dev_nick_name(mac)$/;" f
get_device_SN ./meizu/bfs.lua /^function get_device_SN()$/;" f
get_device_details ./meizu/nwfs.lua /^function get_device_details(mac)$/;" f
get_device_version ./meizu/bfs.lua /^function get_device_version()$/;" f
get_https_data ./meizu/bfs.lua /^function get_https_data(url, data)$/;" f
get_interface ./luci/model/network.lua /^function get_interface(self, i)$/;" f
get_interfaces ./luci/model/network.lua /^function get_interfaces(self)$/;" f
get_lan_ip ./meizu/nwfs.lua /^function get_lan_ip()$/;" f
get_mesh_device_list ./meizu/nwfs.lua /^function get_mesh_device_list()$/;" f
get_net_device ./meizu/nwfs.lua /^function get_net_device()$/;" f
get_network ./luci/model/network.lua /^function get_network(self, n)$/;" f
get_networks ./luci/model/network.lua /^function get_networks(self)$/;" f
get_protocol ./luci/model/network.lua /^function get_protocol(self, protoname, netname)$/;" f
get_protocols ./luci/model/network.lua /^function get_protocols(self)$/;" f
get_reply ./socket/tp.lua /^local function get_reply(c)$/;" f
get_status_by_address ./luci/model/network.lua /^function get_status_by_address(self, addr)$/;" f
get_status_by_route ./luci/model/network.lua /^function get_status_by_route(self, addr, mask)$/;" f
get_user_access_token ./meizu/bfs.lua /^function get_user_access_token()$/;" f
get_wan6dev ./luci/model/network.lua /^function get_wan6dev(self)$/;" f
get_wan6net ./luci/model/network.lua /^function get_wan6net(self)$/;" f
get_wan_type ./meizu/nwfs.lua /^function get_wan_type()$/;" f
get_wandev ./luci/model/network.lua /^function get_wandev(self)$/;" f
get_wannet ./luci/model/network.lua /^function get_wannet(self)$/;" f
get_wifi_settings ./meizu/nwfs.lua /^function get_wifi_settings(app_version)$/;" f
get_wifi_ssids ./meizu/nwfs.lua /^function get_wifi_ssids()$/;" f
get_wifidev ./luci/model/network.lua /^function get_wifidev(self, dev)$/;" f
get_wifidevs ./luci/model/network.lua /^function get_wifidevs(self)$/;" f
get_wifinet ./luci/model/network.lua /^function get_wifinet(self, net)$/;" f
get_wireless_channel ./meizu/nwfs.lua /^function get_wireless_channel()$/;" f
getfd ./socket.lua /^ getfd = function() return sock:getfd() end,$/;" f
getfd ./socket/http.lua /^ getfd = function() return sock:getfd() end,$/;" f
h.try ./socket/http.lua /^ h.try = socket.newtry(function() h:close() end)$/;" f
has_ipv6 ./luci/model/network.lua /^function has_ipv6(self)$/;" f
httpdispatch ./luci/dispatcher.lua /^function httpdispatch(request, prefix)$/;" f
https_get_access_token ./meizu/bfs.lua /^function https_get_access_token()$/;" f
if base.type(ok) ~ ./socket/tp.lua /^ if base.type(ok) ~= "function" then$/;" f
if c and (c.index or type(target) ./luci/dispatcher.lua /^ if c and (c.index or type(target) == "function") then$/;" f
if type(c.target) ./luci/dispatcher.lua /^ if type(c.target) == "function" then$/;" f
if type(cfg.dhparam) ~ ./ssl.lua /^ if type(cfg.dhparam) ~= "function" then$/;" f
if type(method) ./ssl/https.lua /^ if type(method) == "function" then$/;" f
if type(target) ./luci/dispatcher.lua /^ if type(target) == "function" then$/;" f
iface_delete ./luci/controller/admin/network.lua /^function iface_delete(iface)$/;" f
iface_reconnect ./luci/controller/admin/network.lua /^function iface_reconnect(iface)$/;" f
iface_shutdown ./luci/controller/admin/network.lua /^function iface_shutdown(iface)$/;" f
iface_status ./luci/controller/admin/network.lua /^function iface_status(ifaces)$/;" f
ifattr ./luci/dispatcher.lua /^ ifattr = function(...) return _ifattr(...) end;$/;" f
ifnameof ./luci/model/network.lua /^function ifnameof(self, x)$/;" f
ignore_interface ./luci/model/network.lua /^function ignore_interface(self, x)$/;" f
image_supported ./meizu/bfs.lua /^ local function image_supported()$/;" f
image_supported ./meizu/upgdfs.lua /^ local function image_supported()$/;" f
include ./luci/dispatcher.lua /^ include = function(name) tpl.Template(name):render(getfenv(2)) end;$/;" f
index ./luci/controller/admin/network.lua /^function index()$/;" f
index ./luci/controller/api/index.lua /^function index()$/;" f
index ./luci/controller/bs/index.lua /^function index()$/;" f
info ./luci/controller/bs/index.lua /^function info()$/;" f
info ./ssl.lua /^local function info(ssl, field)$/;" f
init ./luci/model/network.lua /^function init(cursor)$/;" f
initBluetoothTable ./meizu/dbfs.lua /^function initBluetoothTable()$/;" f
init_access_token_table ./meizu/dbfs.lua /^function init_access_token_table()$/;" f
init_arp_table ./meizu/dbfs.lua /^function init_arp_table()$/;" f
init_bind_router_body ./meizu/bfs.lua /^function init_bind_router_body(access_token)$/;" f
init_deny_mac_table ./meizu/dbfs.lua /^function init_deny_mac_table()$/;" f
init_ssid_dbdata ./routerReport.lua /^function init_ssid_dbdata()$/;" f
init_ssid_table ./meizu/dbfs.lua /^function init_ssid_table()$/;" f
init_update_resp_pd ./meizu/sipfs.lua /^function init_update_resp_pd(access_token, commandId, data, finishstatus, timemini)$/;" f
init_upload_router_log_pd ./meizu/sipfs.lua /^function init_upload_router_log_pd(access_token, logtype, logdata)$/;" f
insert_arp_macip ./meizu/dbfs.lua /^function insert_arp_macip(mac, ip, wifi)$/;" f
interface.__init__ ./luci/model/network.lua /^function interface.__init__(self, ifname, network)$/;" f
interface._ubus ./luci/model/network.lua /^function interface._ubus(self, field)$/;" f
interface.adminlink ./luci/model/network.lua /^function interface.adminlink(self)$/;" f
interface.bridge_id ./luci/model/network.lua /^function interface.bridge_id(self)$/;" f
interface.bridge_stp ./luci/model/network.lua /^function interface.bridge_stp(self)$/;" f
interface.get_i18n ./luci/model/network.lua /^function interface.get_i18n(self)$/;" f
interface.get_network ./luci/model/network.lua /^function interface.get_network(self)$/;" f
interface.get_networks ./luci/model/network.lua /^function interface.get_networks(self)$/;" f
interface.get_type_i18n ./luci/model/network.lua /^function interface.get_type_i18n(self)$/;" f
interface.get_wifinet ./luci/model/network.lua /^function interface.get_wifinet(self)$/;" f
interface.ip6addrs ./luci/model/network.lua /^function interface.ip6addrs(self)$/;" f
interface.ipaddrs ./luci/model/network.lua /^function interface.ipaddrs(self)$/;" f
interface.is_bridge ./luci/model/network.lua /^function interface.is_bridge(self)$/;" f
interface.is_bridgeport ./luci/model/network.lua /^function interface.is_bridgeport(self)$/;" f
interface.is_up ./luci/model/network.lua /^function interface.is_up(self)$/;" f
interface.mac ./luci/model/network.lua /^function interface.mac(self)$/;" f
interface.name ./luci/model/network.lua /^function interface.name(self)$/;" f
interface.ports ./luci/model/network.lua /^function interface.ports(self)$/;" f
interface.rx_bytes ./luci/model/network.lua /^function interface.rx_bytes(self)$/;" f
interface.rx_packets ./luci/model/network.lua /^function interface.rx_packets(self)$/;" f
interface.shortname ./luci/model/network.lua /^function interface.shortname(self)$/;" f
interface.tx_bytes ./luci/model/network.lua /^function interface.tx_bytes(self)$/;" f
interface.tx_packets ./luci/model/network.lua /^function interface.tx_packets(self)$/;" f
interface.type ./luci/model/network.lua /^function interface.type(self)$/;" f
is_del_timer_ok ./meizu/nwfs.lua /^function is_del_timer_ok(mac, timer_id)$/;" f
is_device_online ./meizu/nwfs.lua /^function is_device_online(ip)$/;" f
is_file_exist ./meizu/nwfs.lua /^function is_file_exist(TMP)$/;" f
is_receive_id ./meizu/nwfs.lua /^function is_receive_id(mac)$/;" f
is_remove_ble_from_mesh ./meizu/nwfs.lua /^function is_remove_ble_from_mesh()$/;" f
is_set_key_ok ./meizu/nwfs.lua /^function is_set_key_ok()$/;" f
is_set_name_ok ./meizu/nwfs.lua /^function is_set_name_ok(mac)$/;" f
is_set_timer_ok ./meizu/nwfs.lua /^function is_set_timer_ok(mac, timer_id)$/;" f
is_str_nil ./meizu/nwfs.lua /^function is_str_nil(str)$/;" f
is_switch_off ./meizu/nwfs.lua /^function is_switch_off(mac)$/;" f
is_switch_on ./meizu/nwfs.lua /^function is_switch_on(mac)$/;" f
is_wan_connected ./meizu/nwfs.lua /^function is_wan_connected()$/;" f
kill ./luci/sauth.lua /^function kill(id)$/;" f
lease_status ./luci/controller/admin/network.lua /^function lease_status()$/;" f
local _template ./luci/dispatcher.lua /^local _template = function(self, ...)$/;" f
local authen ./luci/dispatcher.lua /^ local authen = type(track.sysauth_authenticator) == "function"$/;" f
local checkstep ./socket/ftp.lua /^ local checkstep = function(src, snk)$/;" f
local co ./socket/smtp.lua /^ local co = coroutine.create(function() send_message(mesgt) end)$/;" f
local f ./ltn12.lua /^ local f = function(chunk, err)$/;" f
local s ./meizu/bfs.lua /^ local s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end)$/;" f
local s ./meizu/bfs.lua /^ local s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end)$/;" f
local stat, err ./luci/dispatcher.lua /^ local stat, err = util.coxpcall(function()$/;" f
local_upgrade ./meizu/upgdfs.lua /^function local_upgrade()$/;" f
log ./MZLog.lua /^function log(...)$/;" f
lower_headers ./socket/smtp.lua /^local function lower_headers(headers)$/;" f
macFormat ./meizu/nwfs.lua /^function macFormat(mac)$/;" f
make_set ./socket/url.lua /^local function make_set(t)$/;" f
metat.__index:auth ./socket/smtp.lua /^function metat.__index:auth(user, password, ext)$/;" f
metat.__index:check ./socket/tp.lua /^function metat.__index:check(ok)$/;" f
metat.__index:close ./socket/ftp.lua /^function metat.__index:close()$/;" f
metat.__index:close ./socket/http.lua /^function metat.__index:close()$/;" f
metat.__index:close ./socket/smtp.lua /^function metat.__index:close()$/;" f
metat.__index:close ./socket/tp.lua /^function metat.__index:close()$/;" f
metat.__index:command ./socket/tp.lua /^function metat.__index:command(cmd, arg)$/;" f
metat.__index:cwd ./socket/ftp.lua /^function metat.__index:cwd(dir)$/;" f
metat.__index:data ./socket/smtp.lua /^function metat.__index:data(src, step)$/;" f
metat.__index:dirty ./socket/tp.lua /^function metat.__index:dirty()$/;" f
metat.__index:getcontrol ./socket/tp.lua /^function metat.__index:getcontrol()$/;" f
metat.__index:getfd ./socket/tp.lua /^function metat.__index:getfd()$/;" f
metat.__index:greet ./socket/ftp.lua /^function metat.__index:greet()$/;" f
metat.__index:greet ./socket/smtp.lua /^function metat.__index:greet(domain)$/;" f
metat.__index:login ./socket/ftp.lua /^function metat.__index:login(user, password)$/;" f
metat.__index:login ./socket/smtp.lua /^function metat.__index:login(user, password)$/;" f
metat.__index:mail ./socket/smtp.lua /^function metat.__index:mail(from)$/;" f
metat.__index:pasv ./socket/ftp.lua /^function metat.__index:pasv()$/;" f
metat.__index:pasvconnect ./socket/ftp.lua /^function metat.__index:pasvconnect()$/;" f
metat.__index:plain ./socket/smtp.lua /^function metat.__index:plain(user, password)$/;" f
metat.__index:port ./socket/ftp.lua /^function metat.__index:port(ip, port)$/;" f
metat.__index:portconnect ./socket/ftp.lua /^function metat.__index:portconnect()$/;" f
metat.__index:quit ./socket/ftp.lua /^function metat.__index:quit()$/;" f
metat.__index:quit ./socket/smtp.lua /^function metat.__index:quit()$/;" f
metat.__index:rcpt ./socket/smtp.lua /^function metat.__index:rcpt(to)$/;" f
metat.__index:receive ./socket/ftp.lua /^function metat.__index:receive(recvt)$/;" f
metat.__index:receive ./socket/tp.lua /^function metat.__index:receive(pat)$/;" f
metat.__index:receive09body ./socket/http.lua /^function metat.__index:receive09body(status, sink, step)$/;" f
metat.__index:receivebody ./socket/http.lua /^function metat.__index:receivebody(headers, sink, step)$/;" f
metat.__index:receiveheaders ./socket/http.lua /^function metat.__index:receiveheaders()$/;" f
metat.__index:receivestatusline ./socket/http.lua /^function metat.__index:receivestatusline()$/;" f
metat.__index:send ./socket/ftp.lua /^function metat.__index:send(sendt)$/;" f
metat.__index:send ./socket/smtp.lua /^function metat.__index:send(mailt)$/;" f
metat.__index:send ./socket/tp.lua /^function metat.__index:send(data)$/;" f
metat.__index:sendbody ./socket/http.lua /^function metat.__index:sendbody(headers, source, step)$/;" f
metat.__index:sendheaders ./socket/http.lua /^function metat.__index:sendheaders(tosend)$/;" f
metat.__index:sendrequestline ./socket/http.lua /^function metat.__index:sendrequestline(method, uri)$/;" f
metat.__index:sink ./socket/tp.lua /^function metat.__index:sink(snk, pat)$/;" f
metat.__index:source ./socket/tp.lua /^function metat.__index:source(source, step)$/;" f
metat.__index:type ./socket/ftp.lua /^function metat.__index:type(type)$/;" f
modifier ./luci/dispatcher.lua /^function modifier(func, order)$/;" f
modisort ./luci/dispatcher.lua /^ local function modisort(a,b)$/;" f
netspeed_channel ./meizu/nwfs.lua /^function netspeed_channel(cmd)$/;" f
network ./luci/model/network.lua /^function network(name, proto)$/;" f
new_device_notify ./meizu/arpmon.lua /^function new_device_notify()$/;" f
newboundary ./socket/smtp.lua /^local function newboundary()$/;" f
newcontext ./ssl.lua /^function newcontext(cfg)$/;" f
noAuthGetToken ./luci/sauth.lua /^function noAuthGetToken()$/;" f
node ./luci/dispatcher.lua /^function node(...)$/;" f
node_childs ./luci/dispatcher.lua /^function node_childs(node)$/;" f
node_visible ./luci/dispatcher.lua /^function node_visible(node)$/;" f
normip ./luci/controller/bs/index.lua /^function normip()$/;" f
null ./ltn12.lua /^local function null()$/;" f
nw_add_ble_mesh_device ./meizu/nwfs.lua /^function nw_add_ble_mesh_device()$/;" f
nw_check_sys_password ./meizu/nwfs.lua /^function nw_check_sys_password()$/;" f
nw_check_upgrade ./luci/controller/api/index.lua /^function nw_check_upgrade()$/;" f
nw_del_mesh_device_timer ./meizu/nwfs.lua /^function nw_del_mesh_device_timer()$/;" f
nw_dismiss_mesh ./meizu/nwfs.lua /^function nw_dismiss_mesh()$/;" f
nw_do_upgrade ./luci/controller/api/index.lua /^function nw_do_upgrade()$/;" f
nw_exec_reboot ./luci/controller/api/index.lua /^function nw_exec_reboot()$/;" f
nw_get_ble_device_list ./meizu/nwfs.lua /^function nw_get_ble_device_list()$/;" f
nw_get_ble_device_status ./meizu/nwfs.lua /^function nw_get_ble_device_status()$/;" f
nw_get_bluetooth_info ./meizu/nwfs.lua /^function nw_get_bluetooth_info()$/;" f
nw_get_connect_device_list ./meizu/nwfs.lua /^function nw_get_connect_device_list()$/;" f
nw_get_device_details ./meizu/nwfs.lua /^function nw_get_device_details()$/;" f
nw_get_mesh_device_list ./meizu/nwfs.lua /^function nw_get_mesh_device_list()$/;" f
nw_get_wan_type ./meizu/nwfs.lua /^function nw_get_wan_type()$/;" f
nw_get_wifi_settings ./meizu/nwfs.lua /^function nw_get_wifi_settings()$/;" f
nw_get_wireless_channel ./meizu/nwfs.lua /^function nw_get_wireless_channel()$/;" f
nw_real_time_net_speed ./luci/controller/api/index.lua /^function nw_real_time_net_speed()$/;" f
nw_reboot_mesh_device ./meizu/nwfs.lua /^function nw_reboot_mesh_device()$/;" f
nw_remove_ble_from_mesh ./meizu/nwfs.lua /^function nw_remove_ble_from_mesh()$/;" f
nw_scan_ble_switch ./meizu/nwfs.lua /^function nw_scan_ble_switch()$/;" f
nw_search_router ./luci/controller/api/index.lua /^function nw_search_router()$/;" f
nw_set_bluetooth ./meizu/nwfs.lua /^function nw_set_bluetooth()$/;" f
nw_set_device_name ./meizu/nwfs.lua /^function nw_set_device_name()$/;" f
nw_set_lamp_brightness ./meizu/nwfs.lua /^function nw_set_lamp_brightness()$/;" f
nw_set_mesh_device_attr ./meizu/nwfs.lua /^function nw_set_mesh_device_attr()$/;" f
nw_set_mesh_device_timer ./meizu/nwfs.lua /^function nw_set_mesh_device_timer()$/;" f
nw_set_mesh_network_pwd ./meizu/nwfs.lua /^function nw_set_mesh_network_pwd()$/;" f
nw_set_wan_switch ./meizu/nwfs.lua /^function nw_set_wan_switch()$/;" f
nw_set_wan_type ./meizu/nwfs.lua /^function nw_set_wan_type()$/;" f
nw_set_wireless_channel ./meizu/nwfs.lua /^function nw_set_wireless_channel(channel, extch)$/;" f
nw_unmesh_all_device ./meizu/nwfs.lua /^function nw_unmesh_all_device()$/;" f
nw_wifi_settings ./meizu/nwfs.lua /^function nw_wifi_settings()$/;" f
optexec ./ssl.lua /^local function optexec(func, param, ctx)$/;" f
or (scope and type(scope[key]) ~ ./luci/dispatcher.lua /^ or (scope and type(scope[key]) ~= "function" and scope[key])$/;" f
or (type(env[key]) ~ ./luci/dispatcher.lua /^ or (type(env[key]) ~= "function" and env[key])$/;" f
override ./socket/ftp.lua /^local function override(t)$/;" f
param ./luci/controller/admin/network.lua /^ local function param(x)$/;" f
parse ./socket/ftp.lua /^local function parse(u)$/;" f
path ./socket/url.lua /^ path = string.gsub(reduced, "([^\/]*\/%.%.\/)", function (s)$/;" f
path ./socket/url.lua /^ path = string.gsub(path, "([^\/]*%.\/)", function (s)$/;" f
path ./socket/url.lua /^ path = string.gsub(reduced, "([^\/]*\/%.%.)$", function (s)$/;" f
ping_rts_server ./routerReport.lua /^function ping_rts_server()$/;" f
prepare ./luci/sauth.lua /^function prepare()$/;" f
protect_segment ./socket/url.lua /^local function protect_segment(s)$/;" f
proto.__init__ ./luci/model/network.lua /^ function proto.__init__(self, name)$/;" f
proto.proto ./luci/model/network.lua /^ function proto.proto(self)$/;" f
protocol.__init__ ./luci/model/network.lua /^function protocol.__init__(self, name)$/;" f
protocol._get ./luci/model/network.lua /^function protocol._get(self, opt)$/;" f
protocol._ubus ./luci/model/network.lua /^function protocol._ubus(self, field)$/;" f
protocol.add_interface ./luci/model/network.lua /^function protocol.add_interface(self, ifname)$/;" f
protocol.adminlink ./luci/model/network.lua /^function protocol.adminlink(self)$/;" f
protocol.contains_interface ./luci/model/network.lua /^function protocol.contains_interface(self, ifname)$/;" f
protocol.del_interface ./luci/model/network.lua /^function protocol.del_interface(self, ifname)$/;" f
protocol.dns6addrs ./luci/model/network.lua /^function protocol.dns6addrs(self)$/;" f
protocol.dnsaddrs ./luci/model/network.lua /^function protocol.dnsaddrs(self)$/;" f
protocol.expires ./luci/model/network.lua /^function protocol.expires(self)$/;" f
protocol.get ./luci/model/network.lua /^function protocol.get(self, opt)$/;" f
protocol.get_i18n ./luci/model/network.lua /^function protocol.get_i18n(self)$/;" f
protocol.get_interface ./luci/model/network.lua /^function protocol.get_interface(self)$/;" f
protocol.get_interfaces ./luci/model/network.lua /^function protocol.get_interfaces(self)$/;" f
protocol.get_option_value ./luci/model/network.lua /^function protocol.get_option_value(self,name)$/;" f
protocol.gw6addr ./luci/model/network.lua /^function protocol.gw6addr(self)$/;" f
protocol.gwaddr ./luci/model/network.lua /^function protocol.gwaddr(self)$/;" f
protocol.ifname ./luci/model/network.lua /^function protocol.ifname(self)$/;" f
protocol.ip6addr ./luci/model/network.lua /^function protocol.ip6addr(self)$/;" f
protocol.ipaddr ./luci/model/network.lua /^function protocol.ipaddr(self)$/;" f
protocol.is_bridge ./luci/model/network.lua /^function protocol.is_bridge(self)$/;" f
protocol.is_empty ./luci/model/network.lua /^function protocol.is_empty(self)$/;" f
protocol.is_floating ./luci/model/network.lua /^function protocol.is_floating(self)$/;" f
protocol.is_installed ./luci/model/network.lua /^function protocol.is_installed(self)$/;" f
protocol.is_virtual ./luci/model/network.lua /^function protocol.is_virtual(self)$/;" f
protocol.metric ./luci/model/network.lua /^function protocol.metric(self)$/;" f
protocol.name ./luci/model/network.lua /^function protocol.name(self)$/;" f
protocol.netmask ./luci/model/network.lua /^function protocol.netmask(self)$/;" f
protocol.opkg_package ./luci/model/network.lua /^function protocol.opkg_package(self)$/;" f
protocol.proto ./luci/model/network.lua /^function protocol.proto(self)$/;" f
protocol.set ./luci/model/network.lua /^function protocol.set(self, opt, val)$/;" f
protocol.status ./luci/model/network.lua /^function protocol.status(self)$/;" f
protocol.type ./luci/model/network.lua /^function protocol.type(self)$/;" f
protocol.uptime ./luci/model/network.lua /^function protocol.uptime(self)$/;" f
ptable ./luci/controller/admin/network.lua /^ local function ptable(x)$/;" f
pump.all ./ltn12.lua /^function pump.all(src, snk, step)$/;" f
pump.step ./ltn12.lua /^function pump.step(src, snk)$/;" f
push_fw_upgrading_msg ./meizu/upgdfs.lua /^function push_fw_upgrading_msg(url)$/;" f
push_new_version_msg ./meizu/upgdfs.lua /^function push_new_version_msg()$/;" f
push_upgrade_finish_msg ./meizu/upgdfs.lua /^function push_upgrade_finish_msg()$/;" f
pysip ./meizu/sipfs.lua /^function pysip()$/;" f
read ./luci/sauth.lua /^function read(id)$/;" f
real_time_net_speed ./meizu/nwfs.lua /^function real_time_net_speed()$/;" f
reap ./luci/sauth.lua /^function reap()$/;" f
reboot_mesh_device ./meizu/nwfs.lua /^function reboot_mesh_device(mac)$/;" f
receiveheaders ./socket/http.lua /^local function receiveheaders(sock, headers)$/;" f
reg ./ssl/https.lua /^local function reg(conn)$/;" f
register_pattern_virtual ./luci/model/network.lua /^function register_pattern_virtual(self, pat)$/;" f
register_protocol ./luci/model/network.lua /^function register_protocol(self, protoname)$/;" f
remove_ble_from_mesh ./meizu/nwfs.lua /^function remove_ble_from_mesh(mac)$/;" f
rename_network ./luci/model/network.lua /^function rename_network(self, old, new)$/;" f
report_rom_version ./routerReport.lua /^function report_rom_version()$/;" f
request ./ssl/https.lua /^function request(url, body)$/;" f
rewrite ./luci/dispatcher.lua /^function rewrite(n, ...)$/;" f
rts_get_access_token ./meizu/bfs.lua /^function rts_get_access_token()$/;" f
s.try ./socket/smtp.lua /^ s.try = socket.newtry(function()$/;" f
sane ./luci/sauth.lua /^function sane(file)$/;" f
save ./luci/model/network.lua /^function save(self, ...)$/;" f
saveDeviceInfo ./meizu/dbfs.lua /^function saveDeviceInfo(mac, orgname, devicename, deviceip)$/;" f
save_device_name ./meizu/nwfs.lua /^function save_device_name(mac,name)$/;" f
scan_ble_switch ./meizu/nwfs.lua /^function scan_ble_switch(status)$/;" f
send_headers ./socket/smtp.lua /^local function send_headers(tosend)$/;" f
send_message ./socket/smtp.lua /^function send_message(mesgt)$/;" f
send_multipart ./socket/smtp.lua /^local function send_multipart(mesgt)$/;" f
send_source ./socket/smtp.lua /^local function send_source(mesgt)$/;" f
send_string ./socket/smtp.lua /^local function send_string(mesgt)$/;" f
setWanDHCP ./meizu/nwfs.lua /^function setWanDHCP()$/;" f
setWanPPPoE ./meizu/nwfs.lua /^function setWanPPPoE(name, password)$/;" f
set_ap_client ./meizu/nwfs.lua /^function set_ap_client(channel, ssid, mac, sec, extch, wl_type_val, key)$/;" f
set_bluetooth ./meizu/nwfs.lua /^function set_bluetooth(id, status)$/;" f
set_device_name ./meizu/nwfs.lua /^function set_device_name(mac,devicename)$/;" f
set_lamp_brightness ./meizu/nwfs.lua /^function set_lamp_brightness()$/;" f
set_mesh_device_attr ./meizu/nwfs.lua /^function set_mesh_device_attr(mac, key, value)$/;" f
set_mesh_device_timer ./meizu/nwfs.lua /^function set_mesh_device_timer(mac, timer_id, flag, start_time, end_time)$/;" f
set_mesh_network_pwd ./meizu/nwfs.lua /^function set_mesh_network_pwd(old_key, new_key)$/;" f
set_passwd ./meizu/bfs.lua /^function set_passwd()$/;" f
set_wan_switch ./meizu/nwfs.lua /^function set_wan_switch(mac, mode, enable)$/;" f
set_wan_type ./meizu/nwfs.lua /^function set_wan_type(wan_type, pppoe_name, pppoe_pwd)$/;" f
set_wifi_basic_info ./meizu/nwfs.lua /^function set_wifi_basic_info(wifi_index, ssid, password, encryption, on)$/;" f
set_wireless_channel ./meizu/nwfs.lua /^function set_wireless_channel(channel, extch)$/;" f
sget ./socket/ftp.lua /^local function sget(u)$/;" f
shouldreceivebody ./socket/http.lua /^local function shouldreceivebody(reqt, code)$/;" f
shouldredirect ./socket/http.lua /^local function shouldredirect(reqt, code, headers)$/;" f
show_hosts ./luci/controller/bs/index.lua /^function show_hosts()$/;" f
silent_upgrade ./meizu/bfs.lua /^function silent_upgrade()$/;" f
sink.chain ./ltn12.lua /^function sink.chain(f, snk, ...)$/;" f
sink.error ./ltn12.lua /^function sink.error(err)$/;" f
sink.file ./ltn12.lua /^function sink.file(handle, io_err)$/;" f
sink.null ./ltn12.lua /^function sink.null()$/;" f
sink.simplify ./ltn12.lua /^function sink.simplify(snk)$/;" f
sink.table ./ltn12.lua /^function sink.table(t)$/;" f
sinkt["close-when-done"] ./socket.lua /^sinkt["close-when-done"] = function(sock)$/;" f
sinkt["keep-open"] ./socket.lua /^sinkt["keep-open"] = function(sock)$/;" f
sip ./meizu/sipfs.lua /^function sip()$/;" f
sip_get_parameters ./meizu/sipfs.lua /^function sip_get_parameters(commandId)$/;" f
sip_response_uploader ./meizu/sipfs.lua /^function sip_response_uploader(cmd, commandId, data, finishstatus)$/;" f
socket.sinkt["http-chunked"] ./socket/http.lua /^socket.sinkt["http-chunked"] = function(sock)$/;" f
socket.sourcet["http-chunked"] ./socket/http.lua /^socket.sourcet["http-chunked"] = function(sock, headers)$/;" f
source.cat ./ltn12.lua /^function source.cat(...)$/;" f
source.chain ./ltn12.lua /^function source.chain(src, f, ...)$/;" f
source.empty ./ltn12.lua /^function source.empty()$/;" f
source.error ./ltn12.lua /^function source.error(err)$/;" f
source.file ./ltn12.lua /^function source.file(handle, io_err)$/;" f
source.rewind ./ltn12.lua /^function source.rewind(src)$/;" f
source.simplify ./ltn12.lua /^function source.simplify(src)$/;" f
source.string ./ltn12.lua /^function source.string(s)$/;" f
sourcet["by-length"] ./socket.lua /^sourcet["by-length"] = function(sock, length)$/;" f
sourcet["until-closed"] ./socket.lua /^sourcet["until-closed"] = function(sock)$/;" f
sput ./socket/ftp.lua /^local function sput(u, body)$/;" f
srequest ./socket/http.lua /^local function srequest(u, b)$/;" f
strsplit ./meizu/bfs.lua /^function strsplit(str, delim, maxNb)$/;" f
subscribe_auto_upgrade ./meizu/upgdfs.lua /^function subscribe_auto_upgrade()$/;" f
switch_status ./luci/controller/admin/network.lua /^function switch_status(switches)$/;" f
sysinfo ./meizu/bfs.lua /^function sysinfo()$/;" f
table_merge ./meizu/bfs.lua /^function table_merge(t1, t2)$/;" f
tcp ./ssl/https.lua /^local function tcp(params)$/;" f
template ./luci/dispatcher.lua /^function template(name)$/;" f
testip ./luci/controller/bs/index.lua /^function testip()$/;" f
tget ./socket/ftp.lua /^local function tget(gett)$/;" f
token ./luci/controller/bs/index.lua /^function token()$/;" f
tput ./socket/ftp.lua /^local function tput(putt)$/;" f
type(cfg.password) ~ ./ssl.lua /^ type(cfg.password) ~= "function" and$/;" f
unbind_router ./meizu/bfs.lua /^function unbind_router()$/;" f
unmesh_all_device ./meizu/nwfs.lua /^function unmesh_all_device()$/;" f
upRouterPushId ./routerReport.lua /^function upRouterPushId()$/;" f
updateBluetoothDevice ./meizu/dbfs.lua /^function updateBluetoothDevice(id, key, name, len, mac)$/;" f
updateDeviceNickname ./meizu/dbfs.lua /^function updateDeviceNickname(mac, nickname)$/;" f
updateDeviceOrgname ./meizu/dbfs.lua /^function updateDeviceOrgname(mac, orgname)$/;" f
update_access_token ./meizu/dbfs.lua /^function update_access_token(oldToken, newToken, expireTime)$/;" f
update_arp ./meizu/dbfs.lua /^function update_arp(mac, ip, wifi)$/;" f
update_ssid ./meizu/dbfs.lua /^function update_ssid(ssid24, ssid5)$/;" f
upgrade_lock ./meizu/upgdfs.lua /^function upgrade_lock()$/;" f
upgrade_unlock ./meizu/upgdfs.lua /^function upgrade_unlock()$/;" f
upload_router_log ./meizu/sipfs.lua /^function upload_router_log(logdata, logtype)$/;" f
url ./socket/url.lua /^ url = string.gsub(url, "#(.*)$", function(f)$/;" f
url ./socket/url.lua /^ url = string.gsub(url, "%;(.*)", function(p)$/;" f
url ./socket/url.lua /^ url = string.gsub(url, "%?(.*)", function(q)$/;" f
url ./socket/url.lua /^ url = string.gsub(url, "^\/\/([^\/]*)", function(n)$/;" f
urlstring_totable ./ssl/https.lua /^local function urlstring_totable(url, body, result_table)$/;" f
ut ./routerReport.lua /^function ut()$/;" f
wanRestart ./meizu/nwfs.lua /^function wanRestart()$/;" f
wifiNetwork ./luci/controller/admin/network.lua /^function wifiNetwork(wifiDeviceName)$/;" f
wifiNetworks ./luci/controller/admin/network.lua /^function wifiNetworks()$/;" f
wifi_add ./luci/controller/admin/network.lua /^function wifi_add()$/;" f
wifi_delete ./luci/controller/admin/network.lua /^function wifi_delete(network)$/;" f
wifi_join ./luci/controller/admin/network.lua /^function wifi_join()$/;" f
wifi_network ./meizu/nwfs.lua /^function wifi_network(wifi_device_name)$/;" f
wifi_networks ./meizu/nwfs.lua /^function wifi_networks()$/;" f
wifi_reconnect ./luci/controller/admin/network.lua /^function wifi_reconnect(wnet)$/;" f
wifi_reconnect ./meizu/nwfs.lua /^function wifi_reconnect(wnet)$/;" f
wifi_reconnect_shutdown ./luci/controller/admin/network.lua /^local function wifi_reconnect_shutdown(shutdown, wnet)$/;" f
wifi_reconnect_shutdown ./meizu/nwfs.lua /^local function wifi_reconnect_shutdown(shutdown, wnet)$/;" f
wifi_settings ./meizu/nwfs.lua /^function wifi_settings(on1, ssid1, pwd1, encry1, on2, ssid2, pwd2, encry2)$/;" f
wifi_shutdown ./luci/controller/admin/network.lua /^function wifi_shutdown(wnet)$/;" f
wifi_shutdown ./meizu/nwfs.lua /^function wifi_shutdown(wnet)$/;" f
wifi_status ./luci/controller/admin/network.lua /^function wifi_status(devs)$/;" f
wifidev.__init__ ./luci/model/network.lua /^function wifidev.__init__(self, dev)$/;" f
wifidev.add_wifinet ./luci/model/network.lua /^function wifidev.add_wifinet(self, options)$/;" f
wifidev.del_wifinet ./luci/model/network.lua /^function wifidev.del_wifinet(self, net)$/;" f
wifidev.get ./luci/model/network.lua /^function wifidev.get(self, opt)$/;" f
wifidev.get_i18n ./luci/model/network.lua /^function wifidev.get_i18n(self)$/;" f
wifidev.get_wifinet ./luci/model/network.lua /^function wifidev.get_wifinet(self, net)$/;" f
wifidev.get_wifinets ./luci/model/network.lua /^function wifidev.get_wifinets(self)$/;" f
wifidev.hwmodes ./luci/model/network.lua /^function wifidev.hwmodes(self)$/;" f
wifidev.is_up ./luci/model/network.lua /^function wifidev.is_up(self)$/;" f
wifidev.name ./luci/model/network.lua /^function wifidev.name(self)$/;" f
wifidev.set ./luci/model/network.lua /^function wifidev.set(self, opt, val)$/;" f
wifinet.__init__ ./luci/model/network.lua /^function wifinet.__init__(self, net, data)$/;" f
wifinet.active_bssid ./luci/model/network.lua /^function wifinet.active_bssid(self)$/;" f
wifinet.active_encryption ./luci/model/network.lua /^function wifinet.active_encryption(self)$/;" f
wifinet.active_mode ./luci/model/network.lua /^function wifinet.active_mode(self)$/;" f
wifinet.active_mode_i18n ./luci/model/network.lua /^function wifinet.active_mode_i18n(self)$/;" f
wifinet.active_ssid ./luci/model/network.lua /^function wifinet.active_ssid(self)$/;" f
wifinet.adminlink ./luci/model/network.lua /^function wifinet.adminlink(self)$/;" f
wifinet.assoclist ./luci/model/network.lua /^function wifinet.assoclist(self)$/;" f
wifinet.bitrate ./luci/model/network.lua /^function wifinet.bitrate(self)$/;" f
wifinet.bssid ./luci/model/network.lua /^function wifinet.bssid(self)$/;" f
wifinet.channel ./luci/model/network.lua /^function wifinet.channel(self)$/;" f
wifinet.country ./luci/model/network.lua /^function wifinet.country(self)$/;" f
wifinet.frequency ./luci/model/network.lua /^function wifinet.frequency(self)$/;" f
wifinet.get ./luci/model/network.lua /^function wifinet.get(self, opt)$/;" f
wifinet.get_device ./luci/model/network.lua /^function wifinet.get_device(self)$/;" f
wifinet.get_i18n ./luci/model/network.lua /^function wifinet.get_i18n(self)$/;" f
wifinet.get_interface ./luci/model/network.lua /^function wifinet.get_interface(self)$/;" f
wifinet.get_network ./luci/model/network.lua /^function wifinet.get_network(self)$/;" f
wifinet.get_networks ./luci/model/network.lua /^function wifinet.get_networks(self)$/;" f
wifinet.id ./luci/model/network.lua /^function wifinet.id(self)$/;" f
wifinet.ifname ./luci/model/network.lua /^function wifinet.ifname(self)$/;" f
wifinet.is_up ./luci/model/network.lua /^function wifinet.is_up(self)$/;" f
wifinet.mode ./luci/model/network.lua /^function wifinet.mode(self)$/;" f
wifinet.name ./luci/model/network.lua /^function wifinet.name(self)$/;" f
wifinet.network ./luci/model/network.lua /^function wifinet.network(self)$/;" f
wifinet.noise ./luci/model/network.lua /^function wifinet.noise(self)$/;" f
wifinet.set ./luci/model/network.lua /^function wifinet.set(self, opt, val)$/;" f
wifinet.shortname ./luci/model/network.lua /^function wifinet.shortname(self)$/;" f
wifinet.signal ./luci/model/network.lua /^function wifinet.signal(self)$/;" f
wifinet.signal_level ./luci/model/network.lua /^function wifinet.signal_level(self, s, n)$/;" f
wifinet.signal_percent ./luci/model/network.lua /^function wifinet.signal_percent(self)$/;" f
wifinet.ssid ./luci/model/network.lua /^function wifinet.ssid(self)$/;" f
wifinet.txpower ./luci/model/network.lua /^function wifinet.txpower(self)$/;" f
wifinet.txpower_offset ./luci/model/network.lua /^function wifinet.txpower_offset(self)$/;" f
wrap ./ssl.lua /^function wrap(sock, cfg)$/;" f
wrapt['quoted-printable'] ./mime.lua /^wrapt['quoted-printable'] = function()$/;" f
wrapt['text'] ./mime.lua /^wrapt['text'] = function(length)$/;" f
write ./luci/sauth.lua /^function write(id, data)$/;" f
ww_add_ble_mesh_device ./meizu/nwfs.lua /^function ww_add_ble_mesh_device(mac)$/;" f
ww_del_mesh_device_timer ./meizu/nwfs.lua /^function ww_del_mesh_device_timer(mac, timer_id)$/;" f
ww_exec_reboot ./meizu/sipfs.lua /^function ww_exec_reboot(cmd, cmdid)$/;" f
ww_get_ble_device_list ./meizu/nwfs.lua /^function ww_get_ble_device_list()$/;" f
ww_get_ble_device_status ./meizu/nwfs.lua /^function ww_get_ble_device_status(mac)$/;" f
ww_get_bluetooth_info ./meizu/nwfs.lua /^function ww_get_bluetooth_info()$/;" f
ww_get_connect_device_list ./meizu/nwfs.lua /^function ww_get_connect_device_list()$/;" f
ww_get_device_details ./meizu/nwfs.lua /^function ww_get_device_details(mac)$/;" f
ww_get_mesh_device_list ./meizu/nwfs.lua /^function ww_get_mesh_device_list()$/;" f
ww_get_wan_type ./meizu/nwfs.lua /^function ww_get_wan_type()$/;" f
ww_get_wifi_settings ./meizu/nwfs.lua /^function ww_get_wifi_settings(app_version)$/;" f
ww_get_wireless_channel ./meizu/nwfs.lua /^function ww_get_wireless_channel()$/;" f
ww_reboot_mesh_device ./meizu/nwfs.lua /^function ww_reboot_mesh_device(mac)$/;" f
ww_remove_ble_from_mesh ./meizu/nwfs.lua /^function ww_remove_ble_from_mesh(mac)$/;" f
ww_scan_ble_switch ./meizu/nwfs.lua /^function ww_scan_ble_switch(status)$/;" f
ww_set_bluetooth ./meizu/nwfs.lua /^function ww_set_bluetooth()$/;" f
ww_set_lamp_brightness ./meizu/nwfs.lua /^function ww_set_lamp_brightness()$/;" f
ww_set_mesh_device_attr ./meizu/nwfs.lua /^function ww_set_mesh_device_attr(mac, key, value)$/;" f
ww_set_mesh_device_timer ./meizu/nwfs.lua /^function ww_set_mesh_device_timer(mac, timer_id, flag, start, ends)$/;" f
ww_set_mesh_network_pwd ./meizu/nwfs.lua /^function ww_set_mesh_network_pwd (old_key, new_key)$/;" f
ww_set_wireless_channel ./meizu/nwfs.lua /^function ww_set_wireless_channel(channel, extch)$/;" f
ww_unmesh_all_device ./meizu/nwfs.lua /^function ww_unmesh_all_device()$/;" f
}, {__index ./luci/dispatcher.lua /^ }, {__index=function(table, key)$/;" f

113
Mi_Lua/Posix.lua Normal file
View 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

15
Mi_Lua/bit.lua Normal file
View File

@ -0,0 +1,15 @@
--[[
nixio - Linux I/O library for lua
Copyright 2009 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$
]]--
return require "nixio".bit

BIN
Mi_Lua/cjson.so Normal file

Binary file not shown.

BIN
Mi_Lua/iproute.so Normal file

Binary file not shown.

BIN
Mi_Lua/iwinfo.so Normal file

Binary file not shown.

376
Mi_Lua/json.lua Normal file
View File

@ -0,0 +1,376 @@
-----------------------------------------------------------------------------
-- JSON4Lua: JSON encoding / decoding support for the Lua language.
-- json Module.
-- Author: Craig Mason-Jones
-- Homepage: http://json.luaforge.net/
-- Version: 0.9.40
-- This module is released under the MIT License (MIT).
-- Please see LICENCE.txt for details.
--
-- USAGE:
-- This module exposes two functions:
-- encode(o)
-- Returns the table / string / boolean / number / nil / json.null value as a JSON-encoded string.
-- decode(json_string)
-- Returns a Lua object populated with the data encoded in the JSON string json_string.
--
-- REQUIREMENTS:
-- compat-5.1 if using Lua 5.0
--
-- CHANGELOG
-- 0.9.20 Introduction of local Lua functions for private functions (removed _ function prefix).
-- Fixed Lua 5.1 compatibility issues.
-- Introduced json.null to have null values in associative arrays.
-- encode() performance improvement (more than 50%) through table.concat rather than ..
-- Introduced decode ability to ignore /**/ comments in the JSON string.
-- 0.9.10 Fix to array encoding / decoding to correctly manage nil/null values in arrays.
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Imports and dependencies
-----------------------------------------------------------------------------
local math = require('math')
local string = require("string")
local table = require("table")
local base = _G
-----------------------------------------------------------------------------
-- Module declaration
-----------------------------------------------------------------------------
module("json")
-- Public functions
-- Private functions
local decode_scanArray
local decode_scanComment
local decode_scanConstant
local decode_scanNumber
local decode_scanObject
local decode_scanString
local decode_scanWhitespace
local encodeString
local isArray
local isEncodable
-----------------------------------------------------------------------------
-- PUBLIC FUNCTIONS
-----------------------------------------------------------------------------
--- Encodes an arbitrary Lua object / variable.
-- @param v The Lua object / variable to be JSON encoded.
-- @return String containing the JSON encoding in internal Lua string format (i.e. not unicode)
function encode (v)
-- Handle nil values
if v==nil then
return "null"
end
local vtype = base.type(v)
-- Handle strings
if vtype=='string' then
return '"' .. encodeString(v) .. '"' -- Need to handle encoding in string
end
-- Handle booleans
if vtype=='number' or vtype=='boolean' then
return base.tostring(v)
end
-- Handle tables
if vtype=='table' then
local rval = {}
-- Consider arrays separately
local bArray, maxCount = isArray(v)
if bArray then
for i = 1,maxCount do
table.insert(rval, encode(v[i]))
end
else -- An object, not an array
for i,j in base.pairs(v) do
if isEncodable(i) and isEncodable(j) then
table.insert(rval, '"' .. encodeString(i) .. '":' .. encode(j))
end
end
end
if bArray then
return '[' .. table.concat(rval,',') ..']'
else
return '{' .. table.concat(rval,',') .. '}'
end
end
-- Handle null values
if vtype=='function' and v==null then
return 'null'
end
base.assert(false,'encode attempt to encode unsupported type ' .. vtype .. ':' .. base.tostring(v))
end
--- Decodes a JSON string and returns the decoded value as a Lua data structure / value.
-- @param s The string to scan.
-- @param [startPos] Optional starting position where the JSON string is located. Defaults to 1.
-- @param Lua object, number The object that was scanned, as a Lua table / string / number / boolean or nil,
-- and the position of the first character after
-- the scanned JSON object.
function decode(s, startPos)
startPos = startPos and startPos or 1
startPos = decode_scanWhitespace(s,startPos)
base.assert(startPos<=string.len(s), 'Unterminated JSON encoded object found at position in [' .. s .. ']')
local curChar = string.sub(s,startPos,startPos)
-- Object
if curChar=='{' then
return decode_scanObject(s,startPos)
end
-- Array
if curChar=='[' then
return decode_scanArray(s,startPos)
end
-- Number
if string.find("+-0123456789.e", curChar, 1, true) then
return decode_scanNumber(s,startPos)
end
-- String
if curChar==[["]] or curChar==[[']] then
return decode_scanString(s,startPos)
end
if string.sub(s,startPos,startPos+1)=='/*' then
return decode(s, decode_scanComment(s,startPos))
end
-- Otherwise, it must be a constant
return decode_scanConstant(s,startPos)
end
--- The null function allows one to specify a null value in an associative array (which is otherwise
-- discarded if you set the value with 'nil' in Lua. Simply set t = { first=json.null }
function null()
return null -- so json.null() will also return null ;-)
end
-----------------------------------------------------------------------------
-- Internal, PRIVATE functions.
-- Following a Python-like convention, I have prefixed all these 'PRIVATE'
-- functions with an underscore.
-----------------------------------------------------------------------------
--- Scans an array from JSON into a Lua object
-- startPos begins at the start of the array.
-- Returns the array and the next starting position
-- @param s The string being scanned.
-- @param startPos The starting position for the scan.
-- @return table, int The scanned array as a table, and the position of the next character to scan.
function decode_scanArray(s,startPos)
local array = {} -- The return value
local stringLen = string.len(s)
base.assert(string.sub(s,startPos,startPos)=='[','decode_scanArray called but array does not start at position ' .. startPos .. ' in string:\n'..s )
startPos = startPos + 1
-- Infinite loop for array elements
repeat
startPos = decode_scanWhitespace(s,startPos)
base.assert(startPos<=stringLen,'JSON String ended unexpectedly scanning array.')
local curChar = string.sub(s,startPos,startPos)
if (curChar==']') then
return array, startPos+1
end
if (curChar==',') then
startPos = decode_scanWhitespace(s,startPos+1)
end
base.assert(startPos<=stringLen, 'JSON String ended unexpectedly scanning array.')
object, startPos = decode(s,startPos)
table.insert(array,object)
until false
end
--- Scans a comment and discards the comment.
-- Returns the position of the next character following the comment.
-- @param string s The JSON string to scan.
-- @param int startPos The starting position of the comment
function decode_scanComment(s, startPos)
base.assert( string.sub(s,startPos,startPos+1)=='/*', "decode_scanComment called but comment does not start at position " .. startPos)
local endPos = string.find(s,'*/',startPos+2)
base.assert(endPos~=nil, "Unterminated comment in string at " .. startPos)
return endPos+2
end
--- Scans for given constants: true, false or null
-- Returns the appropriate Lua type, and the position of the next character to read.
-- @param s The string being scanned.
-- @param startPos The position in the string at which to start scanning.
-- @return object, int The object (true, false or nil) and the position at which the next character should be
-- scanned.
function decode_scanConstant(s, startPos)
local consts = { ["true"] = true, ["false"] = false, ["null"] = nil }
local constNames = {"true","false","null"}
for i,k in base.pairs(constNames) do
--print ("[" .. string.sub(s,startPos, startPos + string.len(k) -1) .."]", k)
if string.sub(s,startPos, startPos + string.len(k) -1 )==k then
return consts[k], startPos + string.len(k)
end
end
base.assert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' .. startPos)
end
--- Scans a number from the JSON encoded string.
-- (in fact, also is able to scan numeric +- eqns, which is not
-- in the JSON spec.)
-- Returns the number, and the position of the next character
-- after the number.
-- @param s The string being scanned.
-- @param startPos The position at which to start scanning.
-- @return number, int The extracted number and the position of the next character to scan.
function decode_scanNumber(s,startPos)
local endPos = startPos+1
local stringLen = string.len(s)
local acceptableChars = "+-0123456789.e"
while (string.find(acceptableChars, string.sub(s,endPos,endPos), 1, true)
and endPos<=stringLen
) do
endPos = endPos + 1
end
local stringValue = 'return ' .. string.sub(s,startPos, endPos-1)
local stringEval = base.loadstring(stringValue)
base.assert(stringEval, 'Failed to scan number [ ' .. stringValue .. '] in JSON string at position ' .. startPos .. ' : ' .. endPos)
return stringEval(), endPos
end
--- Scans a JSON object into a Lua object.
-- startPos begins at the start of the object.
-- Returns the object and the next starting position.
-- @param s The string being scanned.
-- @param startPos The starting position of the scan.
-- @return table, int The scanned object as a table and the position of the next character to scan.
function decode_scanObject(s,startPos)
local object = {}
local stringLen = string.len(s)
local key, value
base.assert(string.sub(s,startPos,startPos)=='{','decode_scanObject called but object does not start at position ' .. startPos .. ' in string:\n' .. s)
startPos = startPos + 1
repeat
startPos = decode_scanWhitespace(s,startPos)
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly while scanning object.')
local curChar = string.sub(s,startPos,startPos)
if (curChar=='}') then
return object,startPos+1
end
if (curChar==',') then
startPos = decode_scanWhitespace(s,startPos+1)
end
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly scanning object.')
-- Scan the key
key, startPos = decode(s,startPos)
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
startPos = decode_scanWhitespace(s,startPos)
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
base.assert(string.sub(s,startPos,startPos)==':','JSON object key-value assignment mal-formed at ' .. startPos)
startPos = decode_scanWhitespace(s,startPos+1)
base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
value, startPos = decode(s,startPos)
object[key]=value
until false -- infinite loop while key-value pairs are found
end
--- Scans a JSON string from the opening inverted comma or single quote to the
-- end of the string.
-- Returns the string extracted as a Lua string,
-- and the position of the next non-string character
-- (after the closing inverted comma or single quote).
-- @param s The string being scanned.
-- @param startPos The starting position of the scan.
-- @return string, int The extracted string as a Lua string, and the next character to parse.
function decode_scanString(s,startPos)
base.assert(startPos, 'decode_scanString(..) called without start position')
local startChar = string.sub(s,startPos,startPos)
base.assert(startChar==[[']] or startChar==[["]],'decode_scanString called for a non-string')
local escaped = false
local endPos = startPos + 1
local bEnded = false
local stringLen = string.len(s)
repeat
local curChar = string.sub(s,endPos,endPos)
-- Character escaping is only used to escape the string delimiters
if not escaped then
if curChar==[[\]] then
escaped = true
else
bEnded = curChar==startChar
end
else
-- If we're escaped, we accept the current character come what may
escaped = false
end
endPos = endPos + 1
base.assert(endPos <= stringLen+1, "String decoding failed: unterminated string at position " .. endPos)
until bEnded
local stringValue = 'return ' .. string.sub(s, startPos, endPos-1)
local stringEval = base.loadstring(stringValue)
base.assert(stringEval, 'Failed to load string [ ' .. stringValue .. '] in JSON4Lua.decode_scanString at position ' .. startPos .. ' : ' .. endPos)
return stringEval(), endPos
end
--- Scans a JSON string skipping all whitespace from the current start position.
-- Returns the position of the first non-whitespace character, or nil if the whole end of string is reached.
-- @param s The string being scanned
-- @param startPos The starting position where we should begin removing whitespace.
-- @return int The first position where non-whitespace was encountered, or string.len(s)+1 if the end of string
-- was reached.
function decode_scanWhitespace(s,startPos)
local whitespace=" \n\r\t"
local stringLen = string.len(s)
while ( string.find(whitespace, string.sub(s,startPos,startPos), 1, true) and startPos <= stringLen) do
startPos = startPos + 1
end
return startPos
end
--- Encodes a string to be JSON-compatible.
-- This just involves back-quoting inverted commas, back-quotes and newlines, I think ;-)
-- @param s The string to return as a JSON encoded (i.e. backquoted string)
-- @return The string appropriately escaped.
function encodeString(s)
s = string.gsub(s,'\\','\\\\')
s = string.gsub(s,'"','\\"')
s = string.gsub(s,"'","\\'")
s = string.gsub(s,'\n','\\n')
s = string.gsub(s,'\t','\\t')
return s
end
-- Determines whether the given Lua type is an array or a table / dictionary.
-- We consider any table an array if it has indexes 1..n for its n items, and no
-- other data in the table.
-- I think this method is currently a little 'flaky', but can't think of a good way around it yet...
-- @param t The table to evaluate as an array
-- @return boolean, number True if the table can be represented as an array, false otherwise. If true,
-- the second returned value is the maximum
-- number of indexed elements in the array.
function isArray(t)
-- Next we count all the elements, ensuring that any non-indexed elements are not-encodable
-- (with the possible exception of 'n')
local maxIndex = 0
for k,v in base.pairs(t) do
if (base.type(k)=='number' and math.floor(k)==k and 1<=k) then -- k,v is an indexed pair
if (not isEncodable(v)) then return false end -- All array elements must be encodable
maxIndex = math.max(maxIndex,k)
else
if (k=='n') then
if v ~= table.getn(t) then return false end -- False if n does not hold the number of elements
else -- Else of (k=='n')
if isEncodable(v) then return false end
end -- End of (k~='n')
end -- End of k,v not an indexed pair
end -- End of loop across all pairs
return true, maxIndex
end
--- Determines whether the given Lua object / table / variable can be JSON encoded. The only
-- types that are JSON encodable are: string, boolean, number, nil, table and json.null.
-- In this implementation, all other types are ignored.
-- @param o The object to examine.
-- @return boolean True if the object should be JSON encoded, false if it should be ignored.
function isEncodable(o)
local t = base.type(o)
return (t=='string' or t=='boolean' or t=='number' or t=='nil' or t=='table') or (t=='function' and o==null)
end

201
Mi_Lua/logging.lua Normal file
View File

@ -0,0 +1,201 @@
-------------------------------------------------------------------------------
-- includes a new tostring function that handles tables recursively
--
-- @author Danilo Tuler (tuler@ideais.com.br)
-- @author Andre Carregal (info@keplerproject.org)
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
--
-- @copyright 2004-2013 Kepler Project
-------------------------------------------------------------------------------
local type, table, string, _tostring, tonumber = type, table, string, tostring, tonumber
local select = select
local error = error
local format = string.format
local pairs = pairs
local ipairs = ipairs
local logging = {
-- Meta information
_COPYRIGHT = "Copyright (C) 2004-2013 Kepler Project",
_DESCRIPTION = "A simple API to use logging features in Lua",
_VERSION = "LuaLogging 1.3.0",
-- The DEBUG Level designates fine-grained instring.formational events that are most
-- useful to debug an application
DEBUG = "DEBUG",
-- The INFO level designates instring.formational messages that highlight the
-- progress of the application at coarse-grained level
INFO = "INFO",
-- The WARN level designates potentially harmful situations
WARN = "WARN",
-- The ERROR level designates error events that might still allow the
-- application to continue running
ERROR = "ERROR",
-- The FATAL level designates very severe error events that will presumably
-- lead the application to abort
FATAL = "FATAL",
}
local LEVEL = {"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
local MAX_LEVELS = #LEVEL
-- make level names to order
for i=1,MAX_LEVELS do
LEVEL[LEVEL[i]] = i
end
-- private log function, with support for formating a complex log message.
local function LOG_MSG(self, level, fmt, ...)
local f_type = type(fmt)
if f_type == 'string' then
if select('#', ...) > 0 then
return self:append(level, format(fmt, ...))
else
-- only a single string, no formating needed.
return self:append(level, fmt)
end
elseif f_type == 'function' then
-- fmt should be a callable function which returns the message to log
return self:append(level, fmt(...))
end
-- fmt is not a string and not a function, just call tostring() on it.
return self:append(level, logging.tostring(fmt))
end
-- create the proxy functions for each log level.
local LEVEL_FUNCS = {}
for i=1,MAX_LEVELS do
local level = LEVEL[i]
LEVEL_FUNCS[i] = function(self, ...)
-- no level checking needed here, this function will only be called if it's level is active.
return LOG_MSG(self, level, ...)
end
end
-- do nothing function for disabled levels.
local function disable_level() end
-- improved assertion function.
local function assert(exp, ...)
-- if exp is true, we are finished so don't do any processing of the parameters
if exp then return exp, ... end
-- assertion failed, raise error
error(format(...), 2)
end
-------------------------------------------------------------------------------
-- Creates a new logger object
-- @param append Function used by the logger to append a message with a
-- log-level to the log stream.
-- @return Table representing the new logger object.
-------------------------------------------------------------------------------
function logging.new(append)
if type(append) ~= "function" then
return nil, "Appender must be a function."
end
local logger = {}
logger.append = append
logger.setLevel = function (self, level)
local order = LEVEL[level]
assert(order, "undefined level `%s'", _tostring(level))
if self.level then
self:log(logging.WARN, "Logger: changing loglevel from %s to %s", self.level, level)
end
self.level = level
self.level_order = order
-- enable/disable levels
for i=1,MAX_LEVELS do
local name = LEVEL[i]:lower()
if i >= order then
self[name] = LEVEL_FUNCS[i]
else
self[name] = disable_level
end
end
end
-- generic log function.
logger.log = function (self, level, ...)
local order = LEVEL[level]
assert(order, "undefined level `%s'", _tostring(level))
if order < self.level_order then
return
end
return LOG_MSG(self, level, ...)
end
-- initialize log level.
logger:setLevel(logging.DEBUG)
return logger
end
-------------------------------------------------------------------------------
-- Prepares the log message
-------------------------------------------------------------------------------
function logging.prepareLogMsg(pattern, dt, level, message)
local logMsg = pattern or "%date %level %message\n"
message = string.gsub(message, "%%", "%%%%")
logMsg = string.gsub(logMsg, "%%date", dt)
logMsg = string.gsub(logMsg, "%%level", level)
logMsg = string.gsub(logMsg, "%%message", message)
return logMsg
end
-------------------------------------------------------------------------------
-- Converts a Lua value to a string
--
-- Converts Table fields in alphabetical order
-------------------------------------------------------------------------------
local function tostring(value)
local str = ''
if (type(value) ~= 'table') then
if (type(value) == 'string') then
str = string.format("%q", value)
else
str = _tostring(value)
end
else
local auxTable = {}
for key in pairs(value) do
if (tonumber(key) ~= key) then
table.insert(auxTable, key)
else
table.insert(auxTable, tostring(key))
end
end
table.sort(auxTable)
str = str..'{'
local separator = ""
local entry = ""
for _, fieldName in ipairs(auxTable) do
if ((tonumber(fieldName)) and (tonumber(fieldName) > 0)) then
entry = tostring(value[tonumber(fieldName)])
else
entry = fieldName.." = "..tostring(value[fieldName])
end
str = str..separator..entry
separator = ", "
end
str = str..'}'
end
return str
end
logging.tostring = tostring
if _VERSION ~= 'Lua 5.2' then
-- still create 'logging' global for Lua versions < 5.2
_G.logging = logging
end
return logging

View File

@ -0,0 +1,20 @@
-------------------------------------------------------------------------------
-- Prints logging information to console
--
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
--
-- @copyright 2004-2013 Kepler Project
--
-------------------------------------------------------------------------------
local logging = require"logging"
function logging.console(logPattern)
return logging.new( function(self, level, message)
io.stdout:write(logging.prepareLogMsg(logPattern, os.date(), level, message))
return true
end)
end
return logging.console

43
Mi_Lua/logging/email.lua Normal file
View File

@ -0,0 +1,43 @@
-------------------------------------------------------------------------------
-- Emails logging information to the given recipient
--
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
--
-- @copyright 2004-2013 Kepler Project
--
-------------------------------------------------------------------------------
local logging = require"logging"
local smtp = require"socket.smtp"
function logging.email(params)
params = params or {}
params.headers = params.headers or {}
if params.from == nil then
return nil, "'from' parameter is required"
end
if params.rcpt == nil then
return nil, "'rcpt' parameter is required"
end
return logging.new( function(self, level, message)
local s = logging.prepareLogMsg(params.logPattern, os.date(), level, message)
if params.headers.subject then
params.headers.subject =
logging.prepareLogMsg(params.headers.subject, os.date(), level, message)
end
local msg = { headers = params.headers, body = s }
params.source = smtp.message(msg)
local r, e = smtp.send(params)
if not r then
return nil, e
end
return true
end)
end
return logging.email

49
Mi_Lua/logging/file.lua Normal file
View File

@ -0,0 +1,49 @@
-------------------------------------------------------------------------------
-- Saves logging information in a file
--
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
--
-- @copyright 2004-2013 Kepler Project
--
-------------------------------------------------------------------------------
local logging = require"logging"
local lastFileNameDatePattern
local lastFileHandler
local openFileLogger = function (filename, datePattern)
local filename = string.format(filename, os.date(datePattern))
if (lastFileNameDatePattern ~= filename) then
local f = io.open(filename, "a")
if (f) then
f:setvbuf ("line")
lastFileNameDatePattern = filename
lastFileHandler = f
return f
else
return nil, string.format("file `%s' could not be opened for writing", filename)
end
else
return lastFileHandler
end
end
function logging.file(filename, datePattern, logPattern)
if type(filename) ~= "string" then
filename = "lualogging.log"
end
return logging.new( function(self, level, message)
local f, msg = openFileLogger(filename, datePattern)
if not f then
return nil, msg
end
local s = logging.prepareLogMsg(logPattern, os.date(), level, message)
f:write(s)
return true
end)
end
return logging.file

View File

@ -0,0 +1,79 @@
---------------------------------------------------------------------------
-- RollingFileAppender is a FileAppender that rolls over the logfile
-- once it has reached a certain size limit. It also mantains a
-- maximum number of log files.
--
-- @author Tiago Cesar Katcipis (tiagokatcipis@gmail.com)
--
-- @copyright 2004-2013 Kepler Project
---------------------------------------------------------------------------
local logging = require"logging"
local function openFile(self)
self.file = io.open(self.filename, "a")
if not self.file then
return nil, string.format("file `%s' could not be opened for writing", self.filename)
end
self.file:setvbuf ("line")
return self.file
end
local rollOver = function (self)
for i = self.maxIndex - 1, 1, -1 do
-- files may not exist yet, lets ignore the possible errors.
os.rename(self.filename.."."..i, self.filename.."."..i+1)
end
self.file:close()
self.file = nil
local _, msg = os.rename(self.filename, self.filename..".".."1")
if msg then
return nil, string.format("error %s on log rollover", msg)
end
return openFile(self)
end
local openRollingFileLogger = function (self)
if not self.file then
return openFile(self)
end
local filesize = self.file:seek("end", 0)
if (filesize < self.maxSize) then
return self.file
end
return rollOver(self)
end
function logging.rolling_file(filename, maxFileSize, maxBackupIndex, logPattern)
if type(filename) ~= "string" then
filename = "lualogging.log"
end
local obj = {
filename = filename,
maxSize = maxFileSize,
maxIndex = maxBackupIndex or 1
}
return logging.new( function(self, level, message)
local f, msg = openRollingFileLogger(obj)
if not f then
return nil, msg
end
local s = logging.prepareLogMsg(logPattern, os.date(), level, message)
f:write(s)
return true
end)
end
return logging.rolling_file

33
Mi_Lua/logging/socket.lua Normal file
View File

@ -0,0 +1,33 @@
-------------------------------------------------------------------------------
-- Sends the logging information through a socket using luasocket
--
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
--
-- @copyright 2004-2013 Kepler Project
--
-------------------------------------------------------------------------------
local logging = require"logging"
local socket = require"socket"
function logging.socket(address, port, logPattern)
return logging.new( function(self, level, message)
local s = logging.prepareLogMsg(logPattern, os.date(), level, message)
local socket, err = socket.connect(address, port)
if not socket then
return nil, err
end
local cond, err = socket:send(s)
if not cond then
return nil, err
end
socket:close()
return true
end)
end
return logging.socket

62
Mi_Lua/logging/sql.lua Normal file
View File

@ -0,0 +1,62 @@
-------------------------------------------------------------------------------
-- Saves the logging information in a table using luasql
--
-- @author Thiago Costa Ponte (thiago@ideais.com.br)
--
-- @copyright 2004-2013 Kepler Project
--
-------------------------------------------------------------------------------
local logging = require"logging"
function logging.sql(params)
params = params or {}
params.tablename = params.tablename or "LogTable"
params.logdatefield = params.logdatefield or "LogDate"
params.loglevelfield = params.loglevelfield or "LogLevel"
params.logmessagefield = params.logmessagefield or "LogMessage"
if params.connectionfactory == nil or type(params.connectionfactory) ~= "function" then
return nil, "No specified connection factory function"
end
local con, err
if params.keepalive then
con, err = params.connectionfactory()
end
return logging.new( function(self, level, message)
if (not params.keepalive) or (con == nil) then
con, err = params.connectionfactory()
if not con then
return nil, err
end
end
local logDate = os.date("%Y-%m-%d %H:%M:%S")
local insert = string.format("INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s')",
params.tablename, params.logdatefield, params.loglevelfield,
params.logmessagefield, logDate, level, string.gsub(message, "'", "''"))
local ret, err = pcall(con.execute, con, insert)
if not ret then
con, err = params.connectionfactory()
if not con then
return nil, err
end
ret, err = con:execute(insert)
if not ret then
return nil, err
end
end
if not params.keepalive then
con:close()
end
return true
end)
end
return logging.sql

BIN
Mi_Lua/lsqlite3.so Normal file

Binary file not shown.

292
Mi_Lua/ltn12.lua Normal file
View File

@ -0,0 +1,292 @@
-----------------------------------------------------------------------------
-- LTN12 - Filters, sources, sinks and pumps.
-- LuaSocket toolkit.
-- Author: Diego Nehab
-- RCS ID: $Id: ltn12.lua,v 1.31 2006/04/03 04:45:42 diego Exp $
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Declare module
-----------------------------------------------------------------------------
local string = require("string")
local table = require("table")
local base = _G
module("ltn12")
filter = {}
source = {}
sink = {}
pump = {}
-- 2048 seems to be better in windows...
BLOCKSIZE = 2048
_VERSION = "LTN12 1.0.1"
-----------------------------------------------------------------------------
-- 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 n = table.getn(arg)
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(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+BLOCKSIZE-1)
i = i + 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
function source.chain(src, f)
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 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 a filter
function sink.chain(f, snk)
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

View File

@ -0,0 +1,23 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
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$
]]--
local config = require "luci.config"
local ccache = require "luci.ccache"
module "luci.cacheloader"
if config.ccache and config.ccache.enable == "1" then
ccache.cache_ondemand()
end

1850
Mi_Lua/luci/cbi.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,345 @@
--[[
LuCI - Configuration Bind Interface - Datatype Tests
(c) 2010 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
$Id: datatypes.lua 9352 2012-10-06 23:50:52Z jow $
]]--
local fs = require "nixio.fs"
local ip = require "luci.ip"
local math = require "math"
local util = require "luci.util"
local tonumber, tostring, type, unpack, select = tonumber, tostring, type, unpack, select
module "luci.cbi.datatypes"
_M['or'] = function(v, ...)
local i
for i = 1, select('#', ...), 2 do
local f = select(i, ...)
local a = select(i+1, ...)
if type(f) ~= "function" then
if f == v then
return true
end
i = i - 1
elseif f(v, unpack(a)) then
return true
end
end
return false
end
_M['and'] = function(v, ...)
local i
for i = 1, select('#', ...), 2 do
local f = select(i, ...)
local a = select(i+1, ...)
if type(f) ~= "function" then
if f ~= v then
return false
end
i = i - 1
elseif not f(v, unpack(a)) then
return false
end
end
return true
end
function neg(v, ...)
return _M['or'](v:gsub("^%s*!%s*", ""), ...)
end
function list(v, subvalidator, subargs)
if type(subvalidator) ~= "function" then
return false
end
local token
for token in v:gmatch("%S+") do
if not subvalidator(token, unpack(subargs)) then
return false
end
end
return true
end
function bool(val)
if val == "1" or val == "yes" or val == "on" or val == "true" then
return true
elseif val == "0" or val == "no" or val == "off" or val == "false" then
return true
elseif val == "" or val == nil then
return true
end
return false
end
function uinteger(val)
local n = tonumber(val)
if n ~= nil and math.floor(n) == n and n >= 0 then
return true
end
return false
end
function integer(val)
local n = tonumber(val)
if n ~= nil and math.floor(n) == n then
return true
end
return false
end
function ufloat(val)
local n = tonumber(val)
return ( n ~= nil and n >= 0 )
end
function float(val)
return ( tonumber(val) ~= nil )
end
function ipaddr(val)
return ip4addr(val) or ip6addr(val)
end
function ip4addr(val)
if val then
return ip.IPv4(val) and true or false
end
return false
end
function ip4prefix(val)
val = tonumber(val)
return ( val and val >= 0 and val <= 32 )
end
function ip6addr(val)
if val then
return ip.IPv6(val) and true or false
end
return false
end
function ip6prefix(val)
val = tonumber(val)
return ( val and val >= 0 and val <= 128 )
end
function port(val)
val = tonumber(val)
return ( val and val >= 0 and val <= 65535 )
end
function portrange(val)
local p1, p2 = val:match("^(%d+)%-(%d+)$")
if p1 and p2 and port(p1) and port(p2) then
return true
else
return port(val)
end
end
function macaddr(val)
if val and val:match(
"^[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+:" ..
"[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+$"
) then
local parts = util.split( val, ":" )
for i = 1,6 do
parts[i] = tonumber( parts[i], 16 )
if parts[i] < 0 or parts[i] > 255 then
return false
end
end
return true
end
return false
end
function hostname(val)
if val and (#val < 254) and (
val:match("^[a-zA-Z_]+$") or
(val:match("^[a-zA-Z0-9_][a-zA-Z0-9_%-%.]*[a-zA-Z0-9]$") and
val:match("[^0-9%.]"))
) then
return true
end
return false
end
function host(val)
return hostname(val) or ipaddr(val)
end
function network(val)
return uciname(val) or host(val)
end
function wpakey(val)
if #val == 64 then
return (val:match("^[a-fA-F0-9]+$") ~= nil)
else
return (#val >= 8) and (#val <= 63)
end
end
function wepkey(val)
if val:sub(1, 2) == "s:" then
val = val:sub(3)
end
if (#val == 10) or (#val == 26) then
return (val:match("^[a-fA-F0-9]+$") ~= nil)
else
return (#val == 5) or (#val == 13)
end
end
function string(val)
return true -- Everything qualifies as valid string
end
function directory( val, seen )
local s = fs.stat(val)
seen = seen or { }
if s and not seen[s.ino] then
seen[s.ino] = true
if s.type == "dir" then
return true
elseif s.type == "lnk" then
return directory( fs.readlink(val), seen )
end
end
return false
end
function file( val, seen )
local s = fs.stat(val)
seen = seen or { }
if s and not seen[s.ino] then
seen[s.ino] = true
if s.type == "reg" then
return true
elseif s.type == "lnk" then
return file( fs.readlink(val), seen )
end
end
return false
end
function device( val, seen )
local s = fs.stat(val)
seen = seen or { }
if s and not seen[s.ino] then
seen[s.ino] = true
if s.type == "chr" or s.type == "blk" then
return true
elseif s.type == "lnk" then
return device( fs.readlink(val), seen )
end
end
return false
end
function uciname(val)
return (val:match("^[a-zA-Z0-9_]+$") ~= nil)
end
function range(val, min, max)
val = tonumber(val)
min = tonumber(min)
max = tonumber(max)
if val ~= nil and min ~= nil and max ~= nil then
return ((val >= min) and (val <= max))
end
return false
end
function min(val, min)
val = tonumber(val)
min = tonumber(min)
if val ~= nil and min ~= nil then
return (val >= min)
end
return false
end
function max(val, max)
val = tonumber(val)
max = tonumber(max)
if val ~= nil and max ~= nil then
return (val <= max)
end
return false
end
function rangelength(val, min, max)
val = tostring(val)
min = tonumber(min)
max = tonumber(max)
if val ~= nil and min ~= nil and max ~= nil then
return ((#val >= min) and (#val <= max))
end
return false
end
function minlength(val, min)
val = tostring(val)
min = tonumber(min)
if val ~= nil and min ~= nil then
return (#val >= min)
end
return false
end
function maxlength(val, max)
val = tostring(val)
max = tonumber(max)
if val ~= nil and max ~= nil then
return (#val <= max)
end
return false
end
function phonedigit(val)
return (val:match("^[0-9\*#]+$") ~= nil)
end

87
Mi_Lua/luci/ccache.lua Normal file
View File

@ -0,0 +1,87 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
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$
]]--
local io = require "io"
local fs = require "nixio.fs"
local util = require "luci.util"
local nixio = require "nixio"
local debug = require "debug"
local string = require "string"
local package = require "package"
local type, loadfile = type, loadfile
module "luci.ccache"
function cache_ondemand(...)
if debug.getinfo(1, 'S').source ~= "=?" then
cache_enable(...)
end
end
function cache_enable(cachepath, mode)
cachepath = cachepath or "/tmp/luci-modulecache"
mode = mode or "r--r--r--"
local loader = package.loaders[2]
local uid = nixio.getuid()
if not fs.stat(cachepath) then
fs.mkdir(cachepath)
end
local function _encode_filename(name)
local encoded = ""
for i=1, #name do
encoded = encoded .. ("%2X" % string.byte(name, i))
end
return encoded
end
local function _load_sane(file)
local stat = fs.stat(file)
if stat and stat.uid == uid and stat.modestr == mode then
return loadfile(file)
end
end
local function _write_sane(file, func)
if nixio.getuid() == uid then
local fp = io.open(file, "w")
if fp then
fp:write(util.get_bytecode(func))
fp:close()
fs.chmod(file, mode)
end
end
end
package.loaders[2] = function(mod)
local encoded = cachepath .. "/" .. _encode_filename(mod)
local modcons = _load_sane(encoded)
if modcons then
return modcons
end
-- No cachefile
modcons = loader(mod)
if type(modcons) == "function" then
_write_sane(encoded, modcons)
end
return modcons
end
end

42
Mi_Lua/luci/config.lua Normal file
View File

@ -0,0 +1,42 @@
--[[
LuCI - Configuration
Description:
Some LuCI configuration values read from uci file "luci"
FileId:
$Id: config.lua 3856 2008-12-05 15:36:44Z Cyrus $
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.
]]--
local util = require "luci.util"
module("luci.config",
function(m)
if pcall(require, "luci.model.uci") then
local config = util.threadlocal()
setmetatable(m, {
__index = function(tbl, key)
if not config[key] then
config[key] = luci.model.uci.cursor():get_all("luci", key)
end
return config[key]
end
})
end
end)

View File

@ -0,0 +1,10 @@
module("luci.controller.api.index", package.seeall)
function index()
local page = node("api")
page.target = firstchild()
page.title = _("")
page.order = 10
page.sysauth = "admin"
page.sysauth_authenticator = "jsonauth"
page.index = true
end

View File

@ -0,0 +1,336 @@
module("luci.controller.api.xqdatacenter", package.seeall)
function index()
local page = node("api","xqdatacenter")
page.target = firstchild()
page.title = ("")
page.order = 300
page.sysauth = "admin"
page.sysauth_authenticator = "jsonauth"
page.index = true
entry({"api", "xqdatacenter"}, firstchild(), _(""), 300)
entry({"api", "xqdatacenter", "request"}, call("tunnelRequest"), _(""), 301)
entry({"api", "xqdatacenter", "identify_device"}, call("identifyDevice"), _(""), 302, 0x08)
entry({"api", "xqdatacenter", "download"}, call("download"), _(""), 303)
entry({"api", "xqdatacenter", "upload"}, call("upload"), _(""), 304)
entry({"api", "xqdatacenter", "thumb"}, call("getThumb"), _(""), 305)
entry({"api", "xqdatacenter", "device_id"}, call("getDeviceId"), _(""), 306)
entry({"api", "xqdatacenter", "check_file_exist"}, call("checkFileExist"), _(""), 307)
entry({"api", "xqdatacenter", "plugin_ssh"}, call("pluginSSH"), _(""), 308)
entry({"api", "xqdatacenter", "plugin_ssh_status"}, call("pluginSSHStatus"), _(""), 309)
end
local LuciHttp = require("luci.http")
local LuciJson = require("json")
local XQConfigs = require("xiaoqiang.common.XQConfigs")
local XQFunction = require("xiaoqiang.common.XQFunction")
local XQErrorUtil = require("xiaoqiang.util.XQErrorUtil")
function tunnelRequest()
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
local payload = XQCryptoUtil.binaryBase64Enc(LuciHttp.formvalue("payload"))
local cmd = XQConfigs.THRIFT_TUNNEL_TO_DATACENTER % payload
local LuciUtil = require("luci.util")
LuciHttp.write(LuciUtil.exec(cmd))
end
function identifyDevice()
local cmd = XQConfigs.THRIFT_TO_MQTT_IDENTIFY_DEVICE
local LuciUtil = require("luci.util")
local result = {}
result["code"] = 0
result["info"] = LuciUtil.exec(cmd)
LuciHttp.write_json(result)
end
function getDeviceId()
local cmd = XQConfigs.THRIFT_TO_MQTT_GET_DEVICEID
local LuciUtil = require("luci.util")
local result = {}
result["code"] = 0
result["deviceId"] = LuciUtil.exec(cmd)
LuciHttp.write_json(result)
end
function download()
local fs = require("nixio.fs")
local mime = require("luci.http.protocol.mime")
local ltn12 = require("luci.ltn12")
local log = require("xiaoqiang.XQLog")
local path = LuciHttp.formvalue("path")
if XQFunction.isStrNil(path) then
LuciHttp.status(404, _("no Such file"))
return
end
local constPrefix1 = "/userdisk/data/"
local constPrefix2 = "/extdisks/"
local constPrefix3 = "/userdisk/privacyData/"
if (string.sub(path, 1, string.len(constPrefix1)) ~= constPrefix1) and (string.sub(path, 1, string.len(constPrefix2)) ~= constPrefix2) and (string.sub(path, 1, string.len(constPrefix3)) ~= constPrefix3) then
LuciHttp.status(403, _("no permission"))
return
end
-- check privacy disk permission by md5 device mac address
--[[if string.sub(path, 1, string.len(constPrefix3)) == constPrefix3 then
local secret = LuciHttp.formvalue("secret")
if XQFunction.isStrNil(secret) then
LuciHttp.status(403, _("no permission"))
return
end
log.log(3, "=============secret = " .. secret)
local access = false
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
local XQDeviceUtil = require("xiaoqiang.util.XQDeviceUtil")
local macfilterInfoList = XQDeviceUtil.getMacfilterInfoList()
for _,value in ipairs(macfilterInfoList) do
if XQFunction.isStrNil(value.mac) == false then
log.log(3, "=============mac = " .. value.mac)
if string.lower(XQCryptoUtil.md5Str(string.lower(value.mac))) == string.lower(secret) then
log.log(3, "=============device found")
if value.pridisk then
access = true
end
break
end
end
end
if access == false then
LuciHttp.status(403, _("no permission"))
return
end
end]]
log.log(3, "=============path = " .. path)
local stat = fs.stat(path)
if not stat then
LuciHttp.status(404, _("no Such file"))
return
end
LuciHttp.header("Accept-Ranges", "bytes")
LuciHttp.header("Content-Type", mime.to_mime(path))
local range = LuciHttp.getenv("HTTP_RANGE")
-- format: bytes=123-
if range then
LuciHttp.status(206)
range = string.gsub(range, "bytes=", "")
range = string.gsub(range, "-", "")
else
range = 0
end
log.log(3, "=============range = " .. range)
-- format: bytes 123-456/457
local contentRange = "bytes " .. range .. "-" .. (stat.size - 1) .. "/" .. stat.size
log.log(3, "=============contentRange = " .. contentRange)
LuciHttp.header("Content-Length", stat.size - range)
LuciHttp.header("Content-Range", contentRange)
LuciHttp.header("Content-Disposition", "attachment; filename=" .. fs.basename(path))
if string.sub(path, 1, string.len(constPrefix1)) == constPrefix1 then
LuciHttp.header("X-Accel-Redirect", "/download-userdisk/" .. string.sub(path, string.len(constPrefix1) + 1, string.len(path)))
elseif string.sub(path, 1, string.len(constPrefix2)) == constPrefix2 then
LuciHttp.header("X-Accel-Redirect", "/download-extdisks/" .. string.sub(path, string.len(constPrefix2) + 1, string.len(path)))
elseif string.sub(path, 1, string.len(constPrefix3)) == constPrefix3 then
LuciHttp.header("X-Accel-Redirect", "/download-pridisk/" .. string.sub(path, string.len(constPrefix3) + 1, string.len(path)))
end
--local file = io.open(path, "r")
--local position = file:seek("set", range)
--log.log(3, "=============position = " .. position)
--ltn12.pump.all(ltn12.source.file(file), LuciHttp.write)
end
function upload()
local fp
local log = require("xiaoqiang.XQLog")
local fs = require("luci.fs")
local tmpfile = "/userdisk/upload.tmp"
if fs.isfile(tmpfile) then
fs.unlink(tmpfile)
end
local filename
LuciHttp.setfilehandler(
function(meta, chunk, eof)
if not fp then
if meta and meta.name == "file" then
fp = io.open(tmpfile, "w")
filename = meta.file
filename = string.gsub(filename, "+", " ")
filename = string.gsub(filename, "%%(%x%x)",
function(h)
return string.char(tonumber(h, 16))
end)
filename = filename.gsub(filename, "\r\n", "\n")
end
end
if chunk then
fp:write(chunk)
end
if eof then
fp:close()
end
end
)
local path = LuciHttp.formvalue("target")
if string.match(path, "\/$") == nil then
path = path .. "/"
end
fs.mkdir(path, true)
local savename = filename
if fs.isfile(path .. savename) then
local basename = savename
local index = basename:match(".+()%.%w+$")
if index then
basename = basename:sub(1, index - 1)
end
local extension = savename:match(".+%.(%w+)$")
for i = 1, 100, 1 do
local tmpname = basename .. "(" .. i .. ")"
if extension then
tmpname = tmpname .. "." .. extension
end
if not fs.isfile(path .. tmpname) then
savename = tmpname
break
end
end
end
local dest = path .. savename
log.log(3, "dest=" .. dest)
fs.rename(tmpfile, dest)
local result = {}
result["code"] = 0
LuciHttp.write_json(result)
end
function getThumb()
local LuciUtil = require("luci.util")
local fs = require("nixio.fs")
local mime = require("luci.http.protocol.mime")
local ltn12 = require("luci.ltn12")
local log = require("xiaoqiang.XQLog")
local realPath = LuciHttp.formvalue("filePath")
log.log(3, "realPath = ", realPath)
if (realPath == nil) then
LuciHttp.status(404, _("no Such file"))
return
end
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
local payload = "{\"api\":10, \"files\":[\"" ..realPath.. "\"]}"
local thumbResponse = XQFunction.thrift_tunnel_to_datacenter(payload)
if thumbResponse and thumbResponse.code == 0 then
local thumbPath = thumbResponse.thumbnails[1]
local stat = fs.stat(thumbPath)
LuciHttp.header("Content-Type", mime.to_mime(thumbPath))
LuciHttp.header("Content-Length", stat.size)
ltn12.pump.all(ltn12.source.file(io.open(thumbPath, "r")), LuciHttp.write)
else
LuciHttp.status(404, _("no Such thumb file"))
end
end
function checkFileExist()
local fs = require("nixio.fs")
local exist = true
local path = LuciHttp.formvalue("filePath")
if XQFunction.isStrNil(path) then
exist = false
else
local stat = fs.stat(path)
if not stat then
exist = false
end
end
local result = {}
result["code"] = 0
result['exist'] = exist
LuciHttp.write_json(result)
end
function pluginSSH()
local LuciUtil = require("luci.util")
local XQLog = require("xiaoqiang.XQLog")
local code = 0
local result = {}
local pluginID = LuciHttp.formvalue("pluginID")
local capabilitystr = LuciHttp.formvalue("capability")
local open = tonumber(LuciHttp.formvalue("open") or 0)
XQLog.check(0, XQLog.KEY_FUNC_PLUGIN, 1)
if open and open == 1 then
if pluginID and capabilitystr then
local payload = {
["api"] = 611,
["pluginID"] = pluginID,
["capability"] = LuciUtil.split(capabilitystr, ",")
}
local datacenter = XQFunction.thrift_tunnel_to_datacenter(LuciJson.encode(payload))
if datacenter and datacenter.code ~= 0 then
code = 1595
end
else
code = 1537
end
else
local payload = {
["api"] = 613
}
local datacenter = XQFunction.thrift_tunnel_to_datacenter(LuciJson.encode(payload))
if datacenter and datacenter.code == 0 then
code = 0
else
code = 1601
end
end
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
end
result["code"] = code
LuciHttp.write_json(result)
end
function pluginSSHStatus()
local code = 0
local result = {}
local datacenter = XQFunction.thrift_tunnel_to_datacenter([[{"api":612}]])
local capability = XQFunction.thrift_tunnel_to_datacenter([[{"api":621}]])
if datacenter and datacenter.code == 0 and capability and datacenter.code == 0 then
local capabilitylist = {}
result["enable"] = datacenter.status == 1 and 1 or 0
local encapability = {}
if result.enable == 1 then
local pluginSSH = datacenter.plugin_ssh_status
result["pluginID"] = pluginSSH.pluginID
encapability = pluginSSH.capability
end
for _, item in ipairs(capability.list) do
item.enable = 0
for _, capa in ipairs(encapability) do
if item.key == capa then
item.enable = 1
break
end
end
table.insert(capabilitylist, item)
end
result["capability"] = capabilitylist
else
code = 1600
end
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
end
result["code"] = code
LuciHttp.write_json(result)
end

View File

@ -0,0 +1,293 @@
module("luci.controller.api.xqnetdetect", package.seeall)
function index()
local page = node("api","xqnetdetect")
page.target = firstchild()
page.title = ("")
page.order = 350
page.sysauth = "admin"
page.sysauth_authenticator = "jsonauth"
page.index = true
entry({"api", "xqnetdetect"}, firstchild(), _(""), 350)
entry({"api", "xqnetdetect", "wan_status"}, call("getWanStatus"), _(""), 351, 0x01)
entry({"api", "xqnetdetect", "sys_info"}, call("getSysInfo"), (""), 352, 0x01)
entry({"api", "xqnetdetect", "ping_test"}, call("pingTest"), (""), 353, 0x01)
entry({"api", "xqnetdetect", "detect"}, call("systemDiagnostics"), (""), 354, 0x01)
entry({"api", "xqnetdetect", "sys_status"}, call("systemStatus"), (""), 355, 0x01)
entry({"api", "xqnetdetect", "netspeed"}, call("netspeed"), (""), 356)
entry({"api", "xqnetdetect", "uploadspeed"}, call("uploadSpeed"), (""), 357)
end
local LuciHttp = require("luci.http")
local XQFunction = require("xiaoqiang.common.XQFunction")
local XQErrorUtil = require("xiaoqiang.util.XQErrorUtil")
function getWanStatus()
local XQLanWanUtil = require("xiaoqiang.util.XQLanWanUtil")
local result = {}
local wanType = XQLanWanUtil.getAutoWanType()
local wanInfo = XQLanWanUtil.getLanWanInfo("wan")
local wanMonitor = XQLanWanUtil.getWanMonitorStat()
result["code"] = 0
result["wanLink"] = wanType == 99 and 0 or 1
result["wanType"] = wanType
result["wanInfo"] = wanInfo
result["wanMonitor"] = wanMonitor
LuciHttp.write_json(result)
end
function getSysInfo()
local LuciSys = require("luci.sys")
local result = {}
local cpu = {}
local mem = {}
local system, model, memtotal, memcached, membuffers, memfree, bogomips = LuciSys.sysinfo()
cpu["info"] = system
mem["total"] = memtotal
mem["free"] = memfree
result["code"] = 0
result["cpuInfo"] = cpu
result["memInfo"] = mem
LuciHttp.write_json(result)
end
function pingTest()
local LuciSys = require("luci.sys")
local pingUrl = LuciHttp.formvalue("url")
local ping = LuciSys.net.pingtest(pingUrl)
local result = {}
result["code"] = 0
result["result"] = ping == 0 and 1 or 0
LuciHttp.write_json(result)
end
--[[
simple : 0/1/2 (,log/,,log/,,log)
]]--
function systemDiagnostics()
local XQLog = require("xiaoqiang.XQLog")
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
local XQSecureUtil = require("xiaoqiang.util.XQSecureUtil")
local XQWifiUtil = require("xiaoqiang.util.XQWifiUtil")
local XQDeviceUtil = require("xiaoqiang.util.XQDeviceUtil")
local lan = XQDeviceUtil.getWanLanNetworkStatistics("lan")
local wan = XQDeviceUtil.getWanLanNetworkStatistics("wan")
local speed = {}
speed["lan"] = tonumber(lan.downspeed)
speed["wan"] = tonumber(wan.downspeed)
local simple = tonumber(LuciHttp.formvalue("simple") or 0)
local target = LuciHttp.formvalue("target")
local result = {}
local code = 0
local status = 0
local count = 0
local cpuTemperature = XQSysUtil.getCpuTemperature()
local network = XQSysUtil.getNetworkDetectInfo(simple,target)
XQSysUtil.setDetectionTimestamp()
local wifiInfo = XQWifiUtil.getAllWifiInfo()
local same = false
local strong = true
local wifi = {}
for i=1, #wifiInfo do
if XQSecureUtil.checkPlaintextPwd("admin", wifiInfo[i].password) then
same = true
end
if XQSecureUtil.checkStrong(wifiInfo[i].password) < 2 then
strong = false
end
end
wifi["same"] = same and 1 or 0
wifi["strong"] = strong and 1 or 0
local disk = {}
local diskinfo = XQFunction.thrift_tunnel_to_datacenter([[{"api":26}]])
if diskinfo and diskinfo.code == 0 then
local capacity = tonumber(diskinfo.capacity)
local free = tonumber(diskinfo.free)
disk["Used"] = string.format("%.3fG", (capacity - free)/1073741824)
disk["Available"] = string.format("%.3fG", free/1073741824)
end
if network then
local cputemp = {}
cputemp["temperature"] = cpuTemperature
if cpuTemperature > 70 then
count = count + 1
status = 1
cputemp["status"] = 0
else
cputemp["status"] = 1
end
local cpuavg = {}
cpuavg["loadavg"] = network.cpu
if tonumber(network.cpu) > 90 then
count = count + 1
status = 1
cpuavg["status"] = 0
else
cpuavg["status"] = 1
end
local memoryuse = {}
memoryuse["use"] = network.memory
if tonumber(network.memory) > 90 then
count = count + 1
status = 1
memoryuse["status"] = 0
else
memoryuse["status"] = 1
end
local link = {}
if network.wanLink ~= 1 then
count = count + 1
status = 2
link["status"] = 0
else
link["status"] = 1
end
local wan = {}
wan["type"] = network.wanType
if tonumber(network.wanLink) ~= 1 then
count = count + 1
status = 2
wan["status"] = 0
else
wan["status"] = 1
end
local gateway = {}
gateway["lost"] = network.gw
if tonumber(network.gw) > 80 then
count = count + 1
status = 1
gateway["status"] = 0
else
gateway["status"] = 1
end
local dnsstatus = {}
if tonumber(network.dns) ~= 1 then
count = count + 1
status = 2
dnsstatus["status"] = 0
else
dnsstatus["status"] = 1
end
local ping = {}
ping["lost"] = network.pingLost
if tonumber(network.pingLost) > 80 then
count = count + 1
status = 2
ping["status"] = 0
else
ping["status"] = 1
end
result = network
result["count"] = count
result["status"] = status
result["cpuavg"] = cpuavg
result["memoryuse"] = memoryuse
result["cputemp"] = cputemp
result["link"] = link
result["wan"] = wan
result["gateway"] = gateway
result["dnsstatus"] = dnsstatus
result["ping"] = ping
result["cpuTemperature"] = cpuTemperature
result["wifi"] = wifi
result["speed"] = speed
result["disk"] = disk
if count > 0 then
XQLog.check(0, XQLog.KEY_DETECT_ERROR, 1)
end
else
code = 1567
end
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
else
local XQPushHelper = require("xiaoqiang.XQPushHelper")
local LuciJson = require("json")
local payload = {
["type"] = 6,
["data"] = {
["lan"] = speed.lan,
["wan"] = speed.wan
}
}
XQPushHelper.push_request(LuciJson.encode(payload))
end
result["code"] = code
LuciHttp.write_json(result)
end
function systemStatus()
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
local count = 0
local result = {}
local status = XQSysUtil.checkSystemStatus()
result["code"] = 0
result["status"] = 0
if (status.cpu and status.cpu > 90) then
count = count + 1
result["status"] = 1
end
if (status.mem and status.mem > 90) then
count = count + 1
result["status"] = 1
end
if (status.tmp and status.tmp > 70) then
count = count + 1
result["status"] = 1
end
if not status.wan or not status.link then
count = count + 1
result["status"] = 2
end
result["count"] = count
LuciHttp.write_json(result)
end
function netspeed()
local XQPreference = require("xiaoqiang.XQPreference")
local XQNSTUtil = require("xiaoqiang.module.XQNetworkSpeedTest")
local code = 0
local result = {}
local history = LuciHttp.formvalue("history")
if history then
result["bandwidth"] = tonumber(XQPreference.get("BANDWIDTH", 0, "xiaoqiang"))
result["download"] = tonumber(string.format("%.2f", 128 * result.bandwidth))
else
local download = XQNSTUtil.downloadSpeedTest()
if download then
result["download"] = download
result["bandwidth"] = tonumber(string.format("%.2f", 8 * download/1024))
XQPreference.set("BANDWIDTH", tostring(result.bandwidth), "xiaoqiang")
else
code = 1588
end
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
end
end
result["code"] = code
LuciHttp.write_json(result)
end
function uploadSpeed()
local XQNSTUtil = require("xiaoqiang.module.XQNetworkSpeedTest")
local code = 0
local result = {}
local upload = XQNSTUtil.uploadSpeedTest()
if upload then
result["upload"] = upload
result["bandwidth"] = tonumber(string.format("%.2f", 8 * upload/1024))
else
code = 1588
end
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
end
result["code"] = code
LuciHttp.write_json(result)
end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
module("luci.controller.api.xqpassport", package.seeall)
function index()
local page = node("api","xqpassport")
page.target = firstchild()
page.title = ("")
page.order = 400
page.sysauth = "admin"
page.sysauth_authenticator = "jsonauth"
page.index = true
entry({"api", "xqpassport"}, firstchild(), (""), 400)
entry({"api", "xqpassport", "login"}, call("passportLogin"), (""), 401, 0x01)
entry({"api", "xqpassport", "userInfo"}, call("getUserInfo"), (""), 402)
entry({"api", "xqpassport", "rigister"}, call("routerRegister"), (""), 405, 0x01)
entry({"api", "xqpassport", "binded"}, call("getBindInfo"), (""), 406, 0x01)
entry({"api", "xqpassport", "plugin_list"}, call("pluginList"), (""), 407)
entry({"api", "xqpassport", "plugin_enable"}, call("pluginEnable"), (""), 408)
entry({"api", "xqpassport", "plugin_disable"}, call("pluginDisable"), (""), 409)
entry({"api", "xqpassport", "plugin_detail"}, call("pluginDetail"), (""), 410)
entry({"api", "xqpassport", "unbound"}, call("unboundRouter"), (""), 411)
end
local LuciHttp = require("luci.http")
local XQErrorUtil = require("xiaoqiang.util.XQErrorUtil")
function getBindInfo()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
local uuid = LuciHttp.formvalue("uuid") or ""
local force = tonumber(LuciHttp.formvalue("force") or "0")
local result = {}
local code = 0
local bindUUID = XQSysUtil.getPassportBindInfo()
if bindUUID then
result["bind"] = 1
local info = XQSysUtil.getBindUserInfo()
if info == nil or force ~= 0 then
info = XQNetUtil.getUserInfo(uuid)
end
if info then
if info.miliaoNick and info.miliaoNick ~= "" then
info.aliasNick = info.miliaoNick
end
result["info"] = info
else
info = {}
info["aliasNick"] = bindUUID
info["miliaoIcon"] = ""
info["miliaoIconOrig"] = ""
info["miliaoNick"] = ""
info["userId"] = bindUUID
result["info"] = info
end
else
result["bind"] = 0
end
result["routerName"] = XQSysUtil.getRouterName()
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
end
result["code"] = code
LuciHttp.write_json(result)
end
function unboundRouter()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
local result = {}
local code = 0
local uuid = LuciHttp.formvalue("uuid")
local password = LuciHttp.formvalue("password")
if uuid == nil or uuid == "" then
uuid = XQSysUtil.getBindUUID()
end
if password ~= nil then
local login = XQNetUtil.xiaomiLogin(uuid,password)
if login and login.code == 0 then
if XQSysUtil.getPassportBindInfo() then
local unbound = XQNetUtil.dismissAccount(nil,uuid)
if unbound and (tonumber(unbound.code) == 0 or tonumber(unbound.code) == 3001 or tonumber(unbound.code) == 3002) then
XQSysUtil.setPassportBound(false,uuid)
else
code = 1550
end
end
else
code = 1556
end
else
code = 1557
end
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
else
LuciHttp.header("Set-Cookie", "psp=admin|||2|||0;path=/;")
end
result["code"] = code
LuciHttp.write_json(result)
end
function passportLogin()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
local result = {}
local code = 0
local uuid = LuciHttp.formvalue("uuid")
local password = LuciHttp.formvalue("password")
local encrypt = LuciHttp.formvalue("encrypt")
local login = XQNetUtil.xiaomiLogin(uuid,password)
if login and login.code == 0 then
local bindInfo = XQSysUtil.getPassportBindInfo()
if bindInfo then
if login.uuid == bindInfo then
local adminList = XQNetUtil.getAdminList()
if adminList and type(adminList) == "table" then
if tonumber(adminList.code) == 0 then
code = 0
LuciHttp.header("Set-Cookie", "psp=" .. login.uuid .. "|||" .. 1 .. "|||" .. login.token .. ";path=/;")
elseif tonumber(adminList.code) == 401 then
code = 1551
else
code = 1549
XQSysUtil.setPassportBound(false,login.uuid)
LuciHttp.header("Set-Cookie", "psp=admin|||2|||0;path=/;")
end
else
code = 1551
if adminList and adminList.msg then
result["errorDetail"] = adminList.msg
end
end
else
code = 1548
end
else
XQSysUtil.setBindUUID(login.uuid)
end
result["token"] = login.token
result["uuid"] = login.uuid
elseif login and login.code ~= 0 then
if login.code == 1 then
code = 1564
elseif login.code == 2 then
code = 1565
else
code = 1566
end
else
code = 1538
end
if code ~= 0 then
local XQFunction = require("xiaoqiang.common.XQFunction")
XQFunction.forkExec("/usr/sbin/ntpsetclock 99999 log >/dev/null 2>&1")
result["msg"] = XQErrorUtil.getErrorMessage(code)
end
result["code"] = code
LuciHttp.write_json(result)
end
function routerAdminList()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
local result = {}
local code = 0
local uuid = LuciHttp.formvalue("uuid") or ""
if not XQSysUtil.getPassportBindInfo() then
code = 1542
else
local admin = XQNetUtil.getAdminList(uuid)
if admin and tonumber(admin.code) == 0 then
result["list"] = admin.adminList
elseif admin and tonumber(admin.code) == 401 then
code = 1581
else
code = 1543
end
end
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
end
result["code"] = code
LuciHttp.write_json(result)
end
function routerRegister()
local XQSysUtil = require("xiaoqiang.util.XQSysUtil")
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local XQDBUtil = require("xiaoqiang.util.XQDBUtil")
local result = {}
local code = 0
local uuid = LuciHttp.formvalue("uuid")
local register = XQNetUtil.routerRegister(uuid)
local passport = XQNetUtil.getPassport(uuid)
if register and tonumber(register.code) == 0 then
result["deviceID"] = register.id
XQSysUtil.setPassportBound(true,passport.uuid)
else
XQSysUtil.setPassportBound(false,nil)
code = 1541
end
if code ~= 0 then
local XQFunction = require("xiaoqiang.common.XQFunction")
XQFunction.forkExec("/usr/sbin/ntpsetclock 99999 log >/dev/null 2>&1")
result["msg"] = XQErrorUtil.getErrorMessage(code)
else
LuciHttp.header("Set-Cookie", "psp=" .. uuid .. "|||" .. 1 .. "|||" .. passport.token .. ";path=/;")
end
result["code"] = code
LuciHttp.write_json(result)
end
function getUserInfo()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local result = {}
local code = 0
local uuid = LuciHttp.formvalue("uuid") or ""
local info = XQNetUtil.getUserInfo(uuid)
if info then
result["userInfo"] = info
else
code = 1539
end
if code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(code)
end
result["code"] = code
LuciHttp.write_json(result)
end
function pluginList()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local result = {}
local uuid = LuciHttp.formvalue("uuid") or ""
local pList = XQNetUtil.pluginList(uuid)
if pList and tonumber(pList.code) == 0 then
result["code"] = 0
result["list"] = pList
elseif pList and tonumber(pList.code) == 401 then
result["code"] = 1581
elseif pList and tonumber(pList.code) == 3001 then
result["code"] = 1580
else
result["code"] = 1544
end
if result.code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(result.code)
end
LuciHttp.write_json(result)
end
function pluginEnable()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local result = {}
local uuid = LuciHttp.formvalue("uuid") or ""
local pluginId = LuciHttp.formvalue("pluginId")
local enable = XQNetUtil.pluginEnable(uuid,pluginId)
if enable and tonumber(enable.code) == 0 then
result["code"] = 0
elseif enable and tonumber(enable.code) == 401 then
result["code"] = 1581
elseif enable and tonumber(enable.code) == 3001 then
result["code"] = 1580
else
result["code"] = 1545
end
if result.code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(result.code)
end
LuciHttp.write_json(result)
end
function pluginDisable()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local result = {}
local uuid = LuciHttp.formvalue("uuid") or ""
local pluginId = LuciHttp.formvalue("pluginId")
local disable = XQNetUtil.pluginDisable(uuid,pluginId)
if disable and tonumber(disable.code) == 0 then
result["code"] = 0
elseif disable and tonumber(disable.code) == 401 then
result["code"] = 1581
elseif disable and tonumber(disable.code) == 3001 then
result["code"] = 1580
else
result["code"] = 1546
end
if result.code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(result.code)
end
LuciHttp.write_json(result)
end
function pluginDetail()
local XQNetUtil = require("xiaoqiang.util.XQNetUtil")
local result = {}
local uuid = LuciHttp.formvalue("uuid") or ""
local pluginId = LuciHttp.formvalue("pluginId")
local plugin = XQNetUtil.pluginDetail(uuid,pluginId)
if plugin and tonumber(plugin.code) == 0 then
result["code"] = 0
result["detail"] = plugin
elseif plugin and tonumber(plugin.code) == 401 then
result["code"] = 1581
elseif plugin and tonumber(plugin.code) == 3001 then
result["code"] = 1580
else
result["code"] = 1547
end
if result.code ~= 0 then
result["msg"] = XQErrorUtil.getErrorMessage(result.code)
end
LuciHttp.write_json(result)
end

View File

@ -0,0 +1,67 @@
module("luci.controller.api.xqsmarthome", package.seeall)
function index()
local page = node("api","xqsmarthome")
page.target = firstchild()
page.title = ("")
page.order = 500
page.sysauth = "admin"
page.sysauth_authenticator = "jsonauth"
page.index = true
entry({"api", "xqsmarthome"}, firstchild(), _(""), 500)
entry({"api", "xqsmarthome", "request"}, call("tunnelSmartHomeRequest"), _(""), 501)
entry({"api", "xqsmarthome", "request_smartcontroller"}, call("tunnelSmartControllerRequest"), _(""), 502)
entry({"api", "xqsmarthome", "request_miio"}, call("tunnelMiioRequest"), _(""), 503)
entry({"api", "xqsmarthome", "request_mitv"}, call("requestMitv"), _(""), 504)
entry({"api", "xqsmarthome", "request_yeelink"}, call("tunnelYeelink"), _(""), 505)
entry({"api", "xqsmarthome", "request_camera"}, call("requestCamera"), _(""), 506)
end
local LuciHttp = require("luci.http")
local XQConfigs = require("xiaoqiang.common.XQConfigs")
local XQFunction = require("xiaoqiang.common.XQFunction")
function tunnelSmartHomeRequest()
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
local payload = XQCryptoUtil.binaryBase64Enc(LuciHttp.formvalue("payload"))
local cmd = XQConfigs.THRIFT_TUNNEL_TO_SMARTHOME % payload
local LuciUtil = require("luci.util")
LuciHttp.write(LuciUtil.exec(cmd))
end
function tunnelSmartControllerRequest()
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
local payload = XQCryptoUtil.binaryBase64Enc(LuciHttp.formvalue("payload"))
local cmd = XQConfigs.THRIFT_TUNNEL_TO_SMARTHOME_CONTROLLER % payload
local LuciUtil = require("luci.util")
LuciHttp.write(LuciUtil.exec(cmd))
end
function tunnelMiioRequest()
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
local payload = XQCryptoUtil.binaryBase64Enc(LuciHttp.formvalue("payload"))
local cmd = XQConfigs.THRIFT_TUNNEL_TO_MIIO % payload
local LuciUtil = require("luci.util")
LuciHttp.write(LuciUtil.exec(cmd))
end
function tunnelYeelink()
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
local payload = XQCryptoUtil.binaryBase64Enc(LuciHttp.formvalue("payload"))
-- merge yeelink daemon into miio, so tunnel into miio
local cmd = XQConfigs.THRIFT_TUNNEL_TO_MIIO % payload
local LuciUtil = require("luci.util")
LuciHttp.write(LuciUtil.exec(cmd))
end
function requestMitv()
local payload = LuciHttp.formvalue("payload");
local MitvUtil = require("xiaoqiang.util.XQMitvUtil");
LuciHttp.write(MitvUtil.request(payload));
end
function requestCamera()
local payload = LuciHttp.formvalue("payload");
local CamUtil = require("xiaoqiang.util.XQCameraUtil");
LuciHttp.write(CamUtil.request(payload));
end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
module("luci.controller.api.xqtunnel", package.seeall)
function index()
local page = node("api","xqtunnel")
page.target = firstchild()
page.title = ("")
page.order = 300
page.sysauth = "admin"
page.sysauth_authenticator = "jsonauth"
page.index = true
entry({"api", "xqtunnel", "request"}, call("tunnelRequest"), _(""), 301)
end
local LuciHttp = require("luci.http")
local XQConfigs = require("xiaoqiang.common.XQConfigs")
local base64chars = {
['A']=true,['B']=true,['C']=true,['D']=true,
['E']=true,['F']=true,['G']=true,['H']=true,
['I']=true,['J']=true,['K']=true,['L']=true,
['M']=true,['N']=true,['O']=true,['P']=true,
['Q']=true,['R']=true,['S']=true,['T']=true,
['U']=true,['V']=true,['W']=true,['X']=true,
['Y']=true,['Z']=true,['a']=true,['b']=true,
['c']=true,['d']=true,['e']=true,['f']=true,
['g']=true,['h']=true,['i']=true,['j']=true,
['k']=true,['l']=true,['m']=true,['n']=true,
['o']=true,['p']=true,['q']=true,['r']=true,
['s']=true,['t']=true,['u']=true,['v']=true,
['w']=true,['x']=true,['y']=true,['z']=true,
['0']=true,['1']=true,['2']=true,['3']=true,
['4']=true,['5']=true,['6']=true,['7']=true,
['8']=true,['9']=true,['-']=true,['_']=true,
['+']=true,['/']=true,['=']=true
}
local function base64filter(input)
local result = ""
for i = 1, #input do
local c = input:sub(i,i)
if base64chars[c] ~= nil and base64chars[c] then
result = result .. c
end
end
return result
end
function tunnelRequest()
local payload = LuciHttp.formvalue("payloadB64")
local cmd = XQConfigs.TUNNEL_TOOL % base64filter(payload)
local LuciUtil = require("luci.util")
LuciHttp.write(LuciUtil.exec(cmd))
end

View File

@ -0,0 +1,18 @@
module("luci.controller.dispatch.index", package.seeall)
function index()
local root = node()
if not root.target then
root.target = alias("dispatch")
root.index = true
end
local page = node("dispatch")
page.target = firstchild()
page.title = _("")
page.order = 1
page.sysauth = "admin"
page.mediaurlbase = "/xiaoqiang/dispatch"
page.sysauth_authenticator = "htmlauth"
page.index = true
entry({"dispatch"}, template("index"), _("跳转"), 1, 0x09)
end

View File

@ -0,0 +1,23 @@
module("luci.controller.firewall", package.seeall)
function index()
-- entry({"admin", "network", "firewall"},
-- alias("admin", "network", "firewall", "zones"),
-- _("Firewall"), 60)
--
-- entry({"admin", "network", "firewall", "zones"},
-- arcombine(cbi("firewall/zones"), cbi("firewall/zone-details")),
-- _("General Settings"), 10).leaf = true
--
-- entry({"admin", "network", "firewall", "forwards"},
-- arcombine(cbi("firewall/forwards"), cbi("firewall/forward-details")),
-- _("Port Forwards"), 20).leaf = true
--
-- entry({"admin", "network", "firewall", "rules"},
-- arcombine(cbi("firewall/rules"), cbi("firewall/rule-details")),
-- _("Traffic Rules"), 30).leaf = true
--
-- entry({"admin", "network", "firewall", "custom"},
-- cbi("firewall/custom"),
-- _("Custom Rules"), 40).leaf = true
end

View File

@ -0,0 +1,32 @@
module("luci.controller.mobile.index", package.seeall)
function index()
local root = node()
if not root.target then
root.target = alias("mobile")
root.index = true
end
local page = node("mobile")
page.target = firstchild()
page.title = _("")
page.order = 110
page.sysauth = "admin"
page.mediaurlbase = "/xiaoqiang/mobile"
page.sysauth_authenticator = "htmlauth_moblie"
page.index = true
entry({"mobile"}, template("mobile/home"), _("首页"), 1, 0x08)
entry({"mobile", "logout"}, call("action_logout"), 2, 0x09)
entry({"mobile", "hello"}, template("mobile/init/hello"), _("初始化欢迎界面"), 3, 0x09)
entry({"mobile", "agreement"}, template("mobile/init/agreement"), _("查看协议"), 4, 0x09)
entry({"mobile", "guide"}, template("mobile/init/guide"), _("初始化引导"), 5, 0x08)
end
function action_logout()
local dsp = require "luci.dispatcher"
local sauth = require "luci.sauth"
if dsp.context.authsession then
sauth.kill(dsp.context.authsession)
dsp.context.urltoken.stok = nil
end
luci.http.header("Set-Cookie", "sysauth=; path=" .. dsp.build_url())
luci.http.redirect(luci.dispatcher.build_url().."/mobile")
end

View File

@ -0,0 +1,382 @@
module("luci.controller.service.datacenter", package.seeall)
function index()
local page = node("service","datacenter")
page.target = firstchild()
page.title = ("")
page.order = nil
page.sysauth = "admin"
page.sysauth_authenticator = "jsonauth"
page.index = true
entry({"service", "datacenter", "download_file"}, call("downloadFile"), _(""), nil, 0x11)
entry({"service", "datacenter", "device_id"}, call("getDeviceID"), _(""), nil, 0x11)
entry({"service", "datacenter", "download_info"}, call("getDownloadInfo"), _(""), nil, 0x11)
entry({"service", "datacenter", "upload_file"}, call("uploadFile"), _(""), nil, 0x11)
entry({"service", "datacenter", "batch_download_info"}, call("getBatchDownloadInfo"), _(""), nil, 0x11)
entry({"service", "datacenter", "config_info"}, call("getConfigInfo"), _(""), nil, 0x11)
entry({"service", "datacenter", "set_config"}, call("setConfigInfo"), _(""), nil, 0x11)
entry({"service", "datacenter", "plugin_enable"}, call("enablePlugin"), _(""), nil, 0x11)
entry({"service", "datacenter", "plugin_download_info"}, call("pluginDownloadInfo"), _(""), nil, 0x11)
entry({"service", "datacenter", "plugin_disable"}, call("disablePlugin"), _(""), nil, 0x11)
entry({"service", "datacenter", "plugin_control"}, call("controlPlugin"), _(""), nil, 0x11)
entry({"service", "datacenter", "download_delete"}, call("deleteDownload"), _(""), nil, 0x11)
entry({"service", "datacenter", "get_plugin_status"}, call("pluginStatus"), _(""), nil, 0x11)
entry({"service", "datacenter", "get_connected_device"}, call("connectedDevice"), _(""), nil, 0x11)
entry({"service", "datacenter", "get_router_mac"}, call("getMac"), _(""), nil, 0x11)
entry({"service", "datacenter", "set_wan_access"}, call("setWanAccess"), _(""), nil, 0x11)
entry({"service", "datacenter", "get_router_info"}, call("getRouterInfo"), _(""), nil, 0x11)
entry({"service", "datacenter", "xunlei_notify"}, call("xunleiNotify"), _(""), nil, 0x11)
end
local LuciHttp = require("luci.http")
local XQConfigs = require("xiaoqiang.common.XQConfigs")
local ServiceErrorUtil = require("service.util.ServiceErrorUtil")
function xunleiNotify()
local payload = {}
payload["api"] = 519
payload["info"] = LuciHttp.formvalue("tasks")
tunnelRequestDatacenter(payload)
end
function tunnelRequestDatacenter(payload)
local LuciJson = require("cjson")
local LuciUtil = require("luci.util")
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
payload = LuciJson.encode(payload)
payload = XQCryptoUtil.binaryBase64Enc(payload)
local cmd = XQConfigs.THRIFT_TUNNEL_TO_DATACENTER % payload
LuciHttp.write(LuciUtil.exec(cmd))
end
function requestDatacenter(payload)
local LuciJson = require("cjson")
local LuciUtil = require("luci.util")
local XQCryptoUtil = require("xiaoqiang.util.XQCryptoUtil")
payload = LuciJson.encode(payload)
payload = XQCryptoUtil.binaryBase64Enc(payload)
local cmd = XQConfigs.THRIFT_TUNNEL_TO_DATACENTER % payload
return LuciUtil.exec(cmd)
end
function downloadFile()
local payload = {}
payload["api"] = 1101
payload["appid"] = LuciHttp.formvalue("appId")
payload["path"] = LuciHttp.formvalue("path")
payload["url"] = LuciHttp.formvalue("url")
payload["name"] = LuciHttp.formvalue("downloadName")
payload["tag"] = LuciHttp.formvalue("tag")
payload["hidden"] = false
if LuciHttp.formvalue("hidden") == "true" then
payload["hidden"] = true
end
payload["redownload"] = 0
if LuciHttp.formvalue("redownload") == "1" then
payload["redownload"] = 1
end
payload["dupId"] = LuciHttp.formvalue("dupId")
tunnelRequestDatacenter(payload)
end
function setWanAccess()
local payload = {}
payload["api"] = 618
payload["appid"] = LuciHttp.formvalue("appId")
payload["mac"] = LuciHttp.formvalue("mac")
payload["enable"] = false
if LuciHttp.formvalue("enable") == "true" then
payload["enable"] = true
end
tunnelRequestDatacenter(payload)
end
function getDeviceID()
local payload = {}
payload["api"] = 1103
payload["appid"] = LuciHttp.formvalue("appId")
tunnelRequestDatacenter(payload)
end
function getMac()
local payload = {}
payload["api"] = 617
payload["appid"] = LuciHttp.formvalue("appId")
tunnelRequestDatacenter(payload)
end
function getRouterInfo()
local payload = {}
payload["api"] = 622
payload["appid"] = LuciHttp.formvalue("appId")
tunnelRequestDatacenter(payload)
end
function getOperateDeviceID()
local payload = {}
payload["api"] = 1103
payload["appid"] = LuciHttp.formvalue("appId")
local result = requestDatacenter(payload)
if result then
local LuciJson = require("cjson")
result = LuciJson.decode(result)
if result then
if result.code == 0 then
local deviceid = result["deviceid"]
if deviceid then
return 0, deviceid
end
elseif result.code == 5 then
return 5, nil
end
end
end
return 1559, nil
end
function urlEncode(url)
if url then
url = string.gsub(url, "\n", "\r\n")
url = string.gsub(url, "([^0-9a-zA-Z/])",
function(c) return string.format ("%%%02X", string.byte(c)) end)
end
return url
end
function generateUrlFromPath(path)
if path then
path = urlEncode(path)
local url, count = string.gsub (path, "^/userdisk/data/", "http://miwifi.com/api-third-party/download/public/")
if count == 1 then
return url
end
url, count = string.gsub (path, "^/userdisk/appdata/", "http://miwifi.com/api-third-party/download/private/")
if count == 1 then
return url
end
url, count = string.gsub (path, "^/extdisks/", "http://miwifi.com/api-third-party/download/extdisks/")
if count == 1 then
return url
end
end
return nil
end
function generateResponseFromCode(code)
local response = {}
response["code"] = code
response["msg"] = ServiceErrorUtil.getErrorMessage(code)
return response
end
function getDownloadInfo()
local LuciJson = require("cjson")
local payload = {}
payload["api"] = 1102
payload["appid"] = LuciHttp.formvalue("appId")
payload["deviceId"] = LuciHttp.formvalue("deviceId")
payload["downloadId"] = LuciHttp.formvalue("downloadId")
payload["hidden"] = false
if LuciHttp.formvalue("hidden") == "true" then
payload["hidden"] = true
end
local response = {}
local result = requestDatacenter(payload)
if result then
result = LuciJson.decode(result)
if result and result.code == 0 then
local url = generateUrlFromPath(result["path"])
if url then
response["code"] = result["code"]
response["msg"] = result["msg"]
response["url"] = url
else
response = generateResponseFromCode(1559)
end
else
response = result
end
else
response = generateResponseFromCode(1559)
end
LuciHttp.write_json(response)
LuciHttp.close()
end
function uploadFile()
local fp
local log = require("xiaoqiang.XQLog")
local fs = require("luci.fs")
local tmpfile = "/userdisk/upload.tmp"
if fs.isfile(tmpfile) then
fs.unlink(tmpfile)
end
local filename
LuciHttp.setfilehandler(
function(meta, chunk, eof)
if not fp then
if meta and meta.name == "file" then
fp = io.open(tmpfile, "w")
filename = meta.file
filename = string.gsub(filename, "+", " ")
filename = string.gsub(filename, "%%(%x%x)",
function(h)
return string.char(tonumber(h, 16))
end)
filename = filename.gsub(filename, "\r\n", "\n")
end
end
if chunk then
fp:write(chunk)
end
if eof then
fp:close()
end
end
)
local code, deviceId = getOperateDeviceID()
if code ~= 0 then
return LuciHttp.write_json(generateResponseFromCode(code))
end
local path
local appid = LuciHttp.formvalue("appId")
local saveType = LuciHttp.formvalue("saveType")
if saveType == "public" then
path = "/userdisk/data/上传/"
elseif saveType == "private" then
path = "/userdisk/appdata/" .. appid .. "/"
else
return LuciHttp.write_json(generateResponseFromCode(3))
end
fs.mkdir(path, true)
local savename = fs.basename(filename)
if fs.isfile(path .. savename) then
local basename = savename
local index = basename:match(".+()%.%w+$")
if index then
basename = basename:sub(1, index - 1)
end
local extension = savename:match(".+%.(%w+)$")
for i = 1, 100, 1 do
local tmpname = basename .. "(" .. i .. ")"
if extension then
tmpname = tmpname .. "." .. extension
end
if not fs.isfile(path .. tmpname) then
savename = tmpname
break
end
end
end
local dest = path .. savename
log.log("dest=" .. dest)
fs.rename(tmpfile, dest)
local response = {}
response["code"] = 0
response["url"] = generateUrlFromPath(dest)
response["deviceId"] = deviceId
response["msg"] = ""
LuciHttp.write_json(response)
LuciHttp.close()
end
function getBatchDownloadInfo()
local payload = {}
payload["api"] = 1105
payload["appid"] = LuciHttp.formvalue("appId")
payload["ids"] = LuciHttp.formvalue("ids")
payload["hidden"] = false
if LuciHttp.formvalue("hidden") == "true" then
payload["hidden"] = true
end
tunnelRequestDatacenter(payload)
end
function getConfigInfo()
local payload = {}
payload["api"] = 1106
payload["appid"] = LuciHttp.formvalue("appId")
payload["key"] = LuciHttp.formvalue("key")
tunnelRequestDatacenter(payload)
end
function connectedDevice()
local payload = {}
payload["api"] = 616
payload["appid"] = LuciHttp.formvalue("appId")
tunnelRequestDatacenter(payload)
end
function setConfigInfo()
local payload = {}
payload["api"] = 1107
payload["appid"] = LuciHttp.formvalue("appId")
payload["key"] = LuciHttp.formvalue("key")
payload["value"] = LuciHttp.formvalue("value")
tunnelRequestDatacenter(payload)
end
function enablePlugin()
local payload = {}
payload["api"] = 1108
payload["appid"] = LuciHttp.formvalue("appId")
payload["status"] = 5
tunnelRequestDatacenter(payload)
end
function disablePlugin ()
local payload = {}
payload["api"] = 1108
payload["appid"] = LuciHttp.formvalue("appId")
payload["status"] = 6
tunnelRequestDatacenter(payload)
end
function controlPlugin()
local payload = {}
payload["api"] = 600
payload["pluginID"] = LuciHttp.formvalue("appId")
payload["info"] = LuciHttp.formvalue("info")
tunnelRequestDatacenter(payload)
end
function deleteDownload()
local payload = {}
payload["api"] = 1110
payload["appid"] = LuciHttp.formvalue("appId")
payload["idList"] = LuciHttp.formvalue("idList")
payload["deletefile"] = false
if LuciHttp.formvalue("deletefile") == "true" then
payload["deletefile"] = true
end
tunnelRequestDatacenter(payload)
end
function pluginStatus()
local payload = {}
payload["api"] = 1111
payload["appid"] = LuciHttp.formvalue("appId")
tunnelRequestDatacenter(payload)
end
function pluginDownloadInfo()
local payload = {}
payload["api"] = 1109
payload["appid"] = LuciHttp.formvalue("appId")
payload["hidden"] = false
if LuciHttp.formvalue("hidden") == "true" then
payload["hidden"] = true
end
payload["lite"] = false
if LuciHttp.formvalue("lite") == "true" then
payload["lite"] = true
end
tunnelRequestDatacenter(payload)
end

View File

@ -0,0 +1,10 @@
module("luci.controller.service.index", package.seeall)
function index()
local page = node("service")
page.target = firstchild()
page.title = _("")
page.order = nil
page.sysauth = "admin"
page.sysauth_authenticator = "jsonauth"
page.index = true
end

View File

@ -0,0 +1,96 @@
module("luci.controller.web.index", package.seeall)
function index()
local root = node()
if not root.target then
root.target = alias("web")
root.index = true
end
local page = node("web")
page.target = firstchild()
page.title = _("")
page.order = 10
page.sysauth = "admin"
page.mediaurlbase = "/xiaoqiang/web"
page.sysauth_authenticator = "htmlauth"
page.index = true
entry({"web"}, template("web/index"), _("路由器状态"), 10, 0x08)
entry({"web", "home"}, template("web/index"), _("路由器状态"), 70, 0x08)
entry({"web", "manager"}, template("web/manager"), _("终端管理"), 71)
--entry({"web", "plugin"}, template("web/plugin"), _("插件管理"), 72)
--entry({"web", "plugin", "kuaipan"}, template("web/plugins/kuaipan"), _("插件管理_快盘"), 72)
--entry({"web", "plugin", "guest"}, template("web/plugins/guest"), _("插件管理_访客"), 72)
entry({"web", "logout"}, call("action_logout"), 11, 0x09)
entry({"web", "init"}, template("web/init/hello"), _("初始化引导"), 190, 0x09)
entry({"web", "init", "hello"}, template("web/init/hello"), _("欢迎界面"), 198, 0x09) --不需要登录
entry({"web", "init", "agreement"}, template("web/init/agreement"), _("用户协议"), 198, 0x09) --不需要登录
entry({"web", "init", "guide"}, template("web/init/guide"), _("引导模式"), 190, 0x08)
entry({"web", "netset"}, template("web/netset"), _("路由设置"), 73)
entry({"web", "sysset"}, template("web/sysset"), _("路由设置"), 73)
entry({"web", "sysset", "passport"}, template("web/setting/passport"), _("路由器权限"), 18)
entry({"web", "sysset", "reboot"}, template("web/setting/reboot"), _("重启路由器"), 73)
entry({"web", "sysset", "reset"}, template("web/setting/reset"), _("恢复出厂设置"), 73)
entry({"web", "netset", "wifi"}, template("web/setting/wifi_set"), _("WIFI网络设置"), 20)
entry({"web", "netset", "wifi_mini"}, template("web/setting/wifi_set_mini"), _("WIFI网络快捷设置"), 20)
entry({"web", "netset", "wifi_pro"}, template("web/setting/wifi_set_pro"), _("WIFI网络高级设置"), 60)
entry({"web", "netset", "wifi_txpwr"}, template("web/setting/wifi_txpwr"), _("WIFI强度设置"), 60)
entry({"web", "netset", "wifi_filter"}, template("web/setting/wifi_filter"), _("WIFI访问控制"), 60)
entry({"web", "netset" ,"net_wan"}, template("web/setting/net_wan"), _("网络设置WAN"), 20)
entry({"web", "netset", "net_lan"}, template("web/setting/net_lan"), _("网络设置LAN"), 30)
entry({"web", "netset", "mac"}, template("web/setting/net_setup_mac"), _("mac 设置"), 40)
entry({"web", "netset", "ipmacband"}, template("web/setting/net_ipmacband"), _("mac 设置"), 40)
entry({"web", "sysset", "qos_pro"}, template("web/setting/qos_pro"), _("QoS 设置"), 40)
entry({"web", "sysset", "upgrade"}, template("web/setting/upgrade"), _("路由器固件升级"), 198, 0x01)
entry({"web", "sysset", "upgrade_manual"}, template("web/setting/upgrade_manual", _("路由器手动升级"), 200))
entry({"web", "sysset", "log"}, template("web/setting/log", _("上传日志"), 201))
--entry({"web", "sysset", "upload_config"}, template("web/setting/upload_config"), _("上传配置信息"), 202)
--entry({"web", "setting", "sys_psp"}, template("web/setting/sys_psp"), _("管理小米账号"), 73)
entry({"web", "sysset", "sys_status"}, template("web/setting/sys_status"), _("系统状态"), 73)
entry({"web", "sysset", "diskformat"}, template("web/setting/diskformat"), _("格式化小强盘"), 202)
entry({"web", "sysset", "nginx"}, template("web/setting/nginx"), _("关闭NGINX"), 203)
entry({"web", "sysset", "upnp"}, template("web/setting/upnp"), _("upnp"), 204)
-- entry({"web", "sysset", "lamp"}, template("web/setting/lamp"), _("LAMP Settings"), 204)
entry({"web", "sysset", "qos"}, template("web/setting/qos"), _("应用限速"), 204)
entry({"web", "sysset", "vpn"}, template("web/setting/vpn"), _("VPN"), 204)
entry({"web", "sysset", "developer"}, template("web/setting/developer"), _("开发者选项"), 205)
entry({"web", "sysset", "dmz"}, template("web/setting/dmz"), _("DMZ"), 205)
entry({"web", "sysset", "ddns"}, template("web/setting/ddns"), _("DDNS"), 204)
entry({"web", "sysset", "nat"}, template("web/setting/nat"), _("端口转发"), 206)
entry({"web", "sysset", "noflushd"}, template("web/setting/noflushd"), _("磁盘休眠"), 207)
--entry({"web", "sysset", "predownload"}, template("web/setting/predownload"), _("预下载"), 208)
entry({"web", "detecte"}, template("web/netdetection"), _("网络检测"), 74, 0x01)
entry({"web", "detecte_pro"}, template("web/urldetection"), _("网络高级检测"), 75, 0x01)
entry({"web", "xmaccount"}, template("web/xmaccount"), _("小米帐号验证"), 75, 0x01)
-- entry({"web", "safeurl"}, call("action_safeurl"), _(""), 75, 0x09)
entry({"web", "webinitrdr"}, template("web/init/webinitrdr"), _("劫持页面"), 300, 0x09) --不需要登录
end
function action_logout()
local dsp = require "luci.dispatcher"
local sauth = require "luci.sauth"
if dsp.context.authsession then
sauth.kill(dsp.context.authsession)
dsp.context.urltoken.stok = nil
end
luci.http.header("Set-Cookie", "sysauth=; path=" .. dsp.build_url())
luci.http.header("Set-Cookie", "autologin_v2=;expires=-1;path=/;")
luci.http.redirect(luci.dispatcher.build_url())
end
function action_safeurl()
local safeUrl = luci.http.formvalue("safeurl")
require("luci.template")
luci.template.render("web/safeurl", {safeurl=safeUrl})
end

Binary file not shown.

37
Mi_Lua/luci/debug.lua Normal file
View File

@ -0,0 +1,37 @@
local debug = require "debug"
local io = require "io"
local collectgarbage, floor = collectgarbage, math.floor
module "luci.debug"
__file__ = debug.getinfo(1, 'S').source:sub(2)
-- Enables the memory tracer with given flags and returns a function to disable the tracer again
function trap_memtrace(flags, dest)
flags = flags or "clr"
local tracefile = io.open(dest or "/tmp/memtrace", "w")
local peak = 0
local function trap(what, line)
local info = debug.getinfo(2, "Sn")
local size = floor(collectgarbage("count"))
if size > peak then
peak = size
end
if tracefile then
tracefile:write(
"[", what, "] ", info.source, ":", (line or "?"), "\t",
(info.namewhat or ""), "\t",
(info.name or ""), "\t",
size, " (", peak, ")\n"
)
end
end
debug.sethook(trap, flags)
return function()
debug.sethook()
tracefile:close()
end
end

1037
Mi_Lua/luci/dispatcher.lua Normal file

File diff suppressed because it is too large Load Diff

244
Mi_Lua/luci/fs.lua Normal file
View File

@ -0,0 +1,244 @@
--[[
LuCI - Filesystem tools
Description:
A module offering often needed filesystem manipulation functions
FileId:
$Id: fs.lua 5134 2009-07-24 17:34:40Z Cyrus $
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.
]]--
local io = require "io"
local os = require "os"
local ltn12 = require "luci.ltn12"
local fs = require "nixio.fs"
local nutil = require "nixio.util"
local type = type
--- LuCI filesystem library.
module "luci.fs"
--- Test for file access permission on given path.
-- @class function
-- @name access
-- @param str String value containing the path
-- @return Number containing the return code, 0 on sucess or nil on error
-- @return String containing the error description (if any)
-- @return Number containing the os specific errno (if any)
access = fs.access
--- Evaluate given shell glob pattern and return a table containing all matching
-- file and directory entries.
-- @class function
-- @name glob
-- @param filename String containing the path of the file to read
-- @return Table containing file and directory entries or nil if no matches
-- @return String containing the error description (if no matches)
-- @return Number containing the os specific errno (if no matches)
function glob(...)
local iter, code, msg = fs.glob(...)
if iter then
return nutil.consume(iter)
else
return nil, code, msg
end
end
--- Checks wheather the given path exists and points to a regular file.
-- @param filename String containing the path of the file to test
-- @return Boolean indicating wheather given path points to regular file
function isfile(filename)
return fs.stat(filename, "type") == "reg"
end
--- Checks wheather the given path exists and points to a directory.
-- @param dirname String containing the path of the directory to test
-- @return Boolean indicating wheather given path points to directory
function isdirectory(dirname)
return fs.stat(dirname, "type") == "dir"
end
--- Read the whole content of the given file into memory.
-- @param filename String containing the path of the file to read
-- @return String containing the file contents or nil on error
-- @return String containing the error message on error
readfile = fs.readfile
--- Write the contents of given string to given file.
-- @param filename String containing the path of the file to read
-- @param data String containing the data to write
-- @return Boolean containing true on success or nil on error
-- @return String containing the error message on error
writefile = fs.writefile
--- Copies a file.
-- @param source Source file
-- @param dest Destination
-- @return Boolean containing true on success or nil on error
copy = fs.datacopy
--- Renames a file.
-- @param source Source file
-- @param dest Destination
-- @return Boolean containing true on success or nil on error
rename = fs.move
--- Get the last modification time of given file path in Unix epoch format.
-- @param path String containing the path of the file or directory to read
-- @return Number containing the epoch time or nil on error
-- @return String containing the error description (if any)
-- @return Number containing the os specific errno (if any)
function mtime(path)
return fs.stat(path, "mtime")
end
--- Set the last modification time of given file path in Unix epoch format.
-- @param path String containing the path of the file or directory to read
-- @param mtime Last modification timestamp
-- @param atime Last accessed timestamp
-- @return 0 in case of success nil on error
-- @return String containing the error description (if any)
-- @return Number containing the os specific errno (if any)
function utime(path, mtime, atime)
return fs.utimes(path, atime, mtime)
end
--- Return the last element - usually the filename - from the given path with
-- the directory component stripped.
-- @class function
-- @name basename
-- @param path String containing the path to strip
-- @return String containing the base name of given path
-- @see dirname
basename = fs.basename
--- Return the directory component of the given path with the last element
-- stripped of.
-- @class function
-- @name dirname
-- @param path String containing the path to strip
-- @return String containing the directory component of given path
-- @see basename
dirname = fs.dirname
--- Return a table containing all entries of the specified directory.
-- @class function
-- @name dir
-- @param path String containing the path of the directory to scan
-- @return Table containing file and directory entries or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
function dir(...)
local iter, code, msg = fs.dir(...)
if iter then
local t = nutil.consume(iter)
t[#t+1] = "."
t[#t+1] = ".."
return t
else
return nil, code, msg
end
end
--- Create a new directory, recursively on demand.
-- @param path String with the name or path of the directory to create
-- @param recursive Create multiple directory levels (optional, default is true)
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
function mkdir(path, recursive)
return recursive and fs.mkdirr(path) or fs.mkdir(path)
end
--- Remove the given empty directory.
-- @class function
-- @name rmdir
-- @param path String containing the path of the directory to remove
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
rmdir = fs.rmdir
local stat_tr = {
reg = "regular",
dir = "directory",
lnk = "link",
chr = "character device",
blk = "block device",
fifo = "fifo",
sock = "socket"
}
--- Get information about given file or directory.
-- @class function
-- @name stat
-- @param path String containing the path of the directory to query
-- @return Table containing file or directory properties or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
function stat(path, key)
local data, code, msg = fs.stat(path)
if data then
data.mode = data.modestr
data.type = stat_tr[data.type] or "?"
end
return key and data and data[key] or data, code, msg
end
--- Set permissions on given file or directory.
-- @class function
-- @name chmod
-- @param path String containing the path of the directory
-- @param perm String containing the permissions to set ([ugoa][+-][rwx])
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
chmod = fs.chmod
--- Create a hard- or symlink from given file (or directory) to specified target
-- file (or directory) path.
-- @class function
-- @name link
-- @param path1 String containing the source path to link
-- @param path2 String containing the destination path for the link
-- @param symlink Boolean indicating wheather to create a symlink (optional)
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
function link(src, dest, sym)
return sym and fs.symlink(src, dest) or fs.link(src, dest)
end
--- Remove the given file.
-- @class function
-- @name unlink
-- @param path String containing the path of the file to remove
-- @return Number with the return code, 0 on sucess or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
unlink = fs.unlink
--- Retrieve target of given symlink.
-- @class function
-- @name readlink
-- @param path String containing the path of the symlink to read
-- @return String containing the link target or nil on error
-- @return String containing the error description on error
-- @return Number containing the os specific errno on error
readlink = fs.readlink

336
Mi_Lua/luci/http.lua Normal file
View File

@ -0,0 +1,336 @@
--[[
LuCI - HTTP-Interaction
Description:
HTTP-Header manipulator and form variable preprocessor
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.
]]--
local ltn12 = require "luci.ltn12"
local protocol = require "luci.http.protocol"
local util = require "luci.util"
local string = require "string"
local coroutine = require "coroutine"
local table = require "table"
local ipairs, pairs, next, type, tostring, error =
ipairs, pairs, next, type, tostring, error
--- LuCI Web Framework high-level HTTP functions.
module ("luci.http", package.seeall)
context = util.threadlocal()
Request = util.class()
function Request.__init__(self, env, sourcein, sinkerr)
self.input = sourcein
self.error = sinkerr
-- File handler
self.filehandler = function() end
-- HTTP-Message table
self.message = {
env = env,
headers = {},
params = protocol.urldecode_params(env.QUERY_STRING or ""),
}
self.parsed_input = false
end
function Request.formvalue(self, name, noparse)
if not noparse and not self.parsed_input then
self:_parse_input()
end
if name then
return self.message.params[name]
else
return self.message.params
end
end
function Request.formvaluetable(self, prefix)
local vals = {}
prefix = prefix and prefix .. "." or "."
if not self.parsed_input then
self:_parse_input()
end
local void = self.message.params[nil]
for k, v in pairs(self.message.params) do
if k:find(prefix, 1, true) == 1 then
vals[k:sub(#prefix + 1)] = tostring(v)
end
end
return vals
end
function Request.content(self)
if not self.parsed_input then
self:_parse_input()
end
return self.message.content, self.message.content_length
end
function Request.getcookie(self, name)
local c = string.gsub(";" .. (self:getenv("HTTP_COOKIE") or "") .. ";", "%s*;%s*", ";")
local p = ";" .. name .. "=(.-);"
local i, j, value = c:find(p)
return value and urldecode(value)
end
function Request.getenv(self, name)
if name then
return self.message.env[name]
else
return self.message.env
end
end
function Request.setfilehandler(self, callback)
self.filehandler = callback
end
function Request._parse_input(self)
protocol.parse_message_body(
self.input,
self.message,
self.filehandler
)
self.parsed_input = true
end
--- Close the HTTP-Connection.
function close()
if not context.eoh then
context.eoh = true
coroutine.yield(3)
end
if not context.closed then
context.closed = true
coroutine.yield(5)
end
end
--- Return the request content if the request was of unknown type.
-- @return HTTP request body
-- @return HTTP request body length
function content()
return context.request:content()
end
--- Get a certain HTTP input value or a table of all input values.
-- @param name Name of the GET or POST variable to fetch
-- @param noparse Don't parse POST data before getting the value
-- @return HTTP input value or table of all input value
function formvalue(name, noparse)
return context.request:formvalue(name, noparse)
end
function xqformvalue(name, noparse)
local XQSecureUtil = require("xiaoqiang.util.XQSecureUtil")
local value = context.request:formvalue(name, noparse)
return XQSecureUtil.xssCheck(value)
end
--- Get a table of all HTTP input values with a certain prefix.
-- @param prefix Prefix
-- @return Table of all HTTP input values with given prefix
function formvaluetable(prefix)
return context.request:formvaluetable(prefix)
end
--- Get the value of a certain HTTP-Cookie.
-- @param name Cookie Name
-- @return String containing cookie data
function getcookie(name)
return context.request:getcookie(name)
end
--- Get the value of a certain HTTP environment variable
-- or the environment table itself.
-- @param name Environment variable
-- @return HTTP environment value or environment table
function getenv(name)
return context.request:getenv(name)
end
--- Set a handler function for incoming user file uploads.
-- @param callback Handler function
function setfilehandler(callback)
return context.request:setfilehandler(callback)
end
--- Send a HTTP-Header.
-- @param key Header key
-- @param value Header value
function header(key, value)
if not context.headers then
context.headers = {}
end
context.headers[key:lower()] = value
coroutine.yield(2, key, value)
end
--- Set the mime type of following content data.
-- @param mime Mimetype of following content
function prepare_content(mime)
if not context.headers or not context.headers["content-type"] then
if mime == "application/xhtml+xml" then
if not getenv("HTTP_ACCEPT") or
not getenv("HTTP_ACCEPT"):find("application/xhtml+xml", nil, true) then
mime = "text/html; charset=UTF-8"
end
header("Vary", "Accept")
end
header("Content-Type", mime)
end
end
--- Get the RAW HTTP input source
-- @return HTTP LTN12 source
function source()
return context.request.input
end
--- Set the HTTP status code and status message.
-- @param code Status code
-- @param message Status message
function status(code, message)
code = code or 200
message = message or "OK"
context.status = code
coroutine.yield(1, code, message)
end
--- Send a chunk of content data to the client.
-- This function is as a valid LTN12 sink.
-- If the content chunk is nil this function will automatically invoke close.
-- @param content Content chunk
-- @param src_err Error object from source (optional)
-- @see close
function write(content, src_err)
if not content then
if src_err then
error(src_err)
else
close()
end
return true
elseif #content == 0 then
return true
else
if not context.eoh then
if not context.status then
status()
end
if not context.headers or not context.headers["content-type"] then
header("Content-Type", "text/html; charset=utf-8")
end
if not context.headers["cache-control"] then
header("Cache-Control", "no-cache")
header("Expires", "0")
end
context.eoh = true
coroutine.yield(3)
end
coroutine.yield(4, content)
return true
end
end
--- Splice data from a filedescriptor to the client.
-- @param fp File descriptor
-- @param size Bytes to splice (optional)
function splice(fd, size)
coroutine.yield(6, fd, size)
end
--- Redirects the client to a new URL and closes the connection.
-- @param url Target URL
function redirect(url)
status(302, "Found")
header("Location", url)
close()
end
--- Create a querystring out of a table of key - value pairs.
-- @param table Query string source table
-- @return Encoded HTTP query string
function build_querystring(q)
local s = { "?" }
for k, v in pairs(q) do
if #s > 1 then s[#s+1] = "&" end
s[#s+1] = urldecode(k)
s[#s+1] = "="
s[#s+1] = urldecode(v)
end
return table.concat(s, "")
end
--- Return the URL-decoded equivalent of a string.
-- @param str URL-encoded string
-- @param no_plus Don't decode + to " "
-- @return URL-decoded string
-- @see urlencode
urldecode = protocol.urldecode
--- Return the URL-encoded equivalent of a string.
-- @param str Source string
-- @return URL-encoded string
-- @see urldecode
urlencode = protocol.urlencode
function writeJsonNoLog(x)
if x == nil then
write("null")
elseif type(x) == "table" then
local json = require("luci.json")
write(json.encode(x))
elseif type(x) == "number" or type(x) == "boolean" then
if (x ~= x) then
-- NaN is the only value that doesn't equal to itself.
write("Number.NaN")
else
write(tostring(x))
end
else
write('"%s"' % tostring(x):gsub('["%z\1-\31]', function(c)
return '\\u%04x' % c:byte(1)
end))
end
end
--- Send the given data as JSON encoded string.
-- @param data Data to send
function write_json(x)
local XQLog = require("xiaoqiang.XQLog")
XQLog.log(7,x)
writeJsonNoLog(x)
end

View File

@ -0,0 +1,727 @@
--[[
HTTP protocol implementation for LuCI
(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
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: protocol.lua 9195 2012-08-29 13:06:58Z jow $
]]--
--- LuCI http protocol class.
-- This class contains several functions useful for http message- and content
-- decoding and to retrive form data from raw http messages.
module("luci.http.protocol", package.seeall)
local util = require "luci.util"
local ltn12 = require("luci.ltn12")
HTTP_MAX_CONTENT = 1024*32 -- 8 kB maximum content size
--- Decode an urlencoded string - optionally without decoding
-- the "+" sign to " " - and return the decoded string.
-- @param str Input string in x-www-urlencoded format
-- @param no_plus Don't decode "+" signs to spaces
-- @return The decoded string
-- @see urlencode
function urldecode( str, no_plus )
local function __chrdec( hex )
return string.char( tonumber( hex, 16 ) )
end
if type(str) == "string" then
if not no_plus then
str = str:gsub( "+", " " )
end
str = str:gsub( "%%([a-fA-F0-9][a-fA-F0-9])", __chrdec )
end
return str
end
--- Extract and split urlencoded data pairs, separated bei either "&" or ";"
-- from given url or string. Returns a table with urldecoded values.
-- Simple parameters are stored as string values associated with the parameter
-- name within the table. Parameters with multiple values are stored as array
-- containing the corresponding values.
-- @param url The url or string which contains x-www-urlencoded form data
-- @param tbl Use the given table for storing values (optional)
-- @return Table containing the urldecoded parameters
-- @see urlencode_params
function urldecode_params( url, tbl )
local params = tbl or { }
if url:find("?") then
url = url:gsub( "^.+%?([^?]+)", "%1" )
end
for pair in url:gmatch( "[^&;]+" ) do
-- find key and value
local key = urldecode( pair:match("^([^=]+)") )
local val = urldecode( pair:match("^[^=]+=(.+)$") )
-- store
if type(key) == "string" and key:len() > 0 then
if type(val) ~= "string" then val = "" end
if not params[key] then
params[key] = val
elseif type(params[key]) ~= "table" then
params[key] = { params[key], val }
else
table.insert( params[key], val )
end
end
end
return params
end
--- Encode given string to x-www-urlencoded format.
-- @param str String to encode
-- @return String containing the encoded data
-- @see urldecode
function urlencode( str )
local function __chrenc( chr )
return string.format(
"%%%02x", string.byte( chr )
)
end
if type(str) == "string" then
str = str:gsub(
"([^a-zA-Z0-9$_%-%.%+!*'(),])",
__chrenc
)
end
return str
end
function xqurlencode(str)
if (str) then
--Ensure all newlines are in CRLF form
str = string.gsub (str, "\r?\n", "\r\n")
--Percent-encode all non-unreserved characters
--as per RFC 3986, Section 2.3
--(except for space, which gets plus-encoded)
str = string.gsub (str, "([^%w%-%.%_%~ ])",
function (c) return string.format ("%%%02X", string.byte(c)) end)
--Convert spaces to plus signs
str = string.gsub (str, " ", "+")
end
return str
end
function xq_urlencode_params( tbl )
local enc = ""
for k, v in pairs(tbl) do
if type(v) == "table" then
for i, v2 in ipairs(v) do
enc = enc .. ( #enc > 0 and "&" or "" ) ..
urlencode(k) .. "=" .. xqurlencode(v2)
end
else
enc = (enc .. ( #enc > 0 and "&" or "" ) ..
urlencode(k) .. "=" .. xqurlencode(v))
end
end
return enc
end
--- Encode each key-value-pair in given table to x-www-urlencoded format,
-- separated by "&". Tables are encoded as parameters with multiple values by
-- repeating the parameter name with each value.
-- @param tbl Table with the values
-- @return String containing encoded values
-- @see urldecode_params
function urlencode_params( tbl )
local enc = ""
for k, v in pairs(tbl) do
if type(v) == "table" then
for i, v2 in ipairs(v) do
enc = enc .. ( #enc > 0 and "&" or "" ) ..
urlencode(k) .. "=" .. urlencode(v2)
end
else
enc = (enc .. ( #enc > 0 and "&" or "" ) ..
urlencode(k) .. "=" .. urlencode(v))
end
end
return enc
end
-- (Internal function)
-- Initialize given parameter and coerce string into table when the parameter
-- already exists.
-- @param tbl Table where parameter should be created
-- @param key Parameter name
-- @return Always nil
local function __initval( tbl, key )
if tbl[key] == nil then
tbl[key] = ""
elseif type(tbl[key]) == "string" then
tbl[key] = { tbl[key], "" }
else
table.insert( tbl[key], "" )
end
end
-- (Internal function)
-- Append given data to given parameter, either by extending the string value
-- or by appending it to the last string in the parameter's value table.
-- @param tbl Table containing the previously initialized parameter value
-- @param key Parameter name
-- @param chunk String containing the data to append
-- @return Always nil
-- @see __initval
local function __appendval( tbl, key, chunk )
if type(tbl[key]) == "table" then
tbl[key][#tbl[key]] = tbl[key][#tbl[key]] .. chunk
else
tbl[key] = tbl[key] .. chunk
end
end
-- (Internal function)
-- Finish the value of given parameter, either by transforming the string value
-- or - in the case of multi value parameters - the last element in the
-- associated values table.
-- @param tbl Table containing the previously initialized parameter value
-- @param key Parameter name
-- @param handler Function which transforms the parameter value
-- @return Always nil
-- @see __initval
-- @see __appendval
local function __finishval( tbl, key, handler )
if handler then
if type(tbl[key]) == "table" then
tbl[key][#tbl[key]] = handler( tbl[key][#tbl[key]] )
else
tbl[key] = handler( tbl[key] )
end
end
end
-- Table of our process states
local process_states = { }
-- Extract "magic", the first line of a http message.
-- Extracts the message type ("get", "post" or "response"), the requested uri
-- or the status code if the line descripes a http response.
process_states['magic'] = function( msg, chunk, err )
if chunk ~= nil then
-- ignore empty lines before request
if #chunk == 0 then
return true, nil
end
-- Is it a request?
local method, uri, http_ver = chunk:match("^([A-Z]+) ([^ ]+) HTTP/([01]%.[019])$")
-- Yup, it is
if method then
msg.type = "request"
msg.request_method = method:lower()
msg.request_uri = uri
msg.http_version = tonumber( http_ver )
msg.headers = { }
-- We're done, next state is header parsing
return true, function( chunk )
return process_states['headers']( msg, chunk )
end
-- Is it a response?
else
local http_ver, code, message = chunk:match("^HTTP/([01]%.[019]) ([0-9]+) ([^\r\n]+)$")
-- Is a response
if code then
msg.type = "response"
msg.status_code = code
msg.status_message = message
msg.http_version = tonumber( http_ver )
msg.headers = { }
-- We're done, next state is header parsing
return true, function( chunk )
return process_states['headers']( msg, chunk )
end
end
end
end
-- Can't handle it
return nil, "Invalid HTTP message magic"
end
-- Extract headers from given string.
process_states['headers'] = function( msg, chunk )
if chunk ~= nil then
-- Look for a valid header format
local hdr, val = chunk:match( "^([A-Za-z][A-Za-z0-9%-_]+): +(.+)$" )
if type(hdr) == "string" and hdr:len() > 0 and
type(val) == "string" and val:len() > 0
then
msg.headers[hdr] = val
-- Valid header line, proceed
return true, nil
elseif #chunk == 0 then
-- Empty line, we won't accept data anymore
return false, nil
else
-- Junk data
return nil, "Invalid HTTP header received"
end
else
return nil, "Unexpected EOF"
end
end
--- Creates a ltn12 source from the given socket. The source will return it's
-- data line by line with the trailing \r\n stripped of.
-- @param sock Readable network socket
-- @return Ltn12 source function
function header_source( sock )
return ltn12.source.simplify( function()
local chunk, err, part = sock:receive("*l")
-- Line too long
if chunk == nil then
if err ~= "timeout" then
return nil, part
and "Line exceeds maximum allowed length"
or "Unexpected EOF"
else
return nil, err
end
-- Line ok
elseif chunk ~= nil then
-- Strip trailing CR
chunk = chunk:gsub("\r$","")
return chunk, nil
end
end )
end
--- Decode a mime encoded http message body with multipart/form-data
-- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table withing the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
-- If an optional file callback function is given then it is feeded with the
-- file contents chunk by chunk and only the extracted file name is stored
-- within the params table. The callback function will be called subsequently
-- with three arguments:
-- o Table containing decoded (name, file) and raw (headers) mime header data
-- o String value containing a chunk of the file data
-- o Boolean which indicates wheather the current chunk is the last one (eof)
-- @param src Ltn12 source function
-- @param msg HTTP message object
-- @param filecb File callback function (optional)
-- @return Value indicating successful operation (not nil means "ok")
-- @return String containing the error if unsuccessful
-- @see parse_message_header
function mimedecode_message_body( src, msg, filecb )
if msg and msg.env.CONTENT_TYPE then
msg.mime_boundary = msg.env.CONTENT_TYPE:match("^multipart/form%-data; boundary=(.+)$")
end
if not msg.mime_boundary then
return nil, "Invalid Content-Type found"
end
local tlen = 0
local inhdr = false
local field = nil
local store = nil
local lchunk = nil
local function parse_headers( chunk, field )
local stat
repeat
chunk, stat = chunk:gsub(
"^([A-Z][A-Za-z0-9%-_]+): +([^\r\n]+)\r\n",
function(k,v)
field.headers[k] = v
return ""
end
)
until stat == 0
chunk, stat = chunk:gsub("^\r\n","")
-- End of headers
if stat > 0 then
if field.headers["Content-Disposition"] then
if field.headers["Content-Disposition"]:match("^form%-data; ") then
field.name = field.headers["Content-Disposition"]:match('name="(.-)"')
field.file = field.headers["Content-Disposition"]:match('filename="(.+)"$')
end
end
if not field.headers["Content-Type"] then
field.headers["Content-Type"] = "text/plain"
end
if field.name and field.file and filecb then
__initval( msg.params, field.name )
__appendval( msg.params, field.name, field.file )
store = filecb
elseif field.name then
__initval( msg.params, field.name )
store = function( hdr, buf, eof )
__appendval( msg.params, field.name, buf )
end
else
store = nil
end
return chunk, true
end
return chunk, false
end
local function snk( chunk )
tlen = tlen + ( chunk and #chunk or 0 )
if msg.env.CONTENT_LENGTH and tlen > tonumber(msg.env.CONTENT_LENGTH) + 2 then
return nil, "Message body size exceeds Content-Length"
end
if chunk and not lchunk then
lchunk = "\r\n" .. chunk
elseif lchunk then
local data = lchunk .. ( chunk or "" )
local spos, epos, found
repeat
spos, epos = data:find( "\r\n--" .. msg.mime_boundary .. "\r\n", 1, true )
if not spos then
spos, epos = data:find( "\r\n--" .. msg.mime_boundary .. "--\r\n", 1, true )
end
if spos then
local predata = data:sub( 1, spos - 1 )
if inhdr then
predata, eof = parse_headers( predata, field )
if not eof then
return nil, "Invalid MIME section header"
elseif not field.name then
return nil, "Invalid Content-Disposition header"
end
end
if store then
store( field, predata, true )
end
field = { headers = { } }
found = found or true
data, eof = parse_headers( data:sub( epos + 1, #data ), field )
inhdr = not eof
end
until not spos
if found then
-- We found at least some boundary. Save
-- the unparsed remaining data for the
-- next chunk.
lchunk, data = data, nil
else
-- There was a complete chunk without a boundary. Parse it as headers or
-- append it as data, depending on our current state.
if inhdr then
lchunk, eof = parse_headers( data, field )
inhdr = not eof
else
-- We're inside data, so append the data. Note that we only append
-- lchunk, not all of data, since there is a chance that chunk
-- contains half a boundary. Assuming that each chunk is at least the
-- boundary in size, this should prevent problems
store( field, lchunk, false )
lchunk, chunk = chunk, nil
end
end
end
return true
end
return ltn12.pump.all( src, snk )
end
--- Decode an urlencoded http message body with application/x-www-urlencoded
-- Content-Type. Stores all extracted data associated with its parameter name
-- in the params table withing the given message object. Multiple parameter
-- values are stored as tables, ordinary ones as strings.
-- @param src Ltn12 source function
-- @param msg HTTP message object
-- @return Value indicating successful operation (not nil means "ok")
-- @return String containing the error if unsuccessful
-- @see parse_message_header
function urldecode_message_body( src, msg )
local tlen = 0
local lchunk = nil
local function snk( chunk )
tlen = tlen + ( chunk and #chunk or 0 )
if msg.env.CONTENT_LENGTH and tlen > tonumber(msg.env.CONTENT_LENGTH) + 2 then
return nil, "Message body size exceeds Content-Length"
elseif tlen > HTTP_MAX_CONTENT then
return nil, "Message body size exceeds maximum allowed length"
end
if not lchunk and chunk then
lchunk = chunk
elseif lchunk then
local data = lchunk .. ( chunk or "&" )
local spos, epos
repeat
spos, epos = data:find("^.-[;&]")
if spos then
local pair = data:sub( spos, epos - 1 )
local key = pair:match("^(.-)=")
local val = pair:match("=([^%s]*)%s*$")
if key and #key > 0 then
__initval( msg.params, key )
__appendval( msg.params, key, val )
__finishval( msg.params, key, urldecode )
else
key = "invalid_param"
__initval( msg.params, key )
__appendval( msg.params, key, pair )
__finishval( msg.params, key, urldecode )
end
data = data:sub( epos + 1, #data )
end
until not spos
lchunk = data
end
return true
end
return ltn12.pump.all( src, snk )
end
--- Try to extract an http message header including information like protocol
-- version, message headers and resulting CGI environment variables from the
-- given ltn12 source.
-- @param src Ltn12 source function
-- @return HTTP message object
-- @see parse_message_body
function parse_message_header( src )
local ok = true
local msg = { }
local sink = ltn12.sink.simplify(
function( chunk )
return process_states['magic']( msg, chunk )
end
)
-- Pump input data...
while ok do
-- get data
ok, err = ltn12.pump.step( src, sink )
-- error
if not ok and err then
return nil, err
-- eof
elseif not ok then
-- Process get parameters
if ( msg.request_method == "get" or msg.request_method == "post" ) and
msg.request_uri:match("?")
then
msg.params = urldecode_params( msg.request_uri )
else
msg.params = { }
end
-- Populate common environment variables
msg.env = {
CONTENT_LENGTH = msg.headers['Content-Length'];
CONTENT_TYPE = msg.headers['Content-Type'] or msg.headers['Content-type'];
REQUEST_METHOD = msg.request_method:upper();
REQUEST_URI = msg.request_uri;
SCRIPT_NAME = msg.request_uri:gsub("?.+$","");
SCRIPT_FILENAME = ""; -- XXX implement me
SERVER_PROTOCOL = "HTTP/" .. string.format("%.1f", msg.http_version);
QUERY_STRING = msg.request_uri:match("?")
and msg.request_uri:gsub("^.+?","") or ""
}
-- Populate HTTP_* environment variables
for i, hdr in ipairs( {
'Accept',
'Accept-Charset',
'Accept-Encoding',
'Accept-Language',
'Connection',
'Cookie',
'Host',
'Referer',
'User-Agent',
} ) do
local var = 'HTTP_' .. hdr:upper():gsub("%-","_")
local val = msg.headers[hdr]
msg.env[var] = val
end
end
end
return msg
end
--- Try to extract and decode a http message body from the given ltn12 source.
-- This function will examine the Content-Type within the given message object
-- to select the appropriate content decoder.
-- Currently the application/x-www-urlencoded and application/form-data
-- mime types are supported. If the encountered content encoding can't be
-- handled then the whole message body will be stored unaltered as "content"
-- property within the given message object.
-- @param src Ltn12 source function
-- @param msg HTTP message object
-- @param filecb File data callback (optional, see mimedecode_message_body())
-- @return Value indicating successful operation (not nil means "ok")
-- @return String containing the error if unsuccessful
-- @see parse_message_header
function parse_message_body( src, msg, filecb )
-- Is it multipart/mime ?
if msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE and
msg.env.CONTENT_TYPE:match("^multipart/form%-data")
then
return mimedecode_message_body( src, msg, filecb )
-- Is it application/x-www-form-urlencoded ?
elseif msg.env.REQUEST_METHOD == "POST" and msg.env.CONTENT_TYPE and
msg.env.CONTENT_TYPE:match("^application/x%-www%-form%-urlencoded")
then
return urldecode_message_body( src, msg, filecb )
-- Unhandled encoding
-- If a file callback is given then feed it chunk by chunk, else
-- store whole buffer in message.content
else
local sink
-- If we have a file callback then feed it
if type(filecb) == "function" then
sink = filecb
-- ... else append to .content
else
msg.content = ""
msg.content_length = 0
sink = function( chunk, err )
if chunk then
if ( msg.content_length + #chunk ) <= HTTP_MAX_CONTENT then
msg.content = msg.content .. chunk
msg.content_length = msg.content_length + #chunk
return true
else
return nil, "POST data exceeds maximum allowed length"
end
end
return true
end
end
-- Pump data...
while true do
local ok, err = ltn12.pump.step( src, sink )
if not ok and err then
return nil, err
elseif not err then
return true
end
end
return true
end
end
--- Table containing human readable messages for several http status codes.
-- @class table
statusmsg = {
[200] = "OK",
[206] = "Partial Content",
[301] = "Moved Permanently",
[302] = "Found",
[304] = "Not Modified",
[400] = "Bad Request",
[403] = "Forbidden",
[404] = "Not Found",
[405] = "Method Not Allowed",
[408] = "Request Time-out",
[411] = "Length Required",
[412] = "Precondition Failed",
[416] = "Requested range not satisfiable",
[500] = "Internal Server Error",
[503] = "Server Unavailable",
}

View File

@ -0,0 +1,153 @@
--[[
HTTP protocol implementation for LuCI - RFC2616 / 14.19, 14.24 - 14.28
(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
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: conditionals.lua 5637 2009-12-20 18:35:05Z jow $
]]--
--- LuCI http protocol implementation - HTTP/1.1 bits.
-- This class provides basic ETag handling and implements most of the
-- conditional HTTP/1.1 headers specified in RFC2616 Sct. 14.24 - 14.28 .
module("luci.http.protocol.conditionals", package.seeall)
local date = require("luci.http.protocol.date")
--- Implement 14.19 / ETag.
-- @param stat A file.stat structure
-- @return String containing the generated tag suitable for ETag headers
function mk_etag( stat )
if stat ~= nil then
return string.format( '"%x-%x-%x"', stat.ino, stat.size, stat.mtime )
end
end
--- 14.24 / If-Match
-- Test whether the given message object contains an "If-Match" header and
-- compare it against the given stat object.
-- @param req HTTP request message object
-- @param stat A file.stat object
-- @return Boolean indicating whether the precondition is ok
-- @return Alternative status code if the precondition failed
function if_match( req, stat )
local h = req.headers
local etag = mk_etag( stat )
-- Check for matching resource
if type(h['If-Match']) == "string" then
for ent in h['If-Match']:gmatch("([^, ]+)") do
if ( ent == '*' or ent == etag ) and stat ~= nil then
return true
end
end
return false, 412
end
return true
end
--- 14.25 / If-Modified-Since
-- Test whether the given message object contains an "If-Modified-Since" header
-- and compare it against the given stat object.
-- @param req HTTP request message object
-- @param stat A file.stat object
-- @return Boolean indicating whether the precondition is ok
-- @return Alternative status code if the precondition failed
-- @return Table containing extra HTTP headers if the precondition failed
function if_modified_since( req, stat )
local h = req.headers
-- Compare mtimes
if type(h['If-Modified-Since']) == "string" then
local since = date.to_unix( h['If-Modified-Since'] )
if stat == nil or since < stat.mtime then
return true
end
return false, 304, {
["ETag"] = mk_etag( stat );
["Date"] = date.to_http( os.time() );
["Last-Modified"] = date.to_http( stat.mtime )
}
end
return true
end
--- 14.26 / If-None-Match
-- Test whether the given message object contains an "If-None-Match" header and
-- compare it against the given stat object.
-- @param req HTTP request message object
-- @param stat A file.stat object
-- @return Boolean indicating whether the precondition is ok
-- @return Alternative status code if the precondition failed
-- @return Table containing extra HTTP headers if the precondition failed
function if_none_match( req, stat )
local h = req.headers
local etag = mk_etag( stat )
local method = req.env and req.env.REQUEST_METHOD or "GET"
-- Check for matching resource
if type(h['If-None-Match']) == "string" then
for ent in h['If-None-Match']:gmatch("([^, ]+)") do
if ( ent == '*' or ent == etag ) and stat ~= nil then
if method == "GET" or method == "HEAD" then
return false, 304, {
["ETag"] = etag;
["Date"] = date.to_http( os.time() );
["Last-Modified"] = date.to_http( stat.mtime )
}
else
return false, 412
end
end
end
end
return true
end
--- 14.27 / If-Range
-- The If-Range header is currently not implemented due to the lack of general
-- byte range stuff in luci.http.protocol . This function will always return
-- false, 412 to indicate a failed precondition.
-- @param req HTTP request message object
-- @param stat A file.stat object
-- @return Boolean indicating whether the precondition is ok
-- @return Alternative status code if the precondition failed
function if_range( req, stat )
-- Sorry, no subranges (yet)
return false, 412
end
--- 14.28 / If-Unmodified-Since
-- Test whether the given message object contains an "If-Unmodified-Since"
-- header and compare it against the given stat object.
-- @param req HTTP request message object
-- @param stat A file.stat object
-- @return Boolean indicating whether the precondition is ok
-- @return Alternative status code if the precondition failed
function if_unmodified_since( req, stat )
local h = req.headers
-- Compare mtimes
if type(h['If-Unmodified-Since']) == "string" then
local since = date.to_unix( h['If-Unmodified-Since'] )
if stat ~= nil and since <= stat.mtime then
return false, 412
end
end
return true
end

View File

@ -0,0 +1,115 @@
--[[
HTTP protocol implementation for LuCI - date handling
(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
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: date.lua 3860 2008-12-06 03:18:14Z jow $
]]--
--- LuCI http protocol implementation - date helper class.
-- This class contains functions to parse, compare and format http dates.
module("luci.http.protocol.date", package.seeall)
require("luci.sys.zoneinfo")
MONTHS = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"
}
--- Return the time offset in seconds between the UTC and given time zone.
-- @param tz Symbolic or numeric timezone specifier
-- @return Time offset to UTC in seconds
function tz_offset(tz)
if type(tz) == "string" then
-- check for a numeric identifier
local s, v = tz:match("([%+%-])([0-9]+)")
if s == '+' then s = 1 else s = -1 end
if v then v = tonumber(v) end
if s and v then
return s * 60 * ( math.floor( v / 100 ) * 60 + ( v % 100 ) )
-- lookup symbolic tz
elseif luci.sys.zoneinfo.OFFSET[tz:lower()] then
return luci.sys.zoneinfo.OFFSET[tz:lower()]
end
end
-- bad luck
return 0
end
--- Parse given HTTP date string and convert it to unix epoch time.
-- @param data String containing the date
-- @return Unix epoch time
function to_unix(date)
local wd, day, mon, yr, hr, min, sec, tz = date:match(
"([A-Z][a-z][a-z]), ([0-9]+) " ..
"([A-Z][a-z][a-z]) ([0-9]+) " ..
"([0-9]+):([0-9]+):([0-9]+) " ..
"([A-Z0-9%+%-]+)"
)
if day and mon and yr and hr and min and sec then
-- find month
local month = 1
for i = 1, 12 do
if MONTHS[i] == mon then
month = i
break
end
end
-- convert to epoch time
return tz_offset(tz) + os.time( {
year = yr,
month = month,
day = day,
hour = hr,
min = min,
sec = sec
} )
end
return 0
end
--- Convert the given unix epoch time to valid HTTP date string.
-- @param time Unix epoch time
-- @return String containing the formatted date
function to_http(time)
return os.date( "%a, %d %b %Y %H:%M:%S GMT", time )
end
--- Compare two dates which can either be unix epoch times or HTTP date strings.
-- @param d1 The first date or epoch time to compare
-- @param d2 The first date or epoch time to compare
-- @return -1 - if d1 is lower then d2
-- @return 0 - if both dates are equal
-- @return 1 - if d1 is higher then d2
function compare(d1, d2)
if d1:match("[^0-9]") then d1 = to_unix(d1) end
if d2:match("[^0-9]") then d2 = to_unix(d2) end
if d1 == d2 then
return 0
elseif d1 < d2 then
return -1
else
return 1
end
end

View File

@ -0,0 +1,99 @@
--[[
HTTP protocol implementation for LuCI - mime handling
(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
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: mime.lua 5327 2009-09-11 01:55:10Z jow $
]]--
--- LuCI http protocol implementation - mime helper class.
-- This class provides functions to guess mime types from file extensions and
-- vice versa.
module("luci.http.protocol.mime", package.seeall)
require("luci.util")
--- MIME mapping table containg extension - mimetype relations.
-- @class table
MIME_TYPES = {
["txt"] = "text/plain";
["js"] = "text/javascript";
["css"] = "text/css";
["htm"] = "text/html";
["html"] = "text/html";
["patch"] = "text/x-patch";
["c"] = "text/x-csrc";
["h"] = "text/x-chdr";
["o"] = "text/x-object";
["ko"] = "text/x-object";
["bmp"] = "image/bmp";
["gif"] = "image/gif";
["png"] = "image/png";
["jpg"] = "image/jpeg";
["jpeg"] = "image/jpeg";
["svg"] = "image/svg+xml";
["zip"] = "application/zip";
["pdf"] = "application/pdf";
["xml"] = "application/xml";
["xsl"] = "application/xml";
["doc"] = "application/msword";
["ppt"] = "application/vnd.ms-powerpoint";
["xls"] = "application/vnd.ms-excel";
["odt"] = "application/vnd.oasis.opendocument.text";
["odp"] = "application/vnd.oasis.opendocument.presentation";
["pl"] = "application/x-perl";
["sh"] = "application/x-shellscript";
["php"] = "application/x-php";
["deb"] = "application/x-deb";
["iso"] = "application/x-cd-image";
["tgz"] = "application/x-compressed-tar";
["mp3"] = "audio/mpeg";
["ogg"] = "audio/x-vorbis+ogg";
["wav"] = "audio/x-wav";
["mpg"] = "video/mpeg";
["mpeg"] = "video/mpeg";
["avi"] = "video/x-msvideo";
}
--- Extract extension from a filename and return corresponding mime-type or
-- "application/octet-stream" if the extension is unknown.
-- @param filename The filename for which the mime type is guessed
-- @return String containign the determined mime type
function to_mime(filename)
if type(filename) == "string" then
local ext = filename:match("[^%.]+$")
if ext and MIME_TYPES[ext:lower()] then
return MIME_TYPES[ext:lower()]
end
end
return "application/octet-stream"
end
--- Return corresponding extension for a given mime type or nil if the
-- given mime-type is unknown.
-- @param mimetype The mimetype to retrieve the extension from
-- @return String with the extension or nil for unknown type
function to_ext(mimetype)
if type(mimetype) == "string" then
for ext, type in luci.util.kspairs( MIME_TYPES ) do
if type == mimetype then
return ext
end
end
end
return nil
end

104
Mi_Lua/luci/i18n.lua Normal file
View File

@ -0,0 +1,104 @@
--[[
LuCI - Internationalisation
Description:
A very minimalistic but yet effective internationalisation module
FileId:
$Id: i18n.lua 9558 2012-12-18 13:58:22Z jow $
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 translation library.
module("luci.i18n", package.seeall)
require("luci.util")
local tparser = require "luci.template.parser"
table = {}
i18ndir = luci.util.libpath() .. "/i18n/"
loaded = {}
context = luci.util.threadlocal()
default = "en"
--- Clear the translation table.
function clear()
end
--- Load a translation and copy its data into the translation table.
-- @param file Language file
-- @param lang Two-letter language code
-- @param force Force reload even if already loaded (optional)
-- @return Success status
function load(file, lang, force)
end
--- Load a translation file using the default translation language.
-- Alternatively load the translation of the fallback language.
-- @param file Language file
-- @param force Force reload even if already loaded (optional)
function loadc(file, force)
end
--- Set the context default translation language.
-- @param lang Two-letter language code
function setlanguage(lang)
context.lang = lang:gsub("_", "-")
context.parent = (context.lang:match("^([a-z][a-z])_"))
if not tparser.load_catalog(context.lang, i18ndir) then
if context.parent then
tparser.load_catalog(context.parent, i18ndir)
return context.parent
end
end
return context.lang
end
--- Return the translated value for a specific translation key.
-- @param key Default translation text
-- @return Translated string
function translate(key)
return tparser.translate(key) or key
end
--- Return the translated value for a specific translation key and use it as sprintf pattern.
-- @param key Default translation text
-- @param ... Format parameters
-- @return Translated and formatted string
function translatef(key, ...)
return tostring(translate(key)):format(...)
end
--- Return the translated value for a specific translation key
-- and ensure that the returned value is a Lua string value.
-- This is the same as calling <code>tostring(translate(...))</code>
-- @param key Default translation text
-- @return Translated string
function string(key)
return tostring(translate(key))
end
--- Return the translated value for a specific translation key and use it as sprintf pattern.
-- Ensure that the returned value is a Lua string value.
-- This is the same as calling <code>tostring(translatef(...))</code>
-- @param key Default translation text
-- @param ... Format parameters
-- @return Translated and formatted string
function stringf(key, ...)
return tostring(translate(key)):format(...)
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More