From 813f8d93e503d7147e64ac2668371ba5e4a6f715 Mon Sep 17 00:00:00 2001 From: JamesonHuang <462430725@qq.com> Date: Fri, 15 May 2015 16:24:51 +0800 Subject: [PATCH] adj2 --- Me_Lua/R10-WIFI.lua | 73 - Me_Lua/h10/MZLog.lua | 14 - Me_Lua/h10/Posix.lua | 113 - Me_Lua/h10/cjson.so | Bin 30666 -> 0 bytes Me_Lua/h10/lfs.so | Bin 16916 -> 0 bytes Me_Lua/h10/lsqlite3.so | Bin 40103 -> 0 bytes Me_Lua/h10/ltn12.lua | 305 -- Me_Lua/h10/luci/controller/admin/network.lua | 610 ---- Me_Lua/h10/luci/controller/api/index.lua | 308 -- Me_Lua/h10/luci/controller/bs/index.lua | 149 - Me_Lua/h10/luci/dispatcher.lua | 965 ------ Me_Lua/h10/luci/model/network.lua | 1632 ---------- Me_Lua/h10/luci/sauth.lua | 200 -- Me_Lua/h10/meizu/arpmon.lua | 99 - Me_Lua/h10/meizu/bfs.lua | 511 --- Me_Lua/h10/meizu/btfs.lua | 1442 --------- Me_Lua/h10/meizu/dbfs.lua | 604 ---- Me_Lua/h10/meizu/disk.lua | 63 - Me_Lua/h10/meizu/dlfs.lua | 670 ---- Me_Lua/h10/meizu/nwfs.lua | 1878 ----------- Me_Lua/h10/meizu/r10config.lua | 3 - Me_Lua/h10/meizu/sipfs.lua | 906 ------ Me_Lua/h10/meizu/upgdfs.lua | 256 -- Me_Lua/h10/mime.lua | 90 - Me_Lua/h10/mime.so.1.0.3 | Bin 84630 -> 0 bytes Me_Lua/h10/mime/core.so | Bin 84630 -> 0 bytes Me_Lua/h10/posix.so | Bin 34716 -> 0 bytes Me_Lua/h10/routerReport.lua | 144 - Me_Lua/h10/socket.lua | 149 - Me_Lua/h10/socket.so.3.0-rc1 | Bin 289771 -> 0 bytes Me_Lua/h10/socket/core.so | Bin 289771 -> 0 bytes Me_Lua/h10/socket/ftp.lua | 285 -- Me_Lua/h10/socket/headers.lua | 104 - Me_Lua/h10/socket/http.lua | 356 --- Me_Lua/h10/socket/smtp.lua | 256 -- Me_Lua/h10/socket/tp.lua | 126 - Me_Lua/h10/socket/url.lua | 307 -- Me_Lua/h10/ssl.lua | 168 - Me_Lua/h10/ssl.so | Bin 53826 -> 0 bytes Me_Lua/h10/ssl/https.lua | 138 - Me_Lua/h13/MZLog.lua | 14 - Me_Lua/h13/Posix.lua | 113 - Me_Lua/h13/cjson.so | Bin 37404 -> 0 bytes Me_Lua/h13/lfs.so | Bin 20493 -> 0 bytes Me_Lua/h13/lsqlite3.so | Bin 53091 -> 0 bytes Me_Lua/h13/ltn12.lua | 305 -- Me_Lua/h13/luci/controller/admin/network.lua | 611 ---- Me_Lua/h13/luci/controller/api/index.lua | 243 -- Me_Lua/h13/luci/controller/bs/index.lua | 105 - Me_Lua/h13/luci/dispatcher.lua | 965 ------ Me_Lua/h13/luci/model/network.lua | 1632 ---------- Me_Lua/h13/luci/sauth.lua | 200 -- Me_Lua/h13/meizu/arpmon.lua | 103 - Me_Lua/h13/meizu/bfs.lua | 370 --- Me_Lua/h13/meizu/build.sh | 5 - Me_Lua/h13/meizu/dbfs.lua | 410 --- Me_Lua/h13/meizu/nwfs.lua | 2920 ------------------ Me_Lua/h13/meizu/r10config.lua | 3 - Me_Lua/h13/meizu/sipfs.lua | 690 ----- Me_Lua/h13/meizu/upgdfs.lua | 231 -- Me_Lua/h13/mime.lua | 90 - Me_Lua/h13/mime.so.1.0.3 | Bin 10200 -> 0 bytes Me_Lua/h13/mime/core.so | Bin 86651 -> 0 bytes Me_Lua/h13/posix.so | Bin 45066 -> 0 bytes Me_Lua/h13/routerReport.lua | 136 - Me_Lua/h13/socket.lua | 149 - Me_Lua/h13/socket.so.3.0-rc1 | Bin 36276 -> 0 bytes Me_Lua/h13/socket/core.so | Bin 306460 -> 0 bytes Me_Lua/h13/socket/ftp.lua | 285 -- Me_Lua/h13/socket/headers.lua | 104 - Me_Lua/h13/socket/http.lua | 356 --- Me_Lua/h13/socket/smtp.lua | 256 -- Me_Lua/h13/socket/tp.lua | 126 - Me_Lua/h13/socket/url.lua | 307 -- Me_Lua/h13/ssl.lua | 168 - Me_Lua/h13/ssl.so | Bin 67881 -> 0 bytes Me_Lua/h13/ssl/https.lua | 138 - Me_Lua/h13/tags | 670 ---- 78 files changed, 24629 deletions(-) delete mode 100644 Me_Lua/R10-WIFI.lua delete mode 100644 Me_Lua/h10/MZLog.lua delete mode 100644 Me_Lua/h10/Posix.lua delete mode 100644 Me_Lua/h10/cjson.so delete mode 100755 Me_Lua/h10/lfs.so delete mode 100644 Me_Lua/h10/lsqlite3.so delete mode 100644 Me_Lua/h10/ltn12.lua delete mode 100644 Me_Lua/h10/luci/controller/admin/network.lua delete mode 100644 Me_Lua/h10/luci/controller/api/index.lua delete mode 100644 Me_Lua/h10/luci/controller/bs/index.lua delete mode 100644 Me_Lua/h10/luci/dispatcher.lua delete mode 100644 Me_Lua/h10/luci/model/network.lua delete mode 100644 Me_Lua/h10/luci/sauth.lua delete mode 100644 Me_Lua/h10/meizu/arpmon.lua delete mode 100644 Me_Lua/h10/meizu/bfs.lua delete mode 100644 Me_Lua/h10/meizu/btfs.lua delete mode 100644 Me_Lua/h10/meizu/dbfs.lua delete mode 100644 Me_Lua/h10/meizu/disk.lua delete mode 100644 Me_Lua/h10/meizu/dlfs.lua delete mode 100644 Me_Lua/h10/meizu/nwfs.lua delete mode 100644 Me_Lua/h10/meizu/r10config.lua delete mode 100644 Me_Lua/h10/meizu/sipfs.lua delete mode 100644 Me_Lua/h10/meizu/upgdfs.lua delete mode 100644 Me_Lua/h10/mime.lua delete mode 100644 Me_Lua/h10/mime.so.1.0.3 delete mode 100644 Me_Lua/h10/mime/core.so delete mode 100644 Me_Lua/h10/posix.so delete mode 100644 Me_Lua/h10/routerReport.lua delete mode 100644 Me_Lua/h10/socket.lua delete mode 100644 Me_Lua/h10/socket.so.3.0-rc1 delete mode 100644 Me_Lua/h10/socket/core.so delete mode 100644 Me_Lua/h10/socket/ftp.lua delete mode 100644 Me_Lua/h10/socket/headers.lua delete mode 100644 Me_Lua/h10/socket/http.lua delete mode 100644 Me_Lua/h10/socket/smtp.lua delete mode 100644 Me_Lua/h10/socket/tp.lua delete mode 100644 Me_Lua/h10/socket/url.lua delete mode 100644 Me_Lua/h10/ssl.lua delete mode 100644 Me_Lua/h10/ssl.so delete mode 100644 Me_Lua/h10/ssl/https.lua delete mode 100644 Me_Lua/h13/MZLog.lua delete mode 100644 Me_Lua/h13/Posix.lua delete mode 100644 Me_Lua/h13/cjson.so delete mode 100644 Me_Lua/h13/lfs.so delete mode 100644 Me_Lua/h13/lsqlite3.so delete mode 100644 Me_Lua/h13/ltn12.lua delete mode 100644 Me_Lua/h13/luci/controller/admin/network.lua delete mode 100644 Me_Lua/h13/luci/controller/api/index.lua delete mode 100644 Me_Lua/h13/luci/controller/bs/index.lua delete mode 100644 Me_Lua/h13/luci/dispatcher.lua delete mode 100644 Me_Lua/h13/luci/model/network.lua delete mode 100644 Me_Lua/h13/luci/sauth.lua delete mode 100644 Me_Lua/h13/meizu/arpmon.lua delete mode 100644 Me_Lua/h13/meizu/bfs.lua delete mode 100644 Me_Lua/h13/meizu/build.sh delete mode 100644 Me_Lua/h13/meizu/dbfs.lua delete mode 100644 Me_Lua/h13/meizu/nwfs.lua delete mode 100644 Me_Lua/h13/meizu/r10config.lua delete mode 100644 Me_Lua/h13/meizu/sipfs.lua delete mode 100644 Me_Lua/h13/meizu/upgdfs.lua delete mode 100644 Me_Lua/h13/mime.lua delete mode 100644 Me_Lua/h13/mime.so.1.0.3 delete mode 100644 Me_Lua/h13/mime/core.so delete mode 100644 Me_Lua/h13/posix.so delete mode 100644 Me_Lua/h13/routerReport.lua delete mode 100644 Me_Lua/h13/socket.lua delete mode 100644 Me_Lua/h13/socket.so.3.0-rc1 delete mode 100644 Me_Lua/h13/socket/core.so delete mode 100644 Me_Lua/h13/socket/ftp.lua delete mode 100644 Me_Lua/h13/socket/headers.lua delete mode 100644 Me_Lua/h13/socket/http.lua delete mode 100644 Me_Lua/h13/socket/smtp.lua delete mode 100644 Me_Lua/h13/socket/tp.lua delete mode 100644 Me_Lua/h13/socket/url.lua delete mode 100644 Me_Lua/h13/ssl.lua delete mode 100644 Me_Lua/h13/ssl.so delete mode 100644 Me_Lua/h13/ssl/https.lua delete mode 100644 Me_Lua/h13/tags diff --git a/Me_Lua/R10-WIFI.lua b/Me_Lua/R10-WIFI.lua deleted file mode 100644 index 50c1d01..0000000 --- a/Me_Lua/R10-WIFI.lua +++ /dev/null @@ -1,73 +0,0 @@ - -function wifi_reconnect_shutdown(shutdown, wnet) - local netmd = require "luci.model.network".init() - local net = netmd:get_wifinet(wnet) - local dev = net:get_device() - if dev and net then - dev:set("disabled", nil) - net:set("disabled", shutdown and 1 or nil) - netmd:commit("wireless") - - luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null") - - luci.sys.call("env -i /sbin/wifi reload >/dev/null 2>/dev/null") - - --luci.http.status(200, shutdown and "Shutdown" or "Reconnected") - - return - end - - --luci.http.status(404, "No such radio") -end - -function wifi_reconnect(wnet) - wifi_reconnect_shutdown(false, wnet) -end - -function wifi_shutdown(wnet) - wifi_reconnect_shutdown(true, wnet) -end - - - -function fork_smart_wifi_shutdown(switch, wnet, close_time, open_time) - local close_interval = close_time - os.time() - local open_interval = open_time - os.time() - - - local cmd = string.format("/sbin/wifi down "..wnet.."; sleep 15; /sbin/wifi up "..wnet) - require "MZLog".log(3, cmd) - --local cmd = string.format("sleep %s; /sbin/wifi down; sleep %s; /sbin/wifi up;", tostring(close_interval), tostring(open_interval)) - --local cmd = "/sbin/wifi "..switch.." "..wnet - - exec_cmd_in_sh(cmd) -end - - - -function smart_wifi_shutdown() - local wnet = "wl1" - local info = {} - local switch = luci.http.formvalue("switch") - --get para - --close_time = luci.http.formvalue("close_time") - --open_time = luci.http.formvalue("open_time") - - --test normal - close_time = os.time() + 2 - restart_time = os.time() + 4 - - --test exception - --close_time = os.time() - 5 - --restart_time = os.time() - 10 - - --para err manage - if close_time < os.time() or restart_time < close_time then - info["SUCCESS"] = false - else - info["SUCCESS"] = true - end - fork_smart_wifi_shutdown(switch, wnet, close_time, restart_time) - luci.http.write_json(info) - -end diff --git a/Me_Lua/h10/MZLog.lua b/Me_Lua/h10/MZLog.lua deleted file mode 100644 index c4a1177..0000000 --- a/Me_Lua/h10/MZLog.lua +++ /dev/null @@ -1,14 +0,0 @@ -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 diff --git a/Me_Lua/h10/Posix.lua b/Me_Lua/h10/Posix.lua deleted file mode 100644 index 7536a2a..0000000 --- a/Me_Lua/h10/Posix.lua +++ /dev/null @@ -1,113 +0,0 @@ -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 diff --git a/Me_Lua/h10/cjson.so b/Me_Lua/h10/cjson.so deleted file mode 100644 index cec1fb6196a88775ecc98f8d12de269d0f379d7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30666 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 diff --git a/Me_Lua/h10/lfs.so b/Me_Lua/h10/lfs.so deleted file mode 100755 index 1bc10dfa9282ab6049919f9aa6ad534b5c6f16af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16916 zcmds8Yjl*yd7hO7h_&pj0o$@d$%oC=f%O71$To=uh+8ad0g6LXn$>D|g*NPs-IYO! z+u#^GmxBY2@g*%BHVIB}LK@nT9G@0iaA@kbIMGQ+N_Zl1#Nlc~WV?{@GVIF;hu;nZJK)Fac!=U6(p*Fw{bg`^#@E2FEf->dw>T5O z3^Dh@%lv?=;BSSen+d-_O6q3?V5#P`eK-7g__;caaDycqaW;fMf`2D`2p-KL>fu+z z)4dyh8vIT0cfrqtpAS#B5WWR|CH#Bf>8jzEz%PQI1y6T7{2VE%pL?{t9QZ!?TFobG zBs9Zc5C2~HJK+B>&W}Xb{DBF_L67Zzt=4~s#s-Z6jfCqgnWCrp&A@kQ*@megGjzZd zjp%OD-GX2Czv+sK2^yO;x=^PBg1{TKJP~-OmKOurZ{E(eu~Ffwb*rB}X!rzC@+q0W zEXPkORPqh%(AqJ6tE0aL55N0)r4SJRF?_QV{{e@8(y_;9@R07{6Y%8vocOOh=|AW2 ze{%TkPWqF&>;#tIbK=)Jyw9=s8;8Hg(O>7-|AE8*#o=|1z1JLmy<^|>O`7rGscxR< z1U%10PWrQmH;(mv$%#K=B7uy56Zu_4f7k~3dW39p^xtsG^F=59Qb+$bhd+b#8>gyv zpCJ5K_0wBmE8*CmkNy<1`qKude{t?I&V$hFq<_*x0$IQ1PW%Cb&q9Yk z=A`d%(*K(iFT#m*q9DRu01;l@z9t-t=i-|Z`9eI`zGhi6la9AXI+Jk~H+oDsx-CKj zk!0edPz*=nkC*Pg!Np;3^BT-328MU6Ph@B{3$R*O7Xrnb8?T$w` zCo3W0bbM=1KAww33K5ZtB$Jt_Kx{PIDbCR@;T>?tHtl?=PA zBC{bnGnr&Ol9uTcc`LGzF|}hgQrc{#T!r4OvKr0BBLx(SMPl>jB3n^Rfz*-0!bTay zjH1zGCf}2bi%d42jwNK}bTjtIMw87N$!$_uz-SCwFu-(iCWvuv5rZ)2z4H(@jn@?wlreQ0~{3xdjabzkBTFBV#!D3snEO(fdLrftv)+3Dj9x6^sze-NbV)2kxfZ>saY*AOjh8iE z(a6OtL{X!$R^us+eHzbbd=`s1>Yv8Kk9bDoS&jV~_h7-y_-8d1HBQ1Jmf`gpw`;tj zaVHkrjK8R{4GTi@%Nnm}BW1Yr;#z`9MHBQ#(X`H5Umc}_6LmC@3Hfda}u~}n_##I_yHMVJN z*SJCBMU024sp!8%d^EK~u0kK&K*Wb=AL@4l`ub@iK6=g&@$oYB6@0%`3vr1Ey~{*= z=w2a?MMFUE##*!oaXh{eiTI$aBjO_{K*WN05)mI{^+Ze>lZp7o@rYRTO(Wt1X%-P5 zw{wX25DpRX0o6!E!#5Ez2P`IH4rnH#PAx=??NvmK;Z`EXU>ork)R#C7^(EpXZXLkgt$bA7l_M*I7)00 z;y7`I5GRQ%@$EodCB!M>`|zE7yjU9g`P|oP4z~^redC?4)%4FT*Yxi%U)R5@zjo;F z%7v%#48OZ;VEjMt94P$yXxYd~OO9FcMoVtD;+-S*jEP0wGPqySqmRx7a zHI{tkKPzRvWXTsT`J5%6wdB*5e9DqfTJlj#K4Qs-Ect*X@3rJTmb}xFcUba6mRzvp zq$S5Jd7~w_TXL%;6cOTK8y=PdcGC7-tB zQo37iW*NNVpiJX^r;Ie`55Rss><_{I5HJSbH#~eHfP6%AvD74rBe@`&79@ z)q`IDzH{e(KYXDd?}$L?iSj${svf8szkU#}XTMLQ->-PJ3D>+z<6`vdv5+~IsscqH zUilY7v=5vE#M0oxEFhK)7p74M=mF8CFH8oWME*1IK3)Jn1@GgNz-RD2t_8jWz5)Kf zbbqh$9v|?b?VkJn@ar`|kyU;ES#Z%od0+WDv3(##-qtpN4-x;kK(X{Ncma8h!T9(X zz~K$rRQS=@m+m(PGU z(FgoH5l8tF@*3+EOTYY`$_GoL3#?av$NuuG2ou@10dneMndct^UABqXUMxN8d-~N! zx4^z=8^n^*UyHmhG7UKLXefr*&x$3MVO;i+{y^xN@&c3t%h?OQwnqovz*uDbLny-o zu!-g4h1-B*kRD50KjYY6#(Blk4`H`8%V%30920mN?~=9bCsOAorU`wrpZYbSC(F!_ z`H)xP`A+1MM){sZ ze2v&s7RX0*uy3gNiGjxkUPK(*iuq7yA34fAR+f23nc>X)7<`jyAGS#|-qp+(`TvM0 z>s2ga9`gSJ{G<%qUH&Oh_H(OlYZ1o2-UQn$ zm>ZZEo}53&bSNuU@ffQ+$^oP|Y3HEcn@oD0hV@>;Fx2y}h)j!gOwY8OBYLoI;5%a) z#u%QFe=9iKGY7=yPy_pe9HT&#;X)Pgu=lc@PyQNM?G;Pkxd&~J_PY!|%iC9e5qxOs z%cUZ;~&CtGczq8tc`LZoq5WfN5v^VD! zKHqK`w!8c=Q1&I{!9MuwE2^zoKelNQ@yJuwmvf3~FJpfW;(vF&82o^=SDCv$3Vy!~ z+g)Z}b{;=<^0)!G{szcZD6bD~ zbQ5IS^}X`=0P7>i0s0@`g{&LL;RV`lZW}=V_2E4+hR<9yqwkA$KF5Z7v@`oQ$Jqkd zV;f~*>$>UqMuxu?o^8UiHbS?o))s?vLTdbTj(iq*Fdg%JMau!`{sJ<~%Caqh9q#4a z4g3}7ZP+WesrMh&lCRT_$f9q1YA*R6(pEEUdnN2gw9T-NN?0Glgmc2s~Au0=XJxWPf@mWY&u^Uo&)@QE%VSK0Tow~mq)|~4o>gL^WA=tF9!nr_NEMG3GP&MSY~skt zo1VW5UY~<`BiiEqX`Z=xg^Y*Nr#HpDt(n|r98gwN7&j9+`={sqf@Vw!Qkhs>tXSQ; z{5BcP;zwjbB~>SGiu1&g%AGh(&GiZ#x1sVP9p6?^1;QCqA{~ow18$0{v(50b``bRa zZuQDl?P6Ib+nY;l>MnS*md*C&he8YH&JWF-@7){ECgVA;EtmNSsxHDU%hxYkx4Nx; z_5JsW)}F`;G}-!IocN}^L>?tWkcVTh97@3F5>MhNE+#9UNx@Jmo-TNJP96&DWxBks zo^+H)e0eVyPvUG+s>;WZmqznY>cXLN%GTJTJh+!%xaA>JcFnba)u?aqh z3W`WH8qeniT0YU0h^kXz^^iq2o=f4Nmeo@|m9RO_gKp{Sv5-4FNu9J+<7J7pg*;0m zP6fxDFaIxsZFBiQ8*FpS|E*z&%m1Tc7|HVs3`5ClfJflRz#qV(aV+o>7Ijz)ixli# z1LQd!L~-sb*zX4(M`kF3{O=aNx5RFIbYeSRyaZ+b2je9uPXyxKJ@Wsh-wzLG4kCUS z$g<))Co=&Ydl)zg|HB>sV`p3kGX4MTO+ATc58{7*#(|H=+?Pe;KZm*RAkH{G2iyUC z8rT8c3tS8=0_%YXfS1sBo(J}^4*?GWj{!dgd<7T-o&=tPejl(I{9l2SfyUuz`7UqP z%KP3w+glJ^5S%YZ{k%}<4sTXVyfYC=ds+OuA&x&C5Do36J&9y2m%%KA*`YBQ zYML8@Yn;1je&hUjWKrjAuQAvZTp(jZjiGtoEZfGCImlc7#Y6aRfjDN-+$CbHf83H< z-}tHtHIsZd_-?AM_cc`A;+x|WL5xWpw*w0~h22K#j^w*VFxH!fio!xp1UIF7f)CqGbzq-BDiGTnxHkAm^T04kYk(Umt&J-nZ6l>oQ`9hekwf2Gs8K? z=?^1yLas1NFgXegr9>+5M(~!yOi1av;!solv;~YTmA&e$z zi}}*6fyXzYOvAZEdMFut)Z?7;fThQ|hn{m1^_br1g(1`aSa|-2j-K^1&gA+zqjbuqrS!&d%Xx?zSQf- zc%(OR)HU)Wkg*Rd+x6U+F<-xp-Y)2{*vyJ&+2`Lz?=KKPR_n?CH$(5T<^Y*5pT_}s zmXG%MjyN|{>48ee^3gvJZ}d2yot=fbM{1}aQ;%E z=Dl96M=1M|idO|;e^Hz(4An0b=SrjEs^!YW<~NKyUxwD;Kg(u~q_k?~nu+67xobw% z->BPzJ(KA_W$Ejtl*x^K&JD`>vGG=EzbdS(ZU=9(;%TqL;`1$T^ov$J)0_6-ii_#F zCRENZmRsDUuNirV`^6t4p5u!B5C6oHapd6-s_@6fA z{IWf{b~8K+ee%5sF#7!On~7)pSH5rk;!mMZ-iL6b&;Pn9r|k3l*znIlpZquij6VMZ zr<~H?Yw@R`PreFh^!Z;oTc6+KhJOKiz8u&-CQVsqx1D>>18@?n4;T{pO z@K>Nuz8C@2KL^fzlV;7?-}zra>8HmVS+=)sa8->nz>|eR6v|9kk-9f7s$1p-+AY;if$N z&zf?|KJO?P&iaK$=5y6wxE52cPISQ@IrH)1w+EbiVp+|Zp67GQO%NYLJUQQ#I6s$b zEfdT6PU_DvA=iq>sIR#Xx0CjOoA;p)`uo7m`;h#b;AZ}({o~+fekG@Uo`ow{C(CW# z=UkOAK0ES08!zJv7C!}h#_?@?+Tmv%{_hU|EqJ${?|DaPOtrD5_6PW%K;vkChQk+v zoA)vA2rYKv-{fP z9p32hr4Da*_(vSx18$f95hs3+!~fjjUv>E3JNzFU{zHfV#Nj`4_-o*H`G%bM-#EN> z?A7f*3EVig_Y{Xuclg~-`er8{+olOzwn!&}Q86tdqPar8(9_igR=Fz_E~LWP$WF)e zVj6Z;^$j8`G#rj)!kdzr&PXyG!}fbV9O>C6u+@ScW$YOTo0{&Jhh6Pal;qtcwP_Q^ zwhXq#<;G4p){{#0B8kQ1Wu~iCae#nw@@fgLY=q6$ZG~fJI6o3Cw{=Y%_O!8kWLWAd zhAm<%PVONaMQ$n^nVZZ;R@=^oaUgRUq^D zBaAyL>CI9UBY`~T2q$ofE8G>4ryU~!Jbc0Nh1?IPl01G8%toCy$OvVf`34jDTm-jY za`9B=L6s^M*{lTI^^w~0c9u+ny|Z+_kj-VX!8@hRE?(4;6_G`g#~G>?>S#mSl6Q)z z!~>dqaA8y9BGHw{5ro`+N5Gwn*f&%TykFDu!TXl1S-nhzSGL~2bV+OY z{uL|MFK-XGFIn2UoL6yT`AirUjq&PQ7&qB;I&&S$To1#|pSRpo3Xj~(lGl6GMII>1 zs*KzRV*nqUd&SFKVUpc;l>12b1ulKpOW)nnm#g%3HrlstURCZ@$y}p+Y`otkD=>18 z%iPE^x9f19uDRJ^a(Y}4#?W)^h>P!kJCjaA=K)L&>?Z~Teyl`jVM7!#i zp1E$N+s(fEg+8M0WXamNm;GA9mFsn;V!VY{sTq=uTo(&peH~F+wCcQ)eSJlH@=(EbHu9IDT zX;EFaW8Un8=6;*8dX-W8BA-!IbBMVc*~%-CIQG#u+)%yB#Y37OxxUGpZ>q^E7X~?+ UF`JpJd#>to)E*fFY23d2Z)8J*ZU6uP diff --git a/Me_Lua/h10/lsqlite3.so b/Me_Lua/h10/lsqlite3.so deleted file mode 100644 index 8b8db6e065d137b430e5c17fb1ff7998400ea194..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40103 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 h< -Copyright 2011 Jo-Philipp Wich - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -]]-- - -module("luci.controller.admin.network", package.seeall) - -function index() - local uci = require("luci.model.uci").cursor() - local page - - page = node("admin", "network") - page.target = firstchild() - page.title = _("Network") - page.order = 50 - page.index = true - --- if page.inreq then - local has_switch = false - - uci:foreach("network", "switch", - function(s) - has_switch = true - return false - end) - - if has_switch then - page = node("admin", "network", "vlan") - page.target = cbi("admin_network/vlan") - page.title = _("Switch") - page.order = 20 - - page = entry({"admin", "network", "switch_status"}, call("switch_status"), nil) - page.leaf = true - end - - - local has_wifi = false - - uci:foreach("wireless", "wifi-device", - function(s) - has_wifi = true - return false - end) - - if has_wifi then - page = entry({"admin", "network", "wireless_join"}, call("wifi_join"), nil) - page.leaf = true - - page = entry({"admin", "network", "wireless_add"}, call("wifi_add"), nil) - page.leaf = true - - page = entry({"admin", "network", "wireless_delete"}, call("wifi_delete"), nil) - page.leaf = true - - page = entry({"admin", "network", "wireless_status"}, call("wifi_status"), nil) - page.leaf = true - - page = entry({"admin", "network", "getWifiSettings"}, call("getWifiSettings"), nil) - page.leaf = true - - page = entry({"admin", "network", "getConnectInfo"}, call("lease_status"), nil) - page.leaf = true - - page = entry({"admin", "network", "getUpLoadSpeed"}, call("getUpLoadSpeed"), nil) - page.leaf = true - page = entry({"admin", "network", "getWanInfo"}, call("getWanInfo"), nil) - page.leaf = true - page = entry({"admin", "network", "getLanDhcp"}, call("getLanDhcp"), nil) - page.leaf = true - - page = entry({"admin", "network", "wireless_reconnect"}, call("wifi_reconnect"), nil) - page.leaf = true - - page = entry({"admin", "network", "wireless_shutdown"}, call("wifi_shutdown"), nil) - page.leaf = true - - page = entry({"admin", "network", "wireless"}, arcombine(template("admin_network/wifi_overview"), cbi("admin_network/wifi")), _("Wifi"), 15) - page.leaf = true - page.subindex = true - - if page.inreq then - local wdev - local net = require "luci.model.network".init(uci) - for _, wdev in ipairs(net:get_wifidevs()) do - local wnet - for _, wnet in ipairs(wdev:get_wifinets()) do - entry( - {"admin", "network", "wireless", wnet:id()}, - alias("admin", "network", "wireless"), - wdev:name() .. ": " .. wnet:shortname() - ) - end - end - end - end - - - page = entry({"admin", "network", "iface_add"}, cbi("admin_network/iface_add"), nil) - page.leaf = true - - page = entry({"admin", "network", "iface_delete"}, call("iface_delete"), nil) - page.leaf = true - - page = entry({"admin", "network", "iface_status"}, call("iface_status"), nil) - page.leaf = true - - page = entry({"admin", "network", "iface_reconnect"}, call("iface_reconnect"), nil) - page.leaf = true - - page = entry({"admin", "network", "iface_shutdown"}, call("iface_shutdown"), nil) - page.leaf = true - - page = entry({"admin", "network", "network"}, arcombine(cbi("admin_network/network"), cbi("admin_network/ifaces")), _("Interfaces"), 10) - page.leaf = true - page.subindex = true - - if page.inreq then - uci:foreach("network", "interface", - function (section) - local ifc = section[".name"] - if ifc ~= "loopback" then - entry({"admin", "network", "network", ifc}, - true, ifc:upper()) - end - end) - end - - - if nixio.fs.access("/etc/config/dhcp") then - page = node("admin", "network", "dhcp") - page.target = cbi("admin_network/dhcp") - page.title = _("DHCP and DNS") - page.order = 30 - - page = entry({"admin", "network", "dhcplease_status"}, call("lease_status"), nil) - page.leaf = true - - page = node("admin", "network", "hosts") - page.target = cbi("admin_network/hosts") - page.title = _("Hostnames") - page.order = 40 - end - - page = node("admin", "network", "routes") - page.target = cbi("admin_network/routes") - page.title = _("Static Routes") - page.order = 50 - - page = node("admin", "network", "diagnostics") - page.target = template("admin_network/diagnostics") - page.title = _("Diagnostics") - page.order = 60 - - page = entry({"admin", "network", "diag_ping"}, call("diag_ping"), nil) - page.leaf = true - - page = entry({"admin", "network", "diag_nslookup"}, call("diag_nslookup"), nil) - page.leaf = true - - page = entry({"admin", "network", "diag_traceroute"}, call("diag_traceroute"), nil) - page.leaf = true - - page = entry({"admin", "network", "diag_ping6"}, call("diag_ping6"), nil) - page.leaf = true - - page = entry({"admin", "network", "diag_traceroute6"}, call("diag_traceroute6"), nil) - page.leaf = true -end - -function wifi_join() - local function param(x) - return luci.http.formvalue(x) - end - - local function ptable(x) - x = param(x) - return x and (type(x) ~= "table" and { x } or x) or {} - end - - local dev = param("device") - local ssid = param("join") - - if dev and ssid then - local cancel = (param("cancel") or param("cbi.cancel")) and true or false - - if cancel then - luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless_join?device=" .. dev)) - else - local cbi = require "luci.cbi" - local tpl = require "luci.template" - local map = luci.cbi.load("admin_network/wifi_add")[1] - - if map:parse() ~= cbi.FORM_DONE then - tpl.render("header") - map:render() - tpl.render("footer") - end - end - else - luci.template.render("admin_network/wifi_join") - end -end - -function wifi_add() - local dev = luci.http.formvalue("device") - local ntm = require "luci.model.network".init() - - dev = dev and ntm:get_wifidev(dev) - - if dev then - local net = dev:add_wifinet({ - mode = "ap", - ssid = "OpenWrt", - encryption = "none" - }) - - ntm:save("wireless") - luci.http.redirect(net:adminlink()) - end -end - -function wifi_delete(network) - local ntm = require "luci.model.network".init() - local wnet = ntm:get_wifinet(network) - if wnet then - local dev = wnet:get_device() - local nets = wnet:get_networks() - if dev then - ntm:del_wifinet(network) - ntm:commit("wireless") - local _, net - for _, net in ipairs(nets) do - if net:is_empty() then - ntm:del_network(net:name()) - ntm:commit("network") - end - end - luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null") - luci.sys.call("env -i /sbin/wifi reload >/dev/null 2>/dev/null") - end - end - - luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless")) -end - -function iface_status(ifaces) - local netm = require "luci.model.network".init() - local rv = { } - - local iface - for iface in ifaces:gmatch("[%w%.%-_]+") do - local net = netm:get_network(iface) - local device = net and net:get_interface() - if device then - local data = { - id = iface, - proto = net:proto(), - uptime = net:uptime(), - gwaddr = net:gwaddr(), - dnsaddrs = net:dnsaddrs(), - name = device:shortname(), - type = device:type(), - ifname = device:name(), - macaddr = device:mac(), - is_up = device:is_up(), - rx_bytes = device:rx_bytes(), - tx_bytes = device:tx_bytes(), - rx_packets = device:rx_packets(), - tx_packets = device:tx_packets(), - - ipaddrs = { }, - ip6addrs = { }, - subdevices = { } - } - - local _, a - for _, a in ipairs(device:ipaddrs()) do - data.ipaddrs[#data.ipaddrs+1] = { - addr = a:host():string(), - netmask = a:mask():string(), - prefix = a:prefix() - } - end - for _, a in ipairs(device:ip6addrs()) do - if not a:is6linklocal() then - data.ip6addrs[#data.ip6addrs+1] = { - addr = a:host():string(), - netmask = a:mask():string(), - prefix = a:prefix() - } - end - end - - for _, device in ipairs(net:get_interfaces() or {}) do - data.subdevices[#data.subdevices+1] = { - name = device:shortname(), - type = device:type(), - ifname = device:name(), - macaddr = device:mac(), - macaddr = device:mac(), - is_up = device:is_up(), - rx_bytes = device:rx_bytes(), - tx_bytes = device:tx_bytes(), - rx_packets = device:rx_packets(), - tx_packets = device:tx_packets(), - } - end - - rv[#rv+1] = data - else - rv[#rv+1] = { - id = iface, - name = iface, - type = "ethernet" - } - end - end - - if #rv > 0 then - luci.http.prepare_content("application/json") - luci.http.write_json(rv) - return - end - - luci.http.status(404, "No such device") -end - -function iface_reconnect(iface) - local netmd = require "luci.model.network".init() - local net = netmd:get_network(iface) - if net then - luci.sys.call("env -i /sbin/ifup %q >/dev/null 2>/dev/null" % iface) - luci.http.status(200, "Reconnected") - return - end - - luci.http.status(404, "No such interface") -end - -function iface_shutdown(iface) - local netmd = require "luci.model.network".init() - local net = netmd:get_network(iface) - if net then - luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface) - luci.http.status(200, "Shutdown") - return - end - - luci.http.status(404, "No such interface") -end - -function iface_delete(iface) - local netmd = require "luci.model.network".init() - local net = netmd:del_network(iface) - if net then - luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface) - luci.http.redirect(luci.dispatcher.build_url("admin/network/network")) - netmd:commit("network") - netmd:commit("wireless") - return - end - - luci.http.status(404, "No such interface") -end - -function wifi_status(devs) - local s = require "luci.tools.status" - local rv = { } - - local dev - for dev in devs:gmatch("[%w%.%-]+") do - rv[#rv+1] = s.wifi_network(dev) - end - - if #rv > 0 then - luci.http.prepare_content("application/json") - luci.http.write_json(rv) - return - end - - luci.http.status(404, "No such device") -end - -local function wifi_reconnect_shutdown(shutdown, wnet) - local netmd = require "luci.model.network".init() - local net = netmd:get_wifinet(wnet) - local dev = net:get_device() - if dev and net then - dev:set("disabled", nil) - net:set("disabled", shutdown and 1 or nil) - netmd:commit("wireless") - - luci.sys.call("env -i /bin/ubus call network reload >/dev/null 2>/dev/null") - - luci.sys.call("env -i /sbin/wifi reload >/dev/null 2>/dev/null") - - luci.http.status(200, shutdown and "Shutdown" or "Reconnected") - - return - end - - luci.http.status(404, "No such radio") -end - -function wifi_reconnect(wnet) - wifi_reconnect_shutdown(false, wnet) -end - -function wifi_shutdown(wnet) - wifi_reconnect_shutdown(true, wnet) -end - -function wifiNetworks() - local result = {} - local network = require "luci.model.network".init() - local dev - for _, dev in ipairs(network:get_wifidevs()) do - local rd = { - up = dev:is_up(), - device = dev:name(), - name = dev:get_i18n(), - networks = {} - } - local wifiNet - for _, wifiNet in ipairs(dev:get_wifinets()) do - rd.networks[#rd.networks+1] = { - name = wifiNet:shortname(), - up = wifiNet:is_up(), - mode = wifiNet:active_mode(), - ssid = wifiNet:active_ssid(), - bssid = wifiNet:active_bssid(), - encryption = wifiNet:active_encryption(), - frequency = wifiNet:frequency(), - channel = wifiNet:channel(), - signal = wifiNet:signal(), - quality = wifiNet:signal_percent(), - noise = wifiNet:noise(), - bitrate = wifiNet:bitrate(), - ifname = wifiNet:ifname(), - assoclist = wifiNet:assoclist(), - country = wifiNet:country(), - txpower = wifiNet:txpower(), - txpoweroff = wifiNet:txpower_offset(), - key = wifiNet:get("key"), - key1 = wifiNet:get("key1"), - encryption_src = wifiNet:get("encryption"), - hidden = wifiNet:get("hidden"), - } - end - result[#result+1] = rd - end - return result -end - -function wifiNetwork(wifiDeviceName) - local network = require "luci.model.network".init() - local wifiNet = network:get_wifinet(wifiDeviceName) - if wifiNet then - local dev = wifiNet:get_device() - if dev then - return { - id = wifiDeviceName, - name = wifiNet:shortname(), - up = wifiNet:is_up(), - mode = wifiNet:active_mode(), - ssid = wifiNet:active_ssid(), - bssid = wifiNet:active_bssid(), - encryption = wifiNet:active_encryption(), - encryption_src = wifiNet:get("encryption"), - frequency = wifiNet:frequency(), - channel = wifiNet:channel(), - signal = wifiNet:signal(), - quality = wifiNet:signal_percent(), - noise = wifiNet:noise(), - bitrate = wifiNet:bitrate(), - ifname = wifiNet:ifname(), - assoclist = wifiNet:assoclist(), - country = wifiNet:country(), - txpower = wifiNet:txpower(), - txpoweroff = wifiNet:txpower_offset(), - key = wifiNet:get("key"), - key1 = wifiNet:get("key1"), - hidden = wifiNet:get("hidden"), - device = { - up = dev:is_up(), - device = dev:name(), - name = dev:get_i18n() - } - } - end - end - return {} -end - -function getWifiSettings() - local infoList = {} - local wifis = wifiNetworks() - for i,wifiNet in ipairs(wifis) do - local item = {} - local index = 1 - if wifiNet["up"] then - item["status"] = "1" - else - item["status"] = "0" - end - local encryption = wifiNet.networks[index].encryption_src - local key = wifiNet.networks[index].key - if encryption == "wep-open" then - key = wifiNet.networks[index].key1 - if key:len()>4 and key:sub(0,2)=="s:" then - key = key:sub(3) - end - end - local channel = wifiNet.networks[index].cchannel - -- local channelparseinfo = channelHelper(channel) - item["ifname"] = wifiNet.networks[index].ifname - item["device"] = wifiNet.device..".network"..index - item["ssid"] = wifiNet.networks[index].ssid - -- item["channel"] = channelparseinfo.channel - -- item["channelInfo"] = getBandList(channel) - -- item["channelInfo"]["channel"] = wifiNet.networks[index].channel - item["mode"] = wifiNet.networks[index].mode - item["hidden"] = wifiNet.networks[index].hidden or 0 - item["signal"] = wifiNet.networks[index].signal - item["password"] = key - item["encryption"] = encryption - infoList[#wifis+1-i] = item - end - --local guestwifi = getGuestWifi(1) - -- if guestwifi then - -- table.insert(infoList, guestwifi) - -- end - --return infoList - local result = {} - -- local code = 0 - -- result["info"] = infoList - -- result["code"] = code - luci.http.write_json(infoList) -end - -function lease_status() - local s = require "luci.tools.status" - - luci.http.prepare_content("application/json") - luci.http.write('[') - luci.http.write_json(s.dhcp_leases()) - luci.http.write(',') - luci.http.write_json(s.dhcp6_leases()) - luci.http.write(']') -end - -function switch_status(switches) - local s = require "luci.tools.status" - - luci.http.prepare_content("application/json") - luci.http.write_json(s.switch_status(switches)) -end - -function diag_command(cmd, addr) - if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then - luci.http.prepare_content("text/plain") - - local util = io.popen(cmd % addr) - if util then - while true do - local ln = util:read("*l") - if not ln then break end - luci.http.write(ln) - luci.http.write("\n") - end - - util:close() - end - - return - end - - luci.http.status(500, "Bad address") -end - -function diag_ping(addr) - diag_command("ping -c 5 -W 1 %q 2>&1", addr) -end - -function diag_traceroute(addr) - diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr) -end - -function diag_nslookup(addr) - diag_command("nslookup %q 2>&1", addr) -end - -function diag_ping6(addr) - diag_command("ping6 -c 5 %q 2>&1", addr) -end - -function diag_traceroute6(addr) - diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr) -end - diff --git a/Me_Lua/h10/luci/controller/api/index.lua b/Me_Lua/h10/luci/controller/api/index.lua deleted file mode 100644 index 37a0689..0000000 --- a/Me_Lua/h10/luci/controller/api/index.lua +++ /dev/null @@ -1,308 +0,0 @@ -module("luci.controller.api.index", package.seeall) - -local bfs = require "meizu.bfs" -local cjson = require "cjson" -local disk = require "meizu.disk" -local dlfs = require "meizu.dlfs" -local lfs = require "lfs" -local lue = require("luci.util").exec -local nwfs = require "meizu.nwfs" -local RC = require "meizu.r10config" -local sipfs = require "meizu.sipfs" -local upgdfs = require "meizu.upgdfs" -local btfs = require "meizu.btfs" - -b64dec = bfs.b64dec -batchfile_checklist = bfs.batchfile_checklist -batchfile_compare_upload = bfs.batchfile_compare_upload -bind_router = bfs.bind_router -data_to_json = bfs.data_to_json -exec_cmd_in_sh = bfs.exec_cmd_in_sh -exec_reboot = bfs.exec_reboot -findInDir = bfs.findInDir -get_device_SN = bfs.get_device_SN -get_device_version = bfs.get_device_version -get_https_data = bfs.get_https_data -getFilesList = bfs.getFilesList -factory_reset = bfs.factory_reset -rts_get_access_token = bfs.rts_get_access_token -set_passwd = bfs.set_passwd -silent_upgrade = bfs.silent_upgrade - -nw_get_disk_info = disk.nw_get_disk_info -disk_formatting = disk.disk_formatting - -sip = sipfs.sip -pysip = sipfs.pysip -upload_router_log = sipfs.upload_router_log - -nw_check_sys_password = nwfs.nw_check_sys_password -nw_get_connect_device_list = nwfs.nw_get_connect_device_list -nw_get_device_details = nwfs.nw_get_device_details -nw_get_wan_type = nwfs.nw_get_wan_type -nw_get_smbswitch = nwfs.nw_get_smbswitch -nw_get_wifi_settings = nwfs.nw_get_wifi_settings -nw_set_device_name = nwfs.nw_set_device_name -nw_set_disk_access = nwfs.nw_set_disk_access -nw_set_wan_switch = nwfs.nw_set_wan_switch -nw_set_wan_type = nwfs.nw_set_wan_type -nw_set_smbswitch = nwfs.nw_set_smbswitch -nw_wifi_settings = nwfs.nw_wifi_settings -nw_get_tx_power_mode = nwfs.nw_get_tx_power_mode -nw_set_tx_power_mode = nwfs.nw_set_tx_power_mode -nw_get_wireless_channel = nwfs.nw_get_wireless_channel -nw_set_wireless_channel = nwfs.nw_set_wireless_channel - -get_connect_info = nwfs.get_connect_info -get_net_device = nwfs.get_net_device -real_time_net_speed = nwfs.real_time_net_speed - -nw_scan_ble_switch = btfs.nw_scan_ble_switch -nw_get_ble_device_list = btfs.nw_get_ble_device_list -nw_add_ble_mesh_device = btfs.nw_add_ble_mesh_device -nw_get_ble_device_status = btfs.nw_get_ble_device_status -nw_get_mesh_device_list = btfs.nw_get_mesh_device_list -nw_remove_ble_from_mesh = btfs.nw_remove_ble_from_mesh -nw_dismiss_mesh = btfs.nw_dismiss_mesh -nw_set_mesh_device_attr = btfs.nw_set_mesh_device_attr -nw_reboot_mesh_device = btfs.nw_reboot_mesh_device -nw_unmesh_all_device = btfs.nw_unmesh_all_device -nw_set_mesh_device_timer = btfs.nw_set_mesh_device_timer -nw_del_mesh_device_timer = btfs.nw_del_mesh_device_timer -nw_set_mesh_network_pwd = btfs.nw_set_mesh_network_pwd -nw_set_lamp_brightness = btfs.nw_set_lamp_brightness - -check_upgrade = upgdfs.check_upgrade -do_upgrade = upgdfs.do_upgrade -local_upgrade = upgdfs.local_upgrade - -nw_download_task_operate = dlfs.nw_download_task_operate -nw_get_active_list = dlfs.nw_get_active_list -nw_get_history_list = dlfs.nw_get_history_list ---nw_get_pause_list = dlfs.nw_get_pause_list -nw_thunder_get_bind_code = dlfs.nw_thunder_get_bind_code - -nw_download_task_start = dlfs.nw_download_task_start - -function index() - --nw: abridged for "Nei Wang"; ww abridged for "Wai Wang" - local root = node() - if not root.target then - root.target = alias("api") - root.index = true - end - local page = node("api") - page.target = firstchild() - page.title = _("api") - page.order = 10 - page.index = true - page.sysauth = "root" - page.sysauth_authenticator = "htmlauth" - --page = entry({"api", "getUserAccessToken"}, call("get_user_access_token"), nil, nil) - --page.leaf = true - page = entry({"api", "bindRouter"}, call("bind_router"), nil, nil) - page.leaf = true - --page = entry({"api", "unbindRouter"}, call("unbind_router"), nil, nil) - --page.leaf = true - --page = entry({"api", "getDeviceAccessToken"}, call("rts_get_access_token"), nil, nil) - --page.leaf = true - - page = entry({"api", "sip"}, call("sip"), nil, nil) - page.leaf = true - page = entry({"api", "pysip"}, call("pysip"), nil, nil) - page.leaf = true - - page = entry({"api", "getconnectinfo"}, call("get_connect_info"), nil) - page.leaf = true - page = entry({"api", "getWifiSettings"}, call("nw_get_wifi_settings"), nil) - page.leaf = true - page = entry({"api", "getConnectDeviceList"}, call("nw_get_connect_device_list"), nil) - page.leaf = true - page = entry({"api", "getdevicedetails"}, call("nw_get_device_details"), nil) - page.leaf = true - page = entry({"api", "getNetDevice"}, call("get_net_device"), nil) - page.leaf = true - page = entry({"api", "getWanType"}, call("nw_get_wan_type"), nil) - page.leaf = true - page = entry({"api", "realtimenetspeed"}, call("nw_real_time_net_speed"), nil, nil) - page.leaf = true - page = entry({"api", "setWanType"}, call("nw_set_wan_type"), nil) - page.leaf = true - page = entry({"api", "setDeviceName"}, call("nw_set_device_name"), nil) - page.leaf = true - page = entry({"api", "setDiskAccess"}, call("nw_set_disk_access"), nil) - page.leaf = true - page = entry({"api", "setWanSwitch"}, call("nw_set_wan_switch"), nil) - page.leaf = true - page = entry({"api", "wifiSettings"}, call("nw_wifi_settings"), nil) - page.leaf = true - page = entry({"api", "gettxpowermode"}, call("nw_get_tx_power_mode"), nil) - page.leaf = true - page = entry({"api", "settxpowermode"}, call("nw_set_tx_power_mode"), nil) - page.leaf = true - page = entry({"api", "getWirelessChannel"}, call("nw_get_wireless_channel"), nil) - page.leaf = true - page = entry({"api", "setWirelessChannel"}, call("nw_set_wireless_channel"), nil) - page.leaf = true - - page = entry({"api", "diskinfo"}, call("nw_get_disk_info"), nil) - page.leaf = true - page = entry({"api", "diskformat"}, call("disk_formatting"), nil, nil) - page.leaf = true - - page = entry({"api", "factoryreset"}, call("factory_reset"), nil, nil) - page.leaf = true - page = entry({"api", "reboot"}, call("nw_exec_reboot"), nil, nil) - page.leaf = true - page = entry({"api", "localupgrade"}, call("local_upgrade"), nil, nil) - page.leaf = true - page = entry({"api", "silentupgrade"}, call("silent_upgrade"), nil, nil) - page.leaf = true - - page = entry({"api", "checkSysPassword"}, call("nw_check_sys_password"), nil) - page.leaf = true - page = entry({"api", "setpasswd"}, call("set_passwd"), nil, nil) - page.leaf = true - - page = entry({"api", "downloadstart"}, call("nw_download_task_start"), nil, nil) - page.leaf = true - page = entry({"api", "getActiveList"}, call("nw_get_active_list"), nil, nil) - page.leaf = true - page = entry({"api", "getHistoryList"}, call("nw_get_history_list"), nil, nil) - page.leaf = true - page = entry({"api", "operateTask"}, call("nw_download_task_operate"), nil, nil) - page.leaf = true - page = entry({"api", "getPauseList"}, call("nw_get_pause_list"), nil, nil) - page.leaf = true - page = entry({"api", "thunder_get_bind_code"}, call("nw_thunder_get_bind_code"), nil, nil) - page.leaf = true - - page = entry({"api", "batchFileCompareUpload"}, call("batchfile_compare_upload"), nil, nil) - page.leaf = true - page = entry({"api", "batchFileCheckList"}, call("batchfile_checklist"), nil, nil) - page.leaf = true - page = entry({"api", "getFilesList"}, call("getFilesList"), nil, nil) - page.leaf = true - --page = entry({"api", "setPPPoE"}, call("set_pppoe"), nil) - --page.leaf = true - - page = entry({"api", "checkupgrade"}, call("nw_check_upgrade"), nil) - page.leaf = true - page = entry({"api", "doupgrade"}, call("nw_do_upgrade"), nil) - page.leaf = true - - page = entry({"api", "setsmbsingleswitch"}, call("setsmbsingleswitch"),nil) - page.leaf = true - page = entry({"api", "setsmbswitch"}, call("nw_set_smbswitch"), nil) - page.leaf = true - page = entry({"api", "getsmbsingleswitch"}, call("getsmbsingleswitch"),nil) - page.leaf = true - page = entry({"api", "getsmbswitch"}, call("nw_get_smbswitch"), nil) - page.leaf = true - - page = entry({"api", "scanBleSwitch"}, call("nw_scan_ble_switch"), nil) - page.leaf = true - page = entry({"api", "getBleDeviceList"}, call("nw_get_ble_device_list"), nil) - page.leaf = true - page = entry({"api", "addMeshDevice"}, call("nw_add_ble_mesh_device"), nil) - page.leaf = true - page = entry({"api", "removeBleFromMesh"}, call("nw_remove_ble_from_mesh"), nil) - page.leaf = true - page = entry({"api", "getMeshDeviceDetail"}, call("nw_get_ble_device_status"), nil) - page.leaf = true - page = entry({"api", "getMeshDeviceList"}, call("nw_get_mesh_device_list"), nil) - page.leaf = true - page = entry({"api", "dismissMesh"}, call("nw_dismiss_mesh"), nil) - page.leaf = true - page = entry({"api", "setMeshDeviceAttr"}, call("nw_set_mesh_device_attr"), nil) - page.leaf = true - page = entry({"api", "rebootMeshDevice"}, call("nw_reboot_mesh_device"), nil) - page.leaf = true - page = entry({"api", "unmeshAllDevice"}, call("nw_unmesh_all_device"), nil) - page.leaf = true - page = entry({"api", "setMeshDeviceTimer"}, call("nw_set_mesh_device_timer"), nil) - page.leaf = true - page = entry({"api", "delMeshDeviceTimer"}, call("nw_del_mesh_device_timer"), nil) - page.leaf = true - page = entry({"api", "setMeshNetWorkPassword"}, call("nw_set_mesh_network_pwd"), nil) - page.leaf = true - page = entry({"api", "setLampBrightness"}, call("nw_set_lamp_brightness"), nil) - page.leaf = true - - -end - -function nw_check_upgrade() - local ret = check_upgrade() - luci.http.write(ret) -end - -function nw_do_upgrade() - local ret = {} - luci.http.status(200, "upgrading....") - ret["code"] = 2004 - ret["result"] = "upgrading...." - luci.http.write(data_to_json(ret)) - do_upgrade() -end - -function nw_real_time_net_speed() - luci.http.prepare_content("application/json") - local result = real_time_net_speed() - luci.http.write_json(result) -end - -function setsmbsingleswitch() - --local mac = luci.http.formvalue("mac") - --generate a white/black list to store this mac. - --if you want a mac not rw hdd, then write his mac into deny list. - --if you want a mac rw hdd, write his mac into allow list. - --modify smb.conf to ban this user's access. - --restart samba service -end - -function setsmbswitch() - local result = {} - local code = false - local onoff = luci.http.formvalue("smbswitch") - if (tonumber)(onoff) == 1 then - luci.sys.init.enable("samba") - exec_cmd_in_sh("sleep 1") - if luci.sys.init.enabled("samba") == true then - code = true - else - code = false - end - elseif (tonumber)(onoff) == 0 then - luci.sys.init.disable("samba") - exec_cmd_in_sh("sleep 1") - if luci.sys.init.enabled("samba") == true then - code = false - else - code = true - end - end - - result["result"] = code - luci.http.write_json(result) - -end - -function getsmbsingleswitch() --- -end - -function getsmbswitch() - local smbswitch = {} - local code = false - code = luci.sys.init.enabled("samba") - smbswitch["smbswitch"] = code - luci.http.write_json(smbswitch) -end - -function nw_exec_reboot() - local ret = {} - ret["result"] = true - luci.http.write_json(ret) - exec_reboot() -end diff --git a/Me_Lua/h10/luci/controller/bs/index.lua b/Me_Lua/h10/luci/controller/bs/index.lua deleted file mode 100644 index bb93e3e..0000000 --- a/Me_Lua/h10/luci/controller/bs/index.lua +++ /dev/null @@ -1,149 +0,0 @@ -module("luci.controller.bs.index", package.seeall) - - -local arpmon = require "meizu.arpmon" -local bfs = require "meizu.bfs" -local btfs = require "meizu.btfs" - -nw_get_bluetooth_info = btfs.nw_get_bluetooth_info -new_device_notify = arpmon.new_device_notify - -function index() - local root = node() - if not root.target then - root.target = alias("bs") - root.index = true - end - local page = node("bs") - --page.target = firstchild() - page.title = _("bs") - page.order = 10 - page.index = true - page = entry({"bs", "info"}, call("info"), nil, nil) - page.leaf = true - page = entry({"bs", "token"}, call("token"), nil, nil) - page.leaf = true - - page = entry({"bs", "newdevicenotify"}, call("new_device_notify"), nil) - page.leaf = true - - page = entry({"bs", "devip"}, call("devip"), nil, nil) - page.leaf = true - page = entry({"bs", "testip"}, call("testip"), nil, nil) - page.leaf = true - page = entry({"bs", "normip"}, call("normip"), nil, nil) - page.leaf = true - - page = entry({"bs", "apk"}, call("apk"), nil) - page.leaf = true - - page = entry({"bs", "getToken"}, call("get_token"), nil) - page.leaf = true - page = entry({"bs", "sysauth"}, call("sysauth"), nil) - page.leaf = true - - page = entry({"bs", "getBluetoothInfo"}, call("nw_get_bluetooth_info"), nil) - page.leaf = true - -end - -function info() - luci.http.prepare_content("application/json") - local result = bfs.sysinfo() - luci.http.write_json(result) -end - -function token() - luci.http.prepare_content("application/json") - local httpHandler = require("socket.http") - local usernm = luci.http.formvalue("username") - local passwd = luci.http.formvalue("password") - if usernm == nil and passwd == nil then - local sauth = require "luci.sauth" - local token = sauth.noAuthGetToken() - if token then - luci.http.write_json(token) - end - else - local ret = luci.sys.user.checkpasswd(usernm, passwd) - if ret == true then - local sauth = require "luci.sauth" - local token = sauth.noAuthGetToken() - if token then - luci.http.write_json(token) - end - end - end -end - -function show_hosts() - local lue = require"luci.util".exec - local cmd = "cat /etc/hosts" - local ret = lue(cmd) - luci.http.write(ret) -end - -function devip() - local lue = require"luci.util".exec - local cmd = "/usr/sbin/mzrts_ips.sh devip" - local ret = lue(cmd) - show_hosts() -end - -function normip() - local lue = require"luci.util".exec - local cmd = "/usr/sbin/mzrts_ips.sh" - local ret = lue(cmd) - show_hosts() -end - -function testip() - local lue = require"luci.util".exec - local cmd = "/usr/sbin/mzrts_ips.sh testip" - local ret = lue(cmd) - show_hosts() -end - -function apk() - local fn, fd, block - local cmd = "ls /www/apk_download/apk/*.apk | awk '{printf $1}'" - fd = io.popen(cmd) - fn = fd:read("*l") - fd:close() - if fn ~= nil then - fd = nixio.open(fn, "r") - luci.http.header('Content-Disposition', 'attachment; filename="%s"' % {nixio.fs.basename(fn)}) - luci.http.prepare_content("application/octet-stream") - while true do - block = fd:read(nixio.const.buffersize) - require "MZLog".log(3, debug.getinfo(1).currentline) - if (not block) or (#block == 0) then - require "MZLog".log(3, debug.getinfo(1).currentline) - break - else - luci.http.write(block) - end - end - fd:close() - end - luci.http.close() -end - -function sysauth() - local res = {} - local usernm = luci.http.formvalue("username") - local passwd = luci.http.formvalue("password") - res["result"] = luci.sys.user.checkpasswd(usernm, passwd) - luci.http.write_json(res) -end - -function get_token() - local res = {} - local sauth = require "luci.sauth" - local sess = luci.http.getcookie("sysauth") - sess = sess and sess:match("^[a-f0-9]*$") - local sdat = sauth.read(sess) - res["sysauth"] = sess - res["token"] = sdat.token - luci.http.write_json(res) -end diff --git a/Me_Lua/h10/luci/dispatcher.lua b/Me_Lua/h10/luci/dispatcher.lua deleted file mode 100644 index a8b7fd1..0000000 --- a/Me_Lua/h10/luci/dispatcher.lua +++ /dev/null @@ -1,965 +0,0 @@ ---[[ -LuCI - Dispatcher - -Description: -The request dispatcher and module dispatcher generators - -FileId: -$Id$ - -License: -Copyright 2008 Steven Barth - -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 diff --git a/Me_Lua/h10/luci/model/network.lua b/Me_Lua/h10/luci/model/network.lua deleted file mode 100644 index 41b0e99..0000000 --- a/Me_Lua/h10/luci/model/network.lua +++ /dev/null @@ -1,1632 +0,0 @@ ---[[ -LuCI - Network model - -Copyright 2009-2010 Jo-Philipp Wich - -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 type, next, pairs, ipairs, loadfile, table - = type, next, pairs, ipairs, loadfile, table - -local tonumber, tostring, math = tonumber, tostring, math - -local require = require - -local bus = require "ubus" -local nxo = require "nixio" -local nfs = require "nixio.fs" -local ipc = require "luci.ip" -local sys = require "luci.sys" -local utl = require "luci.util" -local dsp = require "luci.dispatcher" -local uci = require "luci.model.uci" -local lng = require "luci.i18n" - -module "luci.model.network" - - -IFACE_PATTERNS_VIRTUAL = { } -IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^lo$" } -IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^%w+%.network%d" } - - -protocol = utl.class() - -local _protocols = { } - -local _interfaces, _bridge, _switch, _tunnel -local _ubus, _ubusnetcache, _ubusdevcache, _ubuswificache -local _uci_real, _uci_state - -function _filter(c, s, o, r) - local val = _uci_real:get(c, s, o) - if val then - local l = { } - if type(val) == "string" then - for val in val:gmatch("%S+") do - if val ~= r then - l[#l+1] = val - end - end - if #l > 0 then - _uci_real:set(c, s, o, table.concat(l, " ")) - else - _uci_real:delete(c, s, o) - end - elseif type(val) == "table" then - for _, val in ipairs(val) do - if val ~= r then - l[#l+1] = val - end - end - if #l > 0 then - _uci_real:set(c, s, o, l) - else - _uci_real:delete(c, s, o) - end - end - end -end - -function _append(c, s, o, a) - local val = _uci_real:get(c, s, o) or "" - if type(val) == "string" then - local l = { } - for val in val:gmatch("%S+") do - if val ~= a then - l[#l+1] = val - end - end - l[#l+1] = a - _uci_real:set(c, s, o, table.concat(l, " ")) - elseif type(val) == "table" then - local l = { } - for _, val in ipairs(val) do - if val ~= a then - l[#l+1] = val - end - end - l[#l+1] = a - _uci_real:set(c, s, o, l) - end -end - -function _stror(s1, s2) - if not s1 or #s1 == 0 then - return s2 and #s2 > 0 and s2 - else - return s1 - end -end - -function _get(c, s, o) - return _uci_real:get(c, s, o) -end - -function _set(c, s, o, v) - if v ~= nil then - if type(v) == "boolean" then v = v and "1" or "0" end - return _uci_real:set(c, s, o, v) - else - return _uci_real:delete(c, s, o) - end -end - -function _wifi_iface(x) - local _, p - for _, p in ipairs(IFACE_PATTERNS_WIRELESS) do - if x:match(p) then - return true - end - end - return false -end - -function _wifi_state(key, val, field) - if not next(_ubuswificache) then - _ubuswificache = _ubus:call("network.wireless", "status", {}) or {} - end - - local radio, radiostate - for radio, radiostate in pairs(_ubuswificache) do - local ifc, ifcstate - for ifc, ifcstate in pairs(radiostate.interfaces) do - if ifcstate[key] == val then - return ifcstate[field] - end - end - end -end - -function _wifi_lookup(ifn) - -- got a radio#.network# pseudo iface, locate the corresponding section - local radio, ifnidx = ifn:match("^(%w+)%.network(%d+)$") - if radio and ifnidx then - local sid = nil - local num = 0 - - ifnidx = tonumber(ifnidx) - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device == radio then - num = num + 1 - if num == ifnidx then - sid = s['.name'] - return false - end - end - end) - - return sid - - -- looks like wifi, try to locate the section via state vars - elseif _wifi_iface(ifn) then - local sid = _wifi_state("ifname", ifn, "section") - if not sid then - _uci_state:foreach("wireless", "wifi-iface", - function(s) - if s.ifname == ifn then - sid = s['.name'] - return false - end - end) - end - - return sid - end -end - -function _iface_virtual(x) - local _, p - for _, p in ipairs(IFACE_PATTERNS_VIRTUAL) do - if x:match(p) then - return true - end - end - return false -end - -function _iface_ignore(x) - local _, p - for _, p in ipairs(IFACE_PATTERNS_IGNORE) do - if x:match(p) then - return true - end - end - return _iface_virtual(x) -end - - -function init(cursor) - _uci_real = cursor or _uci_real or uci.cursor() - _uci_state = _uci_real:substate() - - _interfaces = { } - _bridge = { } - _switch = { } - _tunnel = { } - - _ubus = bus.connect() - _ubusnetcache = { } - _ubusdevcache = { } - _ubuswificache = { } - - -- read interface information - local n, i - for n, i in ipairs(nxo.getifaddrs()) do - local name = i.name:match("[^:]+") - local prnt = name:match("^([^%.]+)%.") - - if _iface_virtual(name) then - _tunnel[name] = true - end - - if _tunnel[name] or not _iface_ignore(name) then - _interfaces[name] = _interfaces[name] or { - idx = i.ifindex or n, - name = name, - rawname = i.name, - flags = { }, - ipaddrs = { }, - ip6addrs = { } - } - - if prnt then - _switch[name] = true - _switch[prnt] = true - end - - if i.family == "packet" then - _interfaces[name].flags = i.flags - _interfaces[name].stats = i.data - _interfaces[name].macaddr = i.addr - elseif i.family == "inet" then - _interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask) - elseif i.family == "inet6" then - _interfaces[name].ip6addrs[#_interfaces[name].ip6addrs+1] = ipc.IPv6(i.addr, i.netmask) - end - end - end - - -- read bridge informaton - local b, l - for l in utl.execi("brctl show") do - if not l:match("STP") then - local r = utl.split(l, "%s+", nil, true) - if #r == 4 then - b = { - name = r[1], - id = r[2], - stp = r[3] == "yes", - ifnames = { _interfaces[r[4]] } - } - if b.ifnames[1] then - b.ifnames[1].bridge = b - end - _bridge[r[1]] = b - elseif b then - b.ifnames[#b.ifnames+1] = _interfaces[r[2]] - b.ifnames[#b.ifnames].bridge = b - end - end - end - - return _M -end - -function save(self, ...) - _uci_real:save(...) - _uci_real:load(...) -end - -function commit(self, ...) - _uci_real:commit(...) - _uci_real:load(...) -end - -function ifnameof(self, x) - if utl.instanceof(x, interface) then - return x:name() - elseif utl.instanceof(x, protocol) then - return x:ifname() - elseif type(x) == "string" then - return x:match("^[^:]+") - end -end - -function get_protocol(self, protoname, netname) - local v = _protocols[protoname] - if v then - return v(netname or "__dummy__") - end -end - -function get_protocols(self) - local p = { } - local _, v - for _, v in ipairs(_protocols) do - p[#p+1] = v("__dummy__") - end - return p -end - -function register_protocol(self, protoname) - local proto = utl.class(protocol) - - function proto.__init__(self, name) - self.sid = name - end - - function proto.proto(self) - return protoname - end - - _protocols[#_protocols+1] = proto - _protocols[protoname] = proto - - return proto -end - -function register_pattern_virtual(self, pat) - IFACE_PATTERNS_VIRTUAL[#IFACE_PATTERNS_VIRTUAL+1] = pat -end - - -function has_ipv6(self) - return nfs.access("/proc/net/ipv6_route") -end - -function add_network(self, n, options) - local oldnet = self:get_network(n) - if n and #n > 0 and n:match("^[a-zA-Z0-9_]+$") and not oldnet then - if _uci_real:section("network", "interface", n, options) then - return network(n) - end - elseif oldnet and oldnet:is_empty() then - if options then - local k, v - for k, v in pairs(options) do - oldnet:set(k, v) - end - end - return oldnet - end -end - -function get_network(self, n) - if n and _uci_real:get("network", n) == "interface" then - return network(n) - end -end - -function get_networks(self) - local nets = { } - local nls = { } - - _uci_real:foreach("network", "interface", - function(s) - nls[s['.name']] = network(s['.name']) - end) - - local n - for n in utl.kspairs(nls) do - nets[#nets+1] = nls[n] - end - - return nets -end - -function del_network(self, n) - local r = _uci_real:delete("network", n) - if r then - _uci_real:delete_all("network", "alias", - function(s) return (s.interface == n) end) - - _uci_real:delete_all("network", "route", - function(s) return (s.interface == n) end) - - _uci_real:delete_all("network", "route6", - function(s) return (s.interface == n) end) - - _uci_real:foreach("wireless", "wifi-iface", - function(s) - local net - local rest = { } - for net in utl.imatch(s.network) do - if net ~= n then - rest[#rest+1] = net - end - end - if #rest > 0 then - _uci_real:set("wireless", s['.name'], "network", - table.concat(rest, " ")) - else - _uci_real:delete("wireless", s['.name'], "network") - end - end) - end - return r -end - -function rename_network(self, old, new) - local r - if new and #new > 0 and new:match("^[a-zA-Z0-9_]+$") and not self:get_network(new) then - r = _uci_real:section("network", "interface", new, _uci_real:get_all("network", old)) - - if r then - _uci_real:foreach("network", "alias", - function(s) - if s.interface == old then - _uci_real:set("network", s['.name'], "interface", new) - end - end) - - _uci_real:foreach("network", "route", - function(s) - if s.interface == old then - _uci_real:set("network", s['.name'], "interface", new) - end - end) - - _uci_real:foreach("network", "route6", - function(s) - if s.interface == old then - _uci_real:set("network", s['.name'], "interface", new) - end - end) - - _uci_real:foreach("wireless", "wifi-iface", - function(s) - local net - local list = { } - for net in utl.imatch(s.network) do - if net == old then - list[#list+1] = new - else - list[#list+1] = net - end - end - if #list > 0 then - _uci_real:set("wireless", s['.name'], "network", - table.concat(list, " ")) - end - end) - - _uci_real:delete("network", old) - end - end - return r or false -end - -function get_interface(self, i) - if _interfaces[i] or _wifi_iface(i) then - return interface(i) - else - local ifc - local num = { } - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - if s['.name'] == i then - ifc = interface( - "%s.network%d" %{s.device, num[s.device] }) - return false - end - end - end) - return ifc - end -end - -function get_interfaces(self) - local iface - local ifaces = { } - local seen = { } - local nfs = { } - local baseof = { } - - -- find normal interfaces - _uci_real:foreach("network", "interface", - function(s) - for iface in utl.imatch(s.ifname) do - if not _iface_ignore(iface) and not _wifi_iface(iface) then - seen[iface] = true - nfs[iface] = interface(iface) - end - end - end) - - for iface in utl.kspairs(_interfaces) do - if not (seen[iface] or _iface_ignore(iface) or _wifi_iface(iface)) then - nfs[iface] = interface(iface) - end - end - - -- find vlan interfaces - _uci_real:foreach("network", "switch_vlan", - function(s) - if not s.device then - return - end - - local base = baseof[s.device] - if not base then - if not s.device:match("^eth%d") then - local l - for l in utl.execi("swconfig dev %q help 2>/dev/null" % s.device) do - if not base then - base = l:match("^%w+: (%w+)") - end - end - if not base or not base:match("^eth%d") then - base = "eth0" - end - else - base = s.device - end - baseof[s.device] = base - end - - local vid = tonumber(s.vid or s.vlan) - if vid ~= nil and vid >= 0 and vid <= 4095 then - local iface = "%s.%d" %{ base, vid } - if not seen[iface] then - seen[iface] = true - nfs[iface] = interface(iface) - end - end - end) - - for iface in utl.kspairs(nfs) do - ifaces[#ifaces+1] = nfs[iface] - end - - -- find wifi interfaces - local num = { } - local wfs = { } - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - local i = "%s.network%d" %{ s.device, num[s.device] } - wfs[i] = interface(i) - end - end) - - for iface in utl.kspairs(wfs) do - ifaces[#ifaces+1] = wfs[iface] - end - - return ifaces -end - -function ignore_interface(self, x) - return _iface_ignore(x) -end - -function get_wifidev(self, dev) - if _uci_real:get("wireless", dev) == "wifi-device" then - return wifidev(dev) - end -end - -function get_wifidevs(self) - local devs = { } - local wfd = { } - - _uci_real:foreach("wireless", "wifi-device", - function(s) wfd[#wfd+1] = s['.name'] end) - - local dev - for _, dev in utl.vspairs(wfd) do - devs[#devs+1] = wifidev(dev) - end - - return devs -end - -function get_wifinet(self, net) - local wnet = _wifi_lookup(net) - if wnet then - return wifinet(wnet) - end -end - -function add_wifinet(self, net, options) - if type(options) == "table" and options.device and - _uci_real:get("wireless", options.device) == "wifi-device" - then - local wnet = _uci_real:section("wireless", "wifi-iface", nil, options) - return wifinet(wnet) - end -end - -function del_wifinet(self, net) - local wnet = _wifi_lookup(net) - if wnet then - _uci_real:delete("wireless", wnet) - return true - end - return false -end - -function get_status_by_route(self, addr, mask) - local _, object - for _, object in ipairs(_ubus:objects()) do - local net = object:match("^network%.interface%.(.+)") - if net then - local s = _ubus:call(object, "status", {}) - if s and s.route then - local rt - for _, rt in ipairs(s.route) do - if not rt.table and rt.target == addr and rt.mask == mask then - return net, s - end - end - end - end - end -end - -function get_status_by_address(self, addr) - local _, object - for _, object in ipairs(_ubus:objects()) do - local net = object:match("^network%.interface%.(.+)") - if net then - local s = _ubus:call(object, "status", {}) - if s and s['ipv4-address'] then - local a - for _, a in ipairs(s['ipv4-address']) do - if a.address == addr then - return net, s - end - end - end - if s and s['ipv6-address'] then - local a - for _, a in ipairs(s['ipv6-address']) do - if a.address == addr then - return net, s - end - end - end - end - end -end - -function get_wannet(self) - local net = self:get_status_by_route("0.0.0.0", 0) - return net and network(net) -end - -function get_wandev(self) - local _, stat = self:get_status_by_route("0.0.0.0", 0) - return stat and interface(stat.l3_device or stat.device) -end - -function get_wan6net(self) - local net = self:get_status_by_route("::", 0) - return net and network(net) -end - -function get_wan6dev(self) - local _, stat = self:get_status_by_route("::", 0) - return stat and interface(stat.l3_device or stat.device) -end - - -function network(name, proto) - if name then - local p = proto or _uci_real:get("network", name, "proto") - local c = p and _protocols[p] or protocol - return c(name) - end -end - -function protocol.__init__(self, name) - self.sid = name -end - -function protocol._get(self, opt) - local v = _uci_real:get("network", self.sid, opt) - if type(v) == "table" then - return table.concat(v, " ") - end - return v or "" -end - -function protocol._ubus(self, field) - if not _ubusnetcache[self.sid] then - _ubusnetcache[self.sid] = _ubus:call("network.interface.%s" % self.sid, - "status", { }) - end - if _ubusnetcache[self.sid] and field then - return _ubusnetcache[self.sid][field] - end - return _ubusnetcache[self.sid] -end - -function protocol.get(self, opt) - return _get("network", self.sid, opt) -end - -function protocol.set(self, opt, val) - return _set("network", self.sid, opt, val) -end - -function protocol.ifname(self) - local ifname - if self:is_floating() then - ifname = self:_ubus("l3_device") - else - ifname = self:_ubus("device") - end - if not ifname then - local num = { } - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] - and num[s.device] + 1 or 1 - - local net - for net in utl.imatch(s.network) do - if net == self.sid then - ifname = "%s.network%d" %{ s.device, num[s.device] } - return false - end - end - end - end) - end - return ifname -end - -function protocol.proto(self) - return "none" -end - -function protocol.get_i18n(self) - local p = self:proto() - if p == "none" then - return lng.translate("Unmanaged") - elseif p == "static" then - return lng.translate("Static address") - elseif p == "dhcp" then - return lng.translate("DHCP client") - else - return lng.translate("Unknown") - end -end - -function protocol.type(self) - return self:_get("type") -end - -function protocol.name(self) - return self.sid -end - -function protocol.uptime(self) - return self:_ubus("uptime") or 0 -end - -function protocol.expires(self) - local a = tonumber(_uci_state:get("network", self.sid, "lease_acquired")) - local l = tonumber(_uci_state:get("network", self.sid, "lease_lifetime")) - if a and l then - l = l - (nxo.sysinfo().uptime - a) - return l > 0 and l or 0 - end - return -1 -end - -function protocol.metric(self) - return tonumber(_uci_state:get("network", self.sid, "metric")) or 0 -end - -function protocol.ipaddr(self) - local addrs = self:_ubus("ipv4-address") - return addrs and #addrs > 0 and addrs[1].address -end - -function protocol.netmask(self) - local addrs = self:_ubus("ipv4-address") - return addrs and #addrs > 0 and - ipc.IPv4("0.0.0.0/%d" % addrs[1].mask):mask():string() -end - -function protocol.gwaddr(self) - local _, route - for _, route in ipairs(self:_ubus("route") or { }) do - if route.target == "0.0.0.0" and route.mask == 0 then - return route.nexthop - end - end -end - -function protocol.dnsaddrs(self) - local dns = { } - local _, addr - for _, addr in ipairs(self:_ubus("dns-server") or { }) do - if not addr:match(":") then - dns[#dns+1] = addr - end - end - return dns -end - -function protocol.ip6addr(self) - local addrs = self:_ubus("ipv6-address") - if addrs and #addrs > 0 then - return "%s/%d" %{ addrs[1].address, addrs[1].mask } - else - addrs = self:_ubus("ipv6-prefix-assignment") - if addrs and #addrs > 0 then - return "%s/%d" %{ addrs[1].address, addrs[1].mask } - end - end -end - -function protocol.gw6addr(self) - local _, route - for _, route in ipairs(self:_ubus("route") or { }) do - if route.target == "::" and route.mask == 0 then - return ipc.IPv6(route.nexthop):string() - end - end -end - -function protocol.dns6addrs(self) - local dns = { } - local _, addr - for _, addr in ipairs(self:_ubus("dns-server") or { }) do - if addr:match(":") then - dns[#dns+1] = addr - end - end - return dns -end - -function protocol.is_bridge(self) - return (not self:is_virtual() and self:type() == "bridge") -end - -function protocol.opkg_package(self) - return nil -end - -function protocol.is_installed(self) - return true -end - -function protocol.is_virtual(self) - return false -end - -function protocol.is_floating(self) - return false -end - -function protocol.is_empty(self) - if self:is_floating() then - return false - else - local rv = true - - if (self:_get("ifname") or ""):match("%S+") then - rv = false - end - - _uci_real:foreach("wireless", "wifi-iface", - function(s) - local n - for n in utl.imatch(s.network) do - if n == self.sid then - rv = false - return false - end - end - end) - - return rv - end -end - -function protocol.add_interface(self, ifname) - ifname = _M:ifnameof(ifname) - if ifname and not self:is_floating() then - -- if its a wifi interface, change its network option - local wif = _wifi_lookup(ifname) - if wif then - _append("wireless", wif, "network", self.sid) - - -- add iface to our iface list - else - _append("network", self.sid, "ifname", ifname) - end - end -end - -function protocol.del_interface(self, ifname) - ifname = _M:ifnameof(ifname) - if ifname and not self:is_floating() then - -- if its a wireless interface, clear its network option - local wif = _wifi_lookup(ifname) - if wif then _filter("wireless", wif, "network", self.sid) end - - -- remove the interface - _filter("network", self.sid, "ifname", ifname) - end -end - -function protocol.get_interface(self) - if self:is_virtual() then - _tunnel[self:proto() .. "-" .. self.sid] = true - return interface(self:proto() .. "-" .. self.sid, self) - elseif self:is_bridge() then - _bridge["br-" .. self.sid] = true - return interface("br-" .. self.sid, self) - else - local ifn = nil - local num = { } - for ifn in utl.imatch(_uci_real:get("network", self.sid, "ifname")) do - ifn = ifn:match("^[^:/]+") - return ifn and interface(ifn, self) - end - ifn = nil - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - - local net - for net in utl.imatch(s.network) do - if net == self.sid then - ifn = "%s.network%d" %{ s.device, num[s.device] } - return false - end - end - end - end) - return ifn and interface(ifn, self) - end -end - -function protocol.get_interfaces(self) - if self:is_bridge() or (self:is_virtual() and not self:is_floating()) then - local ifaces = { } - - local ifn - local nfs = { } - for ifn in utl.imatch(self:get("ifname")) do - ifn = ifn:match("^[^:/]+") - nfs[ifn] = interface(ifn, self) - end - - for ifn in utl.kspairs(nfs) do - ifaces[#ifaces+1] = nfs[ifn] - end - - local num = { } - local wfs = { } - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - - local net - for net in utl.imatch(s.network) do - if net == self.sid then - ifn = "%s.network%d" %{ s.device, num[s.device] } - wfs[ifn] = interface(ifn, self) - end - end - end - end) - - for ifn in utl.kspairs(wfs) do - ifaces[#ifaces+1] = wfs[ifn] - end - - return ifaces - end -end - -function protocol.contains_interface(self, ifname) - ifname = _M:ifnameof(ifname) - if not ifname then - return false - elseif self:is_virtual() and self:proto() .. "-" .. self.sid == ifname then - return true - elseif self:is_bridge() and "br-" .. self.sid == ifname then - return true - else - local ifn - for ifn in utl.imatch(self:get("ifname")) do - ifn = ifn:match("[^:]+") - if ifn == ifname then - return true - end - end - - local wif = _wifi_lookup(ifname) - if wif then - local n - for n in utl.imatch(_uci_real:get("wireless", wif, "network")) do - if n == self.sid then - return true - end - end - end - end - - return false -end - -function protocol.adminlink(self) - return dsp.build_url("admin", "network", "network", self.sid) -end - -function protocol.get_option_value(self,name) - return self:_get(name) -end - -function protocol.status(self) - local iface = uci.cursor_state():get_all("network", self.sid) - local proto = iface["proto"] - local ifname = iface["ifname"] - local device = iface["device"] - local up = tonumber(iface["up"]) - if proto == "pppoe" then - if device == nil then - return "down" - end - if up == nil then - return "connection" - end - if up == 1 then - return "up" - end - elseif proto == "3g" then - if device ~= ifname and up==nil then - return "down" - end - if device == ifname and up == nil then - return "connection" - end - if up == 1 then - return "up" - end - elseif proto == "static" then - if up == nil then - return "down" - end - if up == 1 then - return "up" - end - elseif proto == "dhcp" then - if up == nil then - return "down" - end - if up == 1 then - return "up" - end - end - return "unkown" -end - -interface = utl.class() - -function interface.__init__(self, ifname, network) - local wif = _wifi_lookup(ifname) - if wif then - self.wif = wifinet(wif) - self.ifname = _wifi_state("section", wif, "ifname") - end - - self.ifname = self.ifname or ifname - self.dev = _interfaces[self.ifname] - self.network = network -end - -function interface._ubus(self, field) - if not _ubusdevcache[self.ifname] then - _ubusdevcache[self.ifname] = _ubus:call("network.device", "status", - { name = self.ifname }) - end - if _ubusdevcache[self.ifname] and field then - return _ubusdevcache[self.ifname][field] - end - return _ubusdevcache[self.ifname] -end - -function interface.name(self) - return self.wif and self.wif:ifname() or self.ifname -end - -function interface.mac(self) - return (self:_ubus("macaddr") or "00:00:00:00:00:00"):upper() -end - -function interface.ipaddrs(self) - return self.dev and self.dev.ipaddrs or { } -end - -function interface.ip6addrs(self) - return self.dev and self.dev.ip6addrs or { } -end - -function interface.type(self) - if self.wif or _wifi_iface(self.ifname) then - return "wifi" - elseif _bridge[self.ifname] then - return "bridge" - elseif _tunnel[self.ifname] then - return "tunnel" - elseif self.ifname:match("%.") then - return "vlan" - elseif _switch[self.ifname] then - return "switch" - else - return "ethernet" - end -end - -function interface.shortname(self) - if self.wif then - return "%s %q" %{ - self.wif:active_mode(), - self.wif:active_ssid() or self.wif:active_bssid() - } - else - return self.ifname - end -end - -function interface.get_i18n(self) - if self.wif then - return "%s: %s %q" %{ - lng.translate("Wireless Network"), - self.wif:active_mode(), - self.wif:active_ssid() or self.wif:active_bssid() - } - else - return "%s: %q" %{ self:get_type_i18n(), self:name() } - end -end - -function interface.get_type_i18n(self) - local x = self:type() - if x == "wifi" then - return lng.translate("Wireless Adapter") - elseif x == "bridge" then - return lng.translate("Bridge") - elseif x == "switch" then - return lng.translate("Ethernet Switch") - elseif x == "vlan" then - return lng.translate("VLAN Interface") - elseif x == "tunnel" then - return lng.translate("Tunnel Interface") - else - return lng.translate("Ethernet Adapter") - end -end - -function interface.adminlink(self) - if self.wif then - return self.wif:adminlink() - end -end - -function interface.ports(self) - local members = self:_ubus("bridge-members") - if members then - local _, iface - local ifaces = { } - for _, iface in ipairs(members) do - ifaces[#ifaces+1] = interface(iface) - end - end -end - -function interface.bridge_id(self) - if self.br then - return self.br.id - else - return nil - end -end - -function interface.bridge_stp(self) - if self.br then - return self.br.stp - else - return false - end -end - -function interface.is_up(self) - return self:_ubus("up") or false -end - -function interface.is_bridge(self) - return (self:type() == "bridge") -end - -function interface.is_bridgeport(self) - return self.dev and self.dev.bridge and true or false -end - -function interface.tx_bytes(self) - local stat = self:_ubus("statistics") - return stat and stat.tx_bytes or 0 -end - -function interface.rx_bytes(self) - local stat = self:_ubus("statistics") - return stat and stat.rx_bytes or 0 -end - -function interface.tx_packets(self) - local stat = self:_ubus("statistics") - return stat and stat.tx_packets or 0 -end - -function interface.rx_packets(self) - local stat = self:_ubus("statistics") - return stat and stat.rx_packets or 0 -end - -function interface.get_network(self) - return self:get_networks()[1] -end - -function interface.get_networks(self) - if not self.networks then - local nets = { } - local _, net - for _, net in ipairs(_M:get_networks()) do - if net:contains_interface(self.ifname) or - net:ifname() == self.ifname - then - nets[#nets+1] = net - end - end - table.sort(nets, function(a, b) return a.sid < b.sid end) - self.networks = nets - return nets - else - return self.networks - end -end - -function interface.get_wifinet(self) - return self.wif -end - - -wifidev = utl.class() - -function wifidev.__init__(self, dev) - self.sid = dev - self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { } -end - -function wifidev.get(self, opt) - return _get("wireless", self.sid, opt) -end - -function wifidev.set(self, opt, val) - return _set("wireless", self.sid, opt, val) -end - -function wifidev.name(self) - return self.sid -end - -function wifidev.hwmodes(self) - local l = self.iwinfo.hwmodelist - if l and next(l) then - return l - else - return { b = true, g = true } - end -end - -function wifidev.get_i18n(self) - local t = "Generic" - if self.iwinfo.type == "wl" then - t = "Broadcom" - elseif self.iwinfo.type == "madwifi" then - t = "Atheros" - end - - local m = "" - local l = self:hwmodes() - if l.a then m = m .. "a" end - if l.b then m = m .. "b" end - if l.g then m = m .. "g" end - if l.n then m = m .. "n" end - if l.ac then m = "ac" end - - return "%s 802.11%s Wireless Controller (%s)" %{ t, m, self:name() } -end - -function wifidev.is_up(self) - if _ubuswificache[self.sid] then - return (_ubuswificache[self.sid].up == true) - end - - local up = false - _uci_state:foreach("wireless", "wifi-iface", - function(s) - if s.device == self.sid then - if s.up == "1" then - up = true - return false - end - end - end) - - return up -end - -function wifidev.get_wifinet(self, net) - if _uci_real:get("wireless", net) == "wifi-iface" then - return wifinet(net) - else - local wnet = _wifi_lookup(net) - if wnet then - return wifinet(wnet) - end - end -end - -function wifidev.get_wifinets(self) - local nets = { } - - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device == self.sid then - nets[#nets+1] = wifinet(s['.name']) - end - end) - - return nets -end - -function wifidev.add_wifinet(self, options) - options = options or { } - options.device = self.sid - - local wnet = _uci_real:section("wireless", "wifi-iface", nil, options) - if wnet then - return wifinet(wnet, options) - end -end - -function wifidev.del_wifinet(self, net) - if utl.instanceof(net, wifinet) then - net = net.sid - elseif _uci_real:get("wireless", net) ~= "wifi-iface" then - net = _wifi_lookup(net) - end - - if net and _uci_real:get("wireless", net, "device") == self.sid then - _uci_real:delete("wireless", net) - return true - end - - return false -end - - -wifinet = utl.class() - -function wifinet.__init__(self, net, data) - self.sid = net - - local num = { } - local netid - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - if s['.name'] == self.sid then - netid = "%s.network%d" %{ s.device, num[s.device] } - return false - end - end - end) - - local dev = _wifi_state("section", self.sid, "ifname") or netid - - self.netid = netid - self.wdev = dev - self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { } - self.iwdata = data or _uci_state:get_all("wireless", self.sid) or - _uci_real:get_all("wireless", self.sid) or { } -end - -function wifinet.get(self, opt) - return _get("wireless", self.sid, opt) -end - -function wifinet.set(self, opt, val) - return _set("wireless", self.sid, opt, val) -end - -function wifinet.mode(self) - return _uci_state:get("wireless", self.sid, "mode") or "ap" -end - -function wifinet.ssid(self) - return _uci_state:get("wireless", self.sid, "ssid") -end - -function wifinet.bssid(self) - return _uci_state:get("wireless", self.sid, "bssid") -end - -function wifinet.network(self) - return _uci_state:get("wifinet", self.sid, "network") -end - -function wifinet.id(self) - return self.netid -end - -function wifinet.name(self) - return self.sid -end - -function wifinet.ifname(self) - local ifname = self.iwinfo.ifname - if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then - ifname = self.wdev - end - return ifname -end - -function wifinet.get_device(self) - if self.iwdata.device then - return wifidev(self.iwdata.device) - end -end - -function wifinet.is_up(self) - local ifc = self:get_interface() - return (ifc and ifc:is_up() or false) -end - -function wifinet.active_mode(self) - local m = _stror(self.iwinfo.mode, self.iwdata.mode) or "ap" - - if m == "ap" then m = "Master" - elseif m == "sta" then m = "Client" - elseif m == "adhoc" then m = "Ad-Hoc" - elseif m == "mesh" then m = "Mesh" - elseif m == "monitor" then m = "Monitor" - end - - return m -end - -function wifinet.active_mode_i18n(self) - return lng.translate(self:active_mode()) -end - -function wifinet.active_ssid(self) - return _stror(self.iwinfo.ssid, self.iwdata.ssid) -end - -function wifinet.active_bssid(self) - return _stror(self.iwinfo.bssid, self.iwdata.bssid) or "00:00:00:00:00:00" -end - -function wifinet.active_encryption(self) - local enc = self.iwinfo and self.iwinfo.encryption - return enc and enc.description or "-" -end - -function wifinet.assoclist(self) - return self.iwinfo.assoclist or { } -end - -function wifinet.frequency(self) - local freq = self.iwinfo.frequency - if freq and freq > 0 then - return "%.03f" % (freq / 1000) - end -end - -function wifinet.bitrate(self) - local rate = self.iwinfo.bitrate - if rate and rate > 0 then - return (rate / 1000) - end -end - -function wifinet.channel(self) - return self.iwinfo.channel or - tonumber(_uci_state:get("wireless", self.iwdata.device, "channel")) -end - -function wifinet.signal(self) - return self.iwinfo.signal or 0 -end - -function wifinet.noise(self) - return self.iwinfo.noise or 0 -end - -function wifinet.country(self) - return self.iwinfo.country or "00" -end - -function wifinet.txpower(self) - local pwr = (self.iwinfo.txpower or 0) - return pwr + self:txpower_offset() -end - -function wifinet.txpower_offset(self) - return self.iwinfo.txpower_offset or 0 -end - -function wifinet.signal_level(self, s, n) - if self:active_bssid() ~= "00:00:00:00:00:00" then - local signal = s or self:signal() - local noise = n or self:noise() - - if signal < 0 and noise < 0 then - local snr = -1 * (noise - signal) - return math.floor(snr / 5) - else - return 0 - end - else - return -1 - end -end - -function wifinet.signal_percent(self) - local qc = self.iwinfo.quality or 0 - local qm = self.iwinfo.quality_max or 0 - - if qc > 0 and qm > 0 then - return math.floor((100 / qm) * qc) - else - return 0 - end -end - -function wifinet.shortname(self) - return "%s %q" %{ - lng.translate(self:active_mode()), - self:active_ssid() or self:active_bssid() - } -end - -function wifinet.get_i18n(self) - return "%s: %s %q (%s)" %{ - lng.translate("Wireless Network"), - lng.translate(self:active_mode()), - self:active_ssid() or self:active_bssid(), - self:ifname() - } -end - -function wifinet.adminlink(self) - return dsp.build_url("admin", "network", "wireless", self.netid) -end - -function wifinet.get_network(self) - return self:get_networks()[1] -end - -function wifinet.get_networks(self) - local nets = { } - local net - for net in utl.imatch(tostring(self.iwdata.network)) do - if _uci_real:get("network", net) == "interface" then - nets[#nets+1] = network(net) - end - end - table.sort(nets, function(a, b) return a.sid < b.sid end) - return nets -end - -function wifinet.get_interface(self) - return interface(self:ifname()) -end - - --- setup base protocols -_M:register_protocol("static") -_M:register_protocol("dhcp") -_M:register_protocol("none") - --- load protocol extensions -local exts = nfs.dir(utl.libpath() .. "/model/network") -if exts then - local ext - for ext in exts do - if ext:match("%.lua$") then - require("luci.model.network." .. ext:gsub("%.lua$", "")) - end - end -end diff --git a/Me_Lua/h10/luci/sauth.lua b/Me_Lua/h10/luci/sauth.lua deleted file mode 100644 index ec02be8..0000000 --- a/Me_Lua/h10/luci/sauth.lua +++ /dev/null @@ -1,200 +0,0 @@ ---[[ - -Session authentication -(c) 2008 Steven Barth - -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 diff --git a/Me_Lua/h10/meizu/arpmon.lua b/Me_Lua/h10/meizu/arpmon.lua deleted file mode 100644 index e0f7160..0000000 --- a/Me_Lua/h10/meizu/arpmon.lua +++ /dev/null @@ -1,99 +0,0 @@ -module("meizu.arpmon", package.seeall) ---network functions - -local cjson = require "cjson" -local lfs = require "lfs" -local bfs = require "meizu.bfs" -local dbfs = require "meizu.dbfs" -local RC = require "meizu.r10config" -local sipfs = require "meizu.sipfs" -local nwfs = require "meizu.nwfs" - -local lue = require("luci.util").exec - -local bind_router = bfs.bind_router -local data_to_json = bfs.data_to_json -local exec_cmd_in_sh = bfs.exec_cmd_in_sh -local exec_reboot = bfs.exec_reboot -local get_device_SN = bfs.get_device_SN -local get_device_version = bfs.get_device_version -local get_https_data = bfs.get_https_data -local rts_get_access_token = bfs.rts_get_access_token -local set_passwd = bfs.set_passwd -local silent_upgrade = bfs.silent_upgrade -local strsplit = bfs.strsplit - -local delete_arp_all_mac = dbfs.delete_arp_all_mac -local fetch_arp_mac = dbfs.fetch_arp_mac -local get_dev_nick_name = dbfs.get_dev_nick_name -local init_arp_table = dbfs.init_arp_table -local insert_arp_macip = dbfs.insert_arp_macip - -function new_device_notify() - - init_arp_table() - local ret = {} - local cmd = [[cat /proc/net/arp |grep br-lan|awk '{print $1","$4}']] - local ipmacs = {} - local devs = lue(cmd) - if devs ~= "" then - ipmacs = strsplit(devs, '\n') - end - local new_devs = {} - ipmacs[#ipmacs] = nil - local wifiDeviceDict = nwfs.getAllWifiConnetDeviceDict() - for k, v in pairs(ipmacs) do - local ipmac = strsplit(v, ',') - local ip = ipmac[1] - local mac = ipmac[2] - mac = string.upper(mac) - local wifiType = wifiDeviceDict[mac] - local data = dbfs.fetch_wireless_device_mac(mac) - if wifiType ~= nil then - --local res = dbfs.fetch_wireless_device_mac(mac) - if data == "" then - dbfs.insert_wireless_device_mac(mac) - end - else - local ret = dbfs.fetch_wire_device_mac(mac) - local res = nwfs.is_device_online(ip) - if res == false and ret == "" and data == "" then - dbfs.insert_wireless_device_mac(mac) - elseif res == true and ret == "" then - dbfs.insert_wire_device_mac(mac, ip) - end - end - - if ip ~= "" then - if fetch_arp_mac(mac) == "" then - table.insert(new_devs, v) - end - end - end - delete_arp_all_mac() - for k, v in pairs(ipmacs) do - local ipmac = strsplit(v, ',') - local ip = ipmac[1] - local mac = ipmac[2] - if ip ~= "" then - insert_arp_macip(mac, ip) - end - end - for k, v in pairs(new_devs) do - local ipmac = strsplit(v, ',') - local ip = ipmac[1] - local mac = ipmac[2] - if ip ~= "" then - local logtype = 1 - ret["mac_address"] = mac - local nickname = get_dev_nick_name(mac) - if nickname and nickname ~= "" then - ret["name"] = nickname - else - ret["name"] = ip - end - local res, code, headers, status = sipfs.upload_router_log(data_to_json(ret), logtype) - end - end - luci.http.write_json(ret) -end diff --git a/Me_Lua/h10/meizu/bfs.lua b/Me_Lua/h10/meizu/bfs.lua deleted file mode 100644 index b62ae41..0000000 --- a/Me_Lua/h10/meizu/bfs.lua +++ /dev/null @@ -1,511 +0,0 @@ -module("meizu.bfs", package.seeall) ---API base functions - -local cjson = require "cjson" -local dbfs = require "meizu.dbfs" - -local delete_access_token = dbfs.delete_access_token - -function cal_str_md5(str) - local md5 = "" - local cmd = [[/bin/echo -n ']]..str - cmd = cmd..[['|/usr/bin/md5sum|/usr/bin/cut -d" " -f1]] - local fd = io.popen(cmd) - local ln = fd:read("*l") - if ln ~= nil then - md5 = ln - end - fd:close() - return md5 -end - -function strsplit(str, delim, maxNb) - local result = {} - if delim == nil then - delim = '\n' - end - if string.find(str, delim) == nil then - return { str } - end - if maxNb == nil or maxNb < 1 then - maxNb = 0 - end - local pat = "(.-)" .. delim .. "()" - local nb = 0 - local lastPos - for part, pos in string.gfind(str, pat) do - nb = nb + 1 - result[nb] = part - lastPos = pos - if nb == maxNb then break end - end - if nb ~= maxNb then - result[nb + 1] = string.sub(str, lastPos) - end - - return result -end - -function data_to_json(x) - local buf = "" - if x == nil then - return "" - elseif x == "" then - return '""' - elseif type(x) == "table" then - local k, v - if type(next(x)) == "number" then - buf = buf.."[ " - for k, v in ipairs(x) do - buf = buf..data_to_json(v) - if next(x, k) then - buf = buf..", " - end - end - buf = buf.." ]" - else - buf = buf.."{ " - for k, v in pairs(x) do - buf = buf..string.format("%q: " % k) - buf = buf..data_to_json(v) - if next(x, k) then - buf = buf..", " - end - end - buf = buf.." }" - end - elseif type(x) == "number" or type(x) == "boolean" then - if (x ~= x) then - buf = buf.."Number.NaN" - else - buf = buf..tostring(x) - end - else - buf = buf..string.format('"%s"' % tostring(x):gsub('[%z\1-\31]', function(c) return '\\u%04x' % c:byte(1) end)) - end - return buf -end - -function exec_cmd_in_sh(command) - local nio = require("nixio") - require "MZLog".log(3, command) - local pid = nio.fork() - if pid > 0 then - return - elseif pid == 0 then - nio.chdir("/") - local null = nio.open("/dev/null", "w+") - if null then - nio.dup(null, nio.stderr) - nio.dup(null, nio.stdout) - nio.dup(null, nio.stdin) - if null:fileno() > 2 then - null:close() - end - end - nio.exec("/bin/sh", "-c", command) - end -end - ---local get_https_data = function(url, data) return require("ssl.https").request(url, data) end ---return res, code, headers, status -function get_https_data(url, data) - if data ~= nil then - return require("ssl.https").request(url, data) - else - return require("ssl.https").request(url) - end -end - -function decodeURI(s) - local s = string.gsub(s, '%%(%x%x)', function(h) return string.char(tonumber(h, 16)) end) - return s -end - -function encodeURI(s) - local s = string.gsub(s, "([^%w%.%- ])", function(c) return string.format("%%%02X", string.byte(c)) end) - return string.gsub(s, " ", "+") -end - -function b64enc(data) - local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - return ((data:gsub('.', function(x) - local r,b='',x:byte() - for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end - return r; - end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x) - if (#x < 6) then return '' end - local c=0 - for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end - return b:sub(c+1,c+1) - end)..({ '', '==', '=' })[#data%3+1]) -end - -function b64dec(data) - local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - data = string.gsub(data, '[^'..b..'=]', '') - return (data:gsub('.', function(x) - if (x == '=') then return '' end - local r,f='',(b:find(x)-1) - for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end - return r; - end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x) - if (#x ~= 8) then return '' end - local c=0 - for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end - return string.char(c) - end)) -end - -function exec_reboot() - --luci.sys.reboot() - exec_cmd_in_sh("reboot -f") -end - -function factory_reset() - --exec_cmd_in_sh("killall dropbear uhttpd; sleep 1; mtd erase nvram; mtd -r erase rootfs_data") - local result = {} - result["result"] = true - luci.http.write_json(result) - exec_cmd_in_sh("killall dropbear uhttpd; sleep 1; /sbin/router_reset;/sbin/reboot") -end - -function set_passwd() - local p1 = luci.http.formvalue("pwd1") - local p2 = luci.http.formvalue("pwd2") - local stat = nil - if p1 ~= nil and luci.sys.user.checkpasswd("root", p1) then - if p2 ~= nil then - stat = luci.sys.user.setpasswd("root", p2) - luci.http.status(200, "setpasswd successful!") - luci.http.write("setpasswd successful!") - return - end - end - luci.http.status(500, "Bad passwd!") - --luci.http.write("setpasswd failed!") -end - -function rts_get_access_token() - local dbfs = require "meizu.dbfs" - dbfs.init_access_token_table() - local dbdata = dbfs.fetch_access_token() - local token - if #dbdata > 0 then - for _, data in ipairs(dbdata) do - local tokenFromdb = data.token - local expireTimeFromdb = data.expireTime - local nowTime = os.time() - if expireTimeFromdb < nowTime then - require "MZLog".log(3, "expireTime expire") - local httpsData = https_get_access_token() - token = httpsData.access_token - dbfs.update_access_token(tokenFromdb, token, httpsData.expires_in + os.time() - 10) - else - require "MZLog".log(3, "token from db") - token = tokenFromdb - end - end - else - local httpsData = https_get_access_token() - token = httpsData.access_token - require "MZLog".log(3, "token from https") - dbfs.add_access_token(token, httpsData.expires_in + os.time() - 10) - end - return token -end - -function https_get_access_token() - local url = "https://api.meizu.com/oauth/token?scope=router_trust&device=" - local suffix = "&password=&grant_type=device_only&client_id=gkzyJzq4RPoaov3BamqsJgg&client_secret=yh9bdKurxxotCjrEvJOiumk2mrzhcyej" - local SN = get_device_SN() - url = url..SN..suffix - local res, code, headers, status = get_https_data(url) - local data = cjson.decode(res) - return data -end - -function get_user_access_token() - local res, code, headers, status - local url = 'https://api.meizu.com/oauth/token?grant_type=password&client_id=gkzyJzq4RPoaov3BamqsJgg&client_secret=yh9bdKurxxotCjrEvJOiumk2mrzhcyej&username=appadmin@flyme.cn&password=appadmin111&scope=router_trust' - local res, code, headers, status = get_https_data(url) - local data = cjson.decode(res) - return data.access_token -end - -function init_bind_router_body(access_token) - local body = "access_token=" - local uat = luci.http.formvalue("uat") - body = body..access_token - body = body.."&user_access_token=" - body = body..uat - return body -end - -function bind_router() - local url = "https://router.meizu.com/oauth/router/bindRouter" - local access_token = rts_get_access_token() - local body = init_bind_router_body(access_token) - local https = require("ssl.https") - local res, code, headers, status = https.request(url, body) - if code == 401 then - delete_access_token() - access_token = rts_get_access_token() - body = init_bind_router_body(access_token) - res, code, headers, status = https.request(url, body) - end - luci.http.write(res) -end - -function unbind_router() - local url = 'https://router.meizu.com/oauth/user/unbind?access_token=' - local https = require("ssl.https") - local uat = luci.http.formvalue("uat") - url = url..uat - url = url..'&device='..get_device_SN() - local res, code, headers, status = https.request(url) - luci.http.write(res) -end - -function get_device_SN() - local sn = "" - local fd = io.popen("nvram get sn") - if fd then - local ln = fd:read("*l") - if ln ~= nil then - sn = ln - end - fd:close() - end - return sn -end - -function get_device_version() - local device_version = "1.0.0" - --[[ - [local pcall, dofile = pcall, dofile - [if pcall(dofile, "/etc/openwrt_release") then - [ if DISTRIB_RELEASE ~= nil then - [ device_version = DISTRIB_RELEASE - [ end - [end - ]] - local lu = require("luci.util") - local cmd = [[cat /etc/openwrt_version|awk '{printf $1}']] - local v = lu.exec(cmd) - if v ~= nil then - device_version = v - end - return device_version -end - -function silent_upgrade() - local fd = nil - local image = "/tmp/firmware.img" - local touchcmd = "touch "..image - exec_cmd_in_sh(touchcmd) - local function image_supported() - return ( 0 == os.execute( - ". /lib/functions.sh; " .. - "include /lib/upgrade; " .. - "platform_check_image %q >/dev/null" - % image - )) - end - if luci.http.formvalue("act") == "update" then - luci.http.write("act == update") - end - if image_supported() then - luci.http.write("updating") - exec_cmd_in_sh("killall dropbear uhttpd; sleep 1; /sbin/sysupgrade -v %q" %{ image }) - luci.http.write("update finished!") - else - luci.http.write("image_supported check failed!") - end -end - -function batchfile_checklist() - local IMEI = luci.http.formvalue("imei") - local dbfs = require "meizu.dbfs" - local searchEndFlag = "searchend" - local flag = dbfs.fetchBatchFileEndFlag(searchEndFlag, IMEI) - dbfs.deleteBatchFileEndFlag(searchEndFlag, IMEI) - local res = dbfs.fetchAllBatchFile(IMEI) - local result = res - dbfs.deleteBatchFile(IMEI) - res = cjson.encode(res) - - if next(result) ~= nil then - if flag.hashCode ~= nil then - res = '{"status":"2002", "data":'..res.."}" - else - res = '{"status":"2001", "data":'..res.."}" - end - else - res = '{"status":"2003"}' - end - luci.http.write(res) - return res -end - -function findInDir(rootpath, wefind, hashCode, md5sum, IMEI) - local dbfs = require "meizu.dbfs" - local flag = 0 - local ret, files, iter = pcall(lfs.dir, rootpath) - if ret == false then - return nil - end - for entry in files, iter do - if entry ~= '.' and entry ~= '..' then - local f = rootpath .. '/' .. entry - local filename = string.match(f, ".+/([^/]*%.%w+)$") - - if wefind == filename then - flag = 1 - if(md5sum == luci.sys.exec("md5sum %q" % f):match("^([^%s]+)")) then - require "MZLog".log(3, debug.getinfo(1).currentline) - else - dbfs.addBatchFile(hashCode, IMEI) - end - end - end - end - return flag -end - -function batchfile_compare_upload() - local data = luci.http.formvalue("data") - local tableData = cjson.decode(data) - local dbfs = require "meizu.dbfs" - dbfs.initBatchFileTable() - local LuciUtil = require("luci.util") - local sharePath = "/mnt/Image" - local ID = nil - for key, value in pairs(tableData) do - local wefind = value.fileName - local md5sum = value.md5 - local hashCode = value.hashCode - local IMEI = value.imei - local rootpath = sharePath - ID = IMEI - - local ret, files, iter = pcall(lfs.dir, rootpath) - if ret == false then - dbfs.addBatchFile(hashCode, IMEI) - end - local flag = findInDir(rootpath, wefind, hashCode, md5sum, IMEI) - if flag == 0 then - dbfs.addBatchFile(hashCode, IMEI) - end - end - local searchEndFlag = "searchend" - dbfs.addBatchFile(searchEndFlag, ID) -end - -function table_merge(t1, t2) - if (type(t1) == "table") and (type(t2) == "table") then - for k, v in pairs(t2) do - if (type(v) == "table") and (type(t1[k] or false) == "table") then - table_merge(t1[k], t2[k]) - else - t1[k] = v - end - end - end - return t1 -end - -function get_files_list(path, start, count, ID) - local result = {} - local ret, files, iter = pcall(lfs.dir, path) - local cmd_file = "ls -al " .. '"'.. path ..'"'.. " | awk '/^-/' | wc -l" - local cmd_dir = "ls -al " .. '"'.. path ..'"'.. " | awk '/^d/' | wc -l" - local luaUtil = require"luci.util" - local file_num = luaUtil.exec(cmd_file) - local dir_num = luaUtil.exec(cmd_dir) - local total_num = file_num + dir_num - 2 - local start = tonumber(start) - local count = tonumber(count) - local fs = require "nixio.fs" - - if ret == true then - for file in lfs.dir(path) do - if file ~= "." and file ~= ".." then - local f = path..'/'..file - local fname = file - local attr = lfs.attributes(f) - assert (type(attr) == "table") - - if attr.mode == "directory" then - local res = {name = "", isfile = nil, size = nil, time = nil} - local cmd_file = "ls -al " .. '"'.. f ..'"'.. " | awk '/^-/' | wc -l" - local cmd_dir = "ls -al " .. '"'.. f ..'"'.. " | awk '/^d/' | wc -l" - local size_file = luaUtil.exec(cmd_file) - local size_dir = luaUtil.exec(cmd_dir) - local size = size_file + size_dir - 2 - local name = fname - local stat = fs.stat(f) - local time = stat.mtime - res.name = fname - res.isfile = 0 - res.size = size - res.time = time - - table.insert(result, res) - else - local res = {name = "", isfile = nil, size = nil, time = nil} - local name = fname - local stat = fs.stat(f) - local time = stat.mtime - local size = nixio.fs.stat(f).size - res.name = fname - res.isfile = 1 - res.size = size - res.time = time - - table.insert(result, res) - end - end - end - if total_num > count then - total_num = count - end - - table.sort(result, function(a, b) return (a.isfile < b.isfile) end) - local res = {} - for i = start + 1, start + count do - table.insert(res, result[i]) - end - - local res = cjson.encode(res) - path = string.gsub(path, "mnt", "router") - res = '{"result":true, "start":'..start..', "count":'..total_num..', "path":"'..path..'", "fileinfo":'..res.."}" - luci.http.write(res) - return res - end -end - -function getFilesList() - local path = luci.http.formvalue("path") - local start = luci.http.formvalue("start") - local count = luci.http.formvalue("count") - local ID = luci.http.formvalue("ID") - local result = get_files_list(path, start, count, ID) - --luci.http.write(result) - return result -end - -function sysinfo() - local lue = require("luci.util").exec - local ret = {} - ret["romversion"] = get_device_version() - ret["SN"] = get_device_SN() - ret["deviceModel"] = "R10" - ret["routername"] = "mzrt"..get_device_SN() - local ssid1, ssid2 = require "meizu.nwfs".get_wifi_ssids() - ret["ssid1"] = ssid1 - ret["ssid2"] = ssid2 - local cmd = [[df /mnt|grep -q sda;echo -n $?]] - ret["diskstatus"] = lue(cmd) - return ret -end diff --git a/Me_Lua/h10/meizu/btfs.lua b/Me_Lua/h10/meizu/btfs.lua deleted file mode 100644 index 4c16467..0000000 --- a/Me_Lua/h10/meizu/btfs.lua +++ /dev/null @@ -1,1442 +0,0 @@ -module("meizu.btfs", package.seeall) ---network functions - -local cjson = require "cjson" -local lfs = require "lfs" -local bfs = require "meizu.bfs" -local RC = require "meizu.r10config" -local dbfs = require("meizu.dbfs") -local posix = require("Posix") - -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 b64dec = bfs.b64dec -local b64enc = bfs.b64enc - -local lue = require("luci.util").exec - ------------------------- bluetooth -------------------- - ------------------------ receive data -------------------- -function bluetooth_info() - dbfs.initBluetoothTable() - local value = luci.http.formvalue("data") - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, value) - local ret = {} - local types = string.sub(value, 1, 2) - - if types == "00" then - local id = string.sub(value, 3, 4) - local status = string.format("%d", "0x" .. string.sub(value, 5, 6)) - local temp1 = string.sub(value, 7, 8) - local temp2 = string.sub(value, 9, 10) - local temp = temp2..temp1 - temp = string.format("%d", "0x" .. temp) - local rh1 = string.sub(value, 11, 12) - local rh2 = string.sub(value, 13, 14) - local rh = rh2..rh1 - rh = string.format("%d", "0x" .. rh) - local light1 = string.sub(value, 15, 16) - local light2 = string.sub(value, 17, 18) - local light = light2..light1 - light = string.format("%d", "0x" .. light) - local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/"..mac.."0" - - ret["mac"] = mac - ret["id"] = id - if status == "1" then - ret["onoff"] = "on" - else - ret["onoff"] = "off" - end - local timer_id = "" - local flag = "" - local start = "" - local ends = "" - local fd = io.open(TMP, "r") - - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - timer_id = res.timerId - flag = res.flag - start = res.start - ends = res.ends - end - - ret["timerId"] = timer_id - ret["flag"] = flag - ret["start"] = start - ret["ends"] = ends - ret["temp"] = temp - ret["hemi"] = rh - ret["light"] = light - ret["time"] = os.time() - - local result = data_to_json(ret) - --[[ - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, id) - require "MZLog".log(3, result) - require "MZLog".log(3, ret) - ]] - local fd = assert(io.open(TMP, "w")) - fd:write(result) - fd:close() - - elseif types == "01" then - local id = string.sub(value, 3, 4) - local voltage1 = string.sub(value, 5, 6) - local voltage2 = string.sub(value, 7, 8) - local voltage = voltage2..voltage1 - voltage = string.format("%d", "0x" .. voltage) - local electricity1 = string.format("%d", "0x" .. string.sub(value, 9, 10)) - local electricity2 = string.format("%d", "0x" .. string.sub(value, 11, 12)) - local electricity = electricity2..electricity1 - electricity = string.format("%d", "0x" .. electricity) - local power1 = string.sub(value, 13, 14) - local power2 = string.sub(value, 15, 16) - local power = power2..power1 - power = string.format("%d", "0x" .. power) - local electric1 = string.sub(value, 17, 18) - local electric2 = string.sub(value, 19, 20) - local electric = electric2..electric1 - electric = string.format("%d", "0x" .. electric) - local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/"..mac.."1" - local timer_id = "" - local fd = io.open(TMP, "r") - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - timer_id = res.timerId - end - - ret["timerId"] = timer_id - ret["mac"] = mac - ret["id"] = id - ret["voltage"] = voltage - ret["current"] = electricity - ret["power"] = power - ret["energy"] = electric - - local result = data_to_json(ret) - local fd = assert(io.open(TMP, "w")) - fd:write(result) - fd:close() - - elseif types == "02" then - require "MZLog".log(3, debug.getinfo(1).currentline) - local id = string.sub(value, 3, 4) - local TYPE = string.sub(value, 5, 6) - local mac1 = string.sub(value, 7, 8) - local mac2 = string.sub(value, 9, 10) - local mac3 = string.sub(value, 11, 12) - local mac4 = string.sub(value, 13, 14) - local mac5 = string.sub(value, 15, 16) - local mac6 = string.sub(value, 17, 18) - local mac = mac6..mac5..mac4..mac3..mac2..mac1 - - mac = string.upper(mac) - local ID = "" - local res = dbfs.fetchBluetoothDevice(mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, #res) - require "MZLog".log(3, res) - if #res > 0 then - for k, v in pairs(res) do - ID = v.id - end - end - if id ~= ID then - dbfs.updateBluetoothDevice(id, "", "", "", mac) - end - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - res["time"] = os.time() - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - require "MZLog".log(3, id) - require "MZLog".log(3, mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - - elseif types == "09" then - local deviceType = string.sub(value, 3, 4) - local mac1 = string.sub(value, 5, 6) - local mac2 = string.sub(value, 7, 8) - local mac3 = string.sub(value, 9, 10) - local mac4 = string.sub(value, 11, 12) - local mac5 = string.sub(value, 13, 14) - local mac6 = string.sub(value, 15, 16) - local mac = mac6..mac5..mac4..mac3..mac2..mac1 - mac = string.upper(mac) - - local res = dbfs.fetchBluetoothDevice(mac) - local ret = nil - local id = nil - if #res > 0 then - for k, v in pairs(res) do - ret = v.mac - id = v.id - end - end - if id then - dbfs.updateBluetoothDevice("", "", "", "", mac) - end - if ret == nil then - dbfs.addBluetoothDevice("", mac, "", "", deviceType, "") - local TMP = "/tmp/"..mac - local fd = io.open(TMP, "w") - fd:write(os.time()) - fd:close() - else - local TMP = "/tmp/"..mac - local fd = io.open(TMP, "w") - fd:write(os.time()) - fd:close() - end - - elseif types == "04" then - local data = string.format("%d", "0x" .. string.sub(value, 3, 4)) - ret["data"] = data - - elseif types == "03" then - require "MZLog".log(3, debug.getinfo(1).currentline) - local id = string.sub(value, 3, 4) - local flag = string.sub(value, 5, 6) - local timer_id = string.sub(value, 7, 8) - local start = string.sub(value, 9, 16) - local ends = string.sub(value, 17, 24) - local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/"..mac.."1" - local fd = io.open(TMP, "r") - - if fd then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, timer_id) - require "MZLog".log(3, flag) - local res = fd:read() - res = cjson.decode(res) - if timer_id == res["timerId"] then - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - local res = fd:read() - res = cjson.decode(res) - res["flag"] = flag - res["timerId"] = timer_id - res["start"] = start - res["ends"] = ends - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - end - - elseif types == "06" then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - local id = string.sub(value, 3, 4) - local mac = dbfs.getBluetoothDevice(id) - local len = tonumber(dbfs.getBleDeviceNameLength(id)) - local str = string.sub(value, 5, len + 4) - --local res = {} - --[[ - for i = 1, #str, 2 do - res[#res + 1] = (tonumber(string.format("%d", "0x"..string.sub(str, i, i+1)))) - end - ]] - local device_name = str - --[[ - if #res == 1 then - device_name = string.char(res[1]) - elseif #res == 2 then - device_name = string.char(res[1], res[2]) - elseif #res == 3 then - device_name = string.char(res[1], res[2], res[3]) - elseif #res == 4 then - device_name = string.char(res[1], res[2], res[3], res[4]) - elseif #res == 5 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5]) - elseif #res == 6 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6]) - elseif #res == 7 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6], res[7]) - elseif #res == 8 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6], res[7], res[8]) - elseif #res == 9 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6], res[7], res[8], res[9]) - elseif #res == 10 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6], res[7], res[8], res[9], res[10]) - end - ]] - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, str) - require "MZLog".log(3, device_name) - dbfs.updateBluetoothDevice(id, "", device_name, len, mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - - elseif types == "07" then - local data = string.format("%d", "0x" .. string.sub(value, 3, 4)) - ret["data"] = data - - elseif types == "0b" then - local key_ack = string.sub(value, 3, 4) - local TMP = "/tmp/0b0b" - local fd = io.open(TMP, "w") - fd:write(key_ack) - fd:close() - - elseif types == "0c" then - local id = string.sub(value, 3, 4) - local status = string.sub(value, 5, 6) - local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - local res = nil - require "MZLog".log(3, debug.getinfo(1).currentline) - - if fd then - res = fd:read() - fd:close() - res = cjson.decode(res) - if status == "01" then - res["onoff"] = "on" - else - res["onoff"] = "off" - end - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - require "MZLog".log(3, res) - - elseif types == "0d" then - local id = string.sub(value, 3, 4) - local led_light = string.sub(value, 5, 6) - local temp1 = string.sub(value, 7, 8) - local temp2 = string.sub(value, 9, 10) - led_light = string.format("%d", "0x" .. led_light) - local led_temp = temp2..temp1 - temp = string.format("%d", "0x" .. temp) - - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - local res = nil - require "MZLog".log(3, debug.getinfo(1).currentline) - - if fd then - res = fd:read() - fd:close() - res = cjson.decode(res) - res["led_light"] = led_light - res["led_temp"] = led_temp - - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - - elseif types == "0e" then - local id = string.sub(value, 3, 4) - local wait_time = string.format("%d", "0x" .. string.sub(value, 5, 6)) - --local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/0e0e" - local fd = io.open(TMP, "w") - fd:write(wait_time) - fd:close() - - elseif types == "10" then - local mac1 = string.sub(value, 3, 4) - local mac2 = string.sub(value, 5, 6) - local mac3 = string.sub(value, 7, 8) - local mac4 = string.sub(value, 9, 10) - local mac5 = string.sub(value, 11, 12) - local mac6 = string.sub(value, 13, 14) - local mac = mac6..mac5..mac4..mac3..mac2..mac1 - mac = string.upper(mac) - - local res = dbfs.fetchBluetoothDevice(mac) - if #res == 0 then - dbfs.addBluetoothDevice("", mac, "0123", "", "", "") - end - --[[ - if ret == nil then - dbfs.addBluetoothDevice("", mac, "", "", deviceType, "") - local TMP = "/tmp/"..mac - local fd = io.open(TMP, "w") - fd:write(os.time()) - fd:close() - else - local TMP = "/tmp/"..mac - local fd = io.open(TMP, "w") - ]] - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, ret) - return ret -end - -function nw_get_bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - local res = bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_get_bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - local res = bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - return res -end - ------------------------ scan_ble_device -------------------- -function scan_ble_switch(status) - local res = {} - if status == "on" then - local cmd = "bt_daemon -s ".."16".." 255" - lue(cmd) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, cmd) - posix.sleep(1) - res["result"] = true - elseif status == "off" then - local cmd = "bt_daemon -s ".."18".." 255" - lue(cmd) - posix.sleep(1) - res["result"] = false - end - return res -end - -function nw_scan_ble_switch() - local status = luci.http.formvalue("status") - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, status) - local res = scan_ble_switch(status) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_scan_ble_switch(status) - local res = scan_ble_switch(status) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ get_ble_device_list -------------------- -function get_ble_device_list() - local res = dbfs.fetchAllBluetoothDevice() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, res) - local result = {} - if #res > 0 then - for k, v in pairs(res) do - local TMP = "/tmp/"..v.mac - local fd = io.open(TMP, "r") - if fd then - local time = fd:read() - fd:close() - if tonumber(os.time()) - tonumber(time) < 5 then - table.insert(result, v) - end - end - end - end - return result -end - -function nw_get_ble_device_list() - local res = get_ble_device_list() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if #res == 0 then - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write("[]") - else - luci.http.write_json(res) - end -end - -function ww_get_ble_device_list() - local res = get_ble_device_list() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if #res == 0 then - return "[]" - else - return cjson.encode(res) - end -end - ------------------------ add_ble_mesh_device -------------------- -function is_receive_id(mac) - local id = "" - local ret = dbfs.fetchBluetoothDevice(mac) - for k, v in pairs(ret) do - id = v.id - end - return id -end - -function add_ble_mesh_device(mac) - local res = {} - local id = "" - local mac1 = string.format("%d", "0x" .. string.sub(mac, 1, 2)) - local mac2 = string.format("%d", "0x" .. string.sub(mac, 3, 4)) - local mac3 = string.format("%d", "0x" .. string.sub(mac, 5, 6)) - local mac4 = string.format("%d", "0x" .. string.sub(mac, 7, 8)) - local mac5 = string.format("%d", "0x" .. string.sub(mac, 9, 10)) - local mac6 = string.format("%d", "0x" .. string.sub(mac, 11, 12)) - local macs = mac6.." "..mac5.." "..mac4.." "..mac3.." "..mac2.." "..mac1 - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, mac) - local cmd = "bt_daemon -s ".."17 "..macs - lue(cmd) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, cmd) - - for i = 1, 20 do - posix.sleep(1) - id = is_receive_id(mac) - if id ~= "" then - break - end - end - if id ~= "" then - res["result"] = true - res["id"] = id - res["mac"] = mac - else - res["result"] = false - res["mac"] = mac - end - return res -end - -function nw_add_ble_mesh_device() - local mac = luci.http.formvalue("mac") - local res = add_ble_mesh_device(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_add_ble_mesh_device(mac) - local res = add_ble_mesh_device(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ get_ble_device_detail -------------------- -function get_ble_device_status(mac) - local TMP1 = "/tmp/"..mac.."0" - local TMP2 = "/tmp/"..mac.."1" - local fd1 = io.open(TMP1, "r") - local fd2 = io.open(TMP2, "r") - if fd1 and fd2 then - local res1 = fd1:read() - local res2 = fd2:read() - fd1:close() - fd2:close() - --require "MZLog".log(3, res1) - --require "MZLog".log(3, res2) - if res1 ~= nil and res2 ~= nil then - res1 = cjson.decode(res1) - res2 = cjson.decode(res2) - res1["voltage"] = res2.voltage - res1["current"] = res2.current - res1["power"] = res2.power - res1["energy"] = res2.energy - - local ret = dbfs.fetchBluetoothDevice(mac) - local deviceType = nil - local name = nil - for k, v in pairs(ret) do - deviceType = v.deviceType - name = v.name - end - - res1["name"] = name - res1["type"] = deviceType - res1["time"] = nil - --require "MZLog".log(3, res1) - require "MZLog".log(3, debug.getinfo(1).currentline) - end - if res1 == "" then - res1 = "{}" - end - return res1 - else - return "{}" - end -end - -function nw_get_ble_device_status() - local mac = luci.http.formvalue("mac") - local res = get_ble_device_status(mac) - --require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if res == "{}" then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, res) - luci.http.write(res) - else - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, res) - luci.http.write_json(res) - end -end - -function ww_get_ble_device_status(mac) - local res = get_ble_device_status(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if res == "{}" then - return res - else - return cjson.encode(res) - end -end - ------------------------ remove_ble_from_mesh -------------------- -function is_remove_ble_from_mesh() - local res = nil - local TMP = "/tmp/0e0e" - local fd = io.open(TMP, "r") - if fd then - local ret = fd:read() - fd:close() - if ret ~= "" and ret ~= nil then - return ret - else - return nil - end - else - return nil - end -end - -function remove_ble_from_mesh(mac) - local res = {} - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - for k, v in pairs(ret) do - id = v.id - end - if id ~= nil and id ~= "" then - local cmd = "bt_daemon -s ".."3 "..string.format("%d", "0x"..id) - lue(cmd) - local wait_time = nil - for i = 1, 20 do - posix.sleep(1) - wait_time = is_remove_ble_from_mesh(mac) - if wait_time ~= nil then - break - end - end - if wait_time then - res["result"] = true - res["waitTime"] = wait_time - res["mac"] = mac - res["id"] =id - else - res["result"] = false - res["mac"] = mac - res["id"] = id - end - else - res["result"] = false - res["mac"] = mac - end - return res -end - -function nw_remove_ble_from_mesh() - local mac = luci.http.formvalue("mac") - local res = remove_ble_from_mesh(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_remove_ble_from_mesh(mac) - local res = remove_ble_from_mesh(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ get_mesh_device_list -------------------- -function is_file_exist(TMP) - local fd = io.open(TMP, "r") - if fd then - return fd - else - require "MZLog".log(3, debug.getinfo(1).currentline) - return false - end -end - -function get_mesh_device_list() - local result = {} - local ret = dbfs.fetchAllBleMeshDevice() - if #ret > 0 then - for k, v in pairs(ret) do - local res = {} - local TMP = "/tmp/" .. v.mac .."0" - local fd = nil - fd = is_file_exist(TMP) - --[[ - for i = 1, 5 do - fd = is_file_exist(TMP) - if fd then - break - else - posix.sleep(1) - end - end - ]] - if fd then - local value = fd:read() - if value ~= nil then - value = cjson.decode(value) - end - res["mac"] = v.mac - --res["online"] = true - res["name"] = v.name - res["type"] = v.deviceType - if value["onoff"] == "on" then - res["onoff"] = "on" - else - res["onoff"] = "off" - end - - if tonumber(os.time()) - tonumber(value.time) > 60 then - res["online"] = false - else - res["online"] = true - end - - if res["online"] == false then - res = nil - end - table.insert(result, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - - else - res["mac"] = v.mac - res["name"] = v.name - res["type"] = v.deviceType - res["onoff"] = "off" - res["online"] = false - table.insert(result, res) - require "MZLog".log (3, debug.getinfo(1).currentline) - end - end - end - return result -end - -function nw_get_mesh_device_list() - local res = get_mesh_device_list() - --require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if #res == 0 then - luci.http.write("[]") - else - luci.http.write_json(res) - end -end - -function ww_get_mesh_device_list() - local res = get_mesh_device_list() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if #res == 0 then - return "[]" - else - return cjson.encode(res) - end -end - ------------------------ dismiss_mesh -------------------- -function dismiss_mesh() - local res = {} - local cmd = "bt_daemon -s ".."3 ".." 255" - lue(cmd) - res["result"] = true -end -function nw_dismiss_mesh() - local res = dismiss_mesh() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - ------------------------ set_mesh_device_attr -------------------- -function is_switch_on(mac) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - if res["onoff"] == "on" then - return true - else - return nil - end - end -end - -function is_switch_off(mac) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - if res["onoff"] == "off" then - return true - else - return nil - end - end -end - -function is_set_name_ok(mac) - local name = "" - local ret = dbfs.fetchBluetoothDevice(mac) - for k, v in pairs(ret) do - name = v.name - end - return name -end - -function set_mesh_device_attr(mac, key, value) - local res = {} - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, mac) - require "MZLog".log(3, key) - require "MZLog".log(3, value) - - local fd = io.open("/tmp/meshDeviceFlag", "r") - if fd then - local time = tonumber(fd:read()) - if os.time() - time < 50 then - local res = {} - res["result"] = true - return res - end - end - - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - if #ret > 0 then - for k, v in pairs(ret) do - id = v.id - end - end - --[[ - local fd1 = io.open("/tmp/tmp", "a") - fd1:write(key) - fd1:write(value) - ]] - - - if id ~= nil then - --local cmd = "touch /tmp/flag" - --lue(cmd) - local fd = io.open("/tmp/meshDeviceFlag", "w") - fd:write(os.time()) - fd:close() - - if key == "8" and value == "true" then - local cmd = "bt_daemon -s ".."1 "..string.format("%d", "0x"..id).." 1" - lue(cmd) - local flag = nil - for i = 1, 10 do - flag = is_switch_on(mac) - if flag then - break - else - posix.sleep(1) - end - end - if flag then - res["result"] = true - res["mac"] = mac - res["key"] = key - res["onoff"] = " on" - else - res["result"] = false - res["mac"] = mac - res["key"] = key - res["onoff"] = "off" - end - - elseif key == "8" and value == "false" then - local cmd = "bt_daemon -s ".."1 "..string.format("%d", "0x"..id).." 0" - lue(cmd) - local flag = nil - for i = 1, 10 do - flag = is_switch_off(mac) - if flag then - break - else - posix.sleep(1) - end - end - if flag then - res["result"] = true - res["mac"] = mac - res["key"] = key - res[ "onoff"] = "off" - else - res[ "result"] = false - res["mac"] = mac - res["key"] = key - res["onoff"] = "on" - end - - elseif key == "0" then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, value) - if #value > 20 then - value = string.sub(value, 1, 20) - end - require "MZLog".log(3, debug.getinfo(1).currentline) - local name = "" - for i = 1, #value, 2 do - name = name.." "..string.format("%d", "0x"..string.sub(value, i, i+1)) - end - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, name) - local len = #value - if len > 20 then - len = 20 - end - require "MZLog".log(3, len) - dbfs.updateBluetoothDevice(id, "", "", len, mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - local cmd = "bt_daemon -s ".."13 "..string.format("%d", "0x"..id).." "..name - lue(cmd) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, cmd) - - local name = "" - for i = 1, 10 do - posix.sleep(1) - name = is_set_name_ok(mac) - if name ~= "" then - break - end - end - - if name ~= "" and name ~= nil then - res ["result"] = true - res["mac"] = mac - res["key"] = key - else - res[ "result"] = false - res["mac"] = mac - res["key"] = key - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - end - else - res["result"] = false - res["mac"] = mac - res["key"] = key - end - --[[ - fd1:write(cjson.encode(res)) - fd1:write("\n") - fd1:close() - ]] - return res -end - -function nw_set_mesh_device_attr() - local mac = luci.http.formvalue("mac") - local key = luci.http.formvalue("key") - local value = luci.http.formvalue("value") - local res = set_mesh_device_attr(mac, key, value) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - local cmd = "rm /tmp/meshDeviceFlag" - lue(cmd) - - luci.http.write_json(res) -end - -function ww_set_mesh_device_attr(mac, key, value) - local res = set_mesh_device_attr(mac, key, value) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - local cmd = "rm /tmp/meshDeviceFlag" - lue(cmd) - return cjson.encode(res) -end - ------------------------ reboot_mesh_device -------------------- -function reboot_mesh_device(mac) - local res = {} - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - for k, v in pairs(ret) do - id = v.id - end - - local cmd = "bt_daemon -s ".."4 "..string.format("%d", "0x"..id) - lue(cmd) - posix.sleep(2) - res["result"] = true -end - -function nw_reboot_mesh_device() - local mac = luci.http.formvalue("mac") - local res = reboot_mesh_device(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_reboot_mesh_device(mac) - local res = reboot_mesh_device(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ unmesh_all_device -------------------- -function unmesh_all_device() - local res = {} - local cmd = "bt_daemon -s ".."3 ".."255" - lue(cmd) - require "MZLog".log(3, debug.getinfo(1).currentline) - local wait_time = nil - for i = 1, 20 do - wait_time = is_remove_ble_from_mesh() - if wait_time ~= nil then - break - else - posix.sleep(1) - end - end - if wait_time then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - res["result"] = true - else - res["result"] = false - end - require "MZLog".log(3, debug.getinfo(1).currentline) - return res -end - -function nw_unmesh_all_device() - local res = unmesh_all_device() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_unmesh_all_device() - local res = unmesh_all_device() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ set_mesh_device_timer -------------------- -function is_set_timer_ok(mac, timer_id) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - if fd then - local ret = fd:read() - ret = cjson.decode(ret) - fd:close() - if ret["timerId"] == timer_id then - return true - else - return nil - end - else - return nil - end -end -function set_mesh_device_timer(mac, timer_id, flag, start_time, end_time) - local res = {} - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - for k ,v in pairs(ret) do - id = v.id - end - local ret = dbfs.getBleTimerId(id, timer_id) - if ret == "" then - dbfs.addBleTimer(id, timer_id, flag, start_time, end_time) - end - --[[ - local start = start - local ends = ends - if string.len(start) == 6 then - start = "00"..start - elseif string.len(start) == 5 then - start = "000"..start - elseif string.len(start) == 4 then - start = "0000"..start - end - - if string.len(ends) == 6 then - ends = "00"..ends - elseif string.len(ends) == 5 then - ends = "000"..ends - elseif string.len(ends) == 4 then - ends = "0000"..ends - end - require "MZLog".log(3, mac) - require "MZLog".log(3, timer_id) - require "MZLog".log(3, flag) - require "MZLog".log(3, start) - require "MZLog".log(3, ends) - - local TMP = "/tmp/"..mac.."1" - local fd = io.open(TMP, "r") - if fd then - local res = fd:read() - res = cjson.decode(res) - res["timerId"] = timer_id - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - - local start1 = string.sub(start, 1, 2) - local start2 = string.sub(start, 3, 4) - local start3 = string.sub(start, 5, 6) - local start4 = string.sub(start, 7, 8) - local end1 = string.sub(ends, 1, 2) - local end2 = string.sub(ends, 3, 4) - local end3 = string.sub(ends, 5, 6) - local end4 = string.sub(ends, 7, 8) - if id then - local start = string.format("%d", "0x"..start1).." ".. - string.format("%d", "0x"..start2).." ".. - string.format("%d", "0x"..start3).." ".. - string.format("%d", "0x"..start4) - local ends = string.format("%d", "0x"..end1).." ".. - string.format("%d", "0x"..end2).." ".. - string.format("%d", "0x"..end3).." ".. - string.format("%d", "0x"..end4) - - local cmd = "/root/spi_send ".."6 "..string.format("%d", "0x"..id).. - " "..string.format("%d", "0x"..flag).." ".. - string.format("%d", "0x"..timer_id).." "..start.." "..ends - require "MZLog".log(3, cmd) - lue(cmd) - - local times = tonumber(os.time()) - 1420041600 - local res = string.format("%x", times) - local time = "" - for i = 1, #res, 2 do - time = time.." "..string.format("%d", "0x"..string.sub(res, i, i+1)) - end - local cmd = "/root/spi_send ".."7 "..string.format("%d", "0x"..id).." "..time - lue(cmd) - end - - local flag = nil - for i = 1, 10 do - posix.sleep(1) - flag = is_set_timer_ok(mac, timer_id) - if flag then - break - end - end - if flag then - res["result"] = true - res["mac"] = mac - res["timerId"] = timer_id - else - res["result"] = false - res["mac"] = mac - res["timerId"] = timer_id - end - return res - ]] -end - -function nw_set_mesh_device_timer() - local mac = luci.http.formvalue("mac") - local timer_id = luci.http.formvalue("timerId") - local flag = luci.http.formvalue("flag") - local start_time = luci.http.formvalue("start") - local end_time = luci.http.formvalue("ends") - local timer = luci.http.formvalue("timer") - local res = set_mesh_device_timer(mac, timer_id, flag, start_time, end_time) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_set_mesh_device_timer(mac, timer_id, flag, start, ends) - local res = set_mesh_device_timer(mac, timer_id, flag, start, ends) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ del_mesh_device_timer -------------------- -function is_del_timer_ok(mac, timer_id) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, r) - if fd then - local ret = fd:read() - ret = cjson.decode(ret) - fd:close() - if ret["timerId"] ~= timer_id then - return true - else - return nil - end - else - return nil - end -end - -function del_mesh_device_timer(mac, timer_id) - local res = {} - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - for k ,v in pairs(ret) do - id = v.id - end - local ret = dbfs.getBleTimerId(id, timer_id) - if ret ~= "" then - dbfs.deleteBleTimer(id, timer_id) - end - - --[[ - local cmd = "/root/spi_send ".."10 "..string.format("%d", "0x"..id).. - " "..string.format("%d", "0x"..timer_id) - lue(cmd) - local flag = nil - for i = 1, 10 do - posix.sleep(1) - flag = is_del_timer_ok(mac, timer_id) - if flag then - break - end - end - if flag then - res["result"] = true - res["mac"] = mac - res["timerId"] = timer_id - else - res["result"] = false - res["mac"] = mac - res["timerId"] = timer_id - end - return res - ]] -end - -function nw_del_mesh_device_timer() - local mac = luci.http.formvalue("mac") - local timer_id = luci.http.formvalue("timerId") - local res = del_mesh_device_timer(mac, timer_id) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_del_mesh_device_timer(mac, timer_id) - local res = del_mesh_device_timer(mac, timer_id) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ set_encry_info -------------------- -function is_set_key_ok() - local TMP = "/tmp/0b0b" - local fd = io.open(TMP, "r") - require "MZLog".log(3, debug.getinfo(1).currentline) - if fd then - local file = fd:read() - fd:close() - if file == "00" then - local cmd = "rm /tmp/0b0b" - lue(cmd) - return true - elseif file == "01" then - return false - end - end -end - -function get_ble_device_key() - local ret = dbfs.fetchBluetoothDeviceKey() - if #ret > 0 then - return ret - else - return nil - end -end - -function set_mesh_network_pwd(old_key, new_key) - --local TMP = "/tmp/"..new_key - --local fd = io.open(TMP, "w") - --fd:write(new_key) - --fd:close() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, old_key) - local key = new_key - require "MZLog".log(3, new_key) - local cmd = "bt_daemon -s 21" - lue(cmd) - local ret = nil - for i = 1, 10 do - ret = get_ble_device_key() - if ret then - break - else - posix.sleep(1) - end - end - - if #ret > 0 then - for k, v in pairs(ret) do - if v.key ~= old_key then - old_key = v.key - end - end - end - - local res = {} - require "MZLog".log(3, old_key) - require "MZLog".log(3, new_key) - local old_key1 = string.sub(old_key, 1, 1) - local old_key2 = string.sub(old_key, 2, 2) - local old_key3 = string.sub(old_key, 3, 3) - local old_key4 = string.sub(old_key, 4, 4) - local new_key1 = string.sub(new_key, 1, 1) - local new_key2 = string.sub(new_key, 2, 2) - local new_key3 = string.sub(new_key, 3, 3) - local new_key4 = string.sub(new_key, 4, 4) - require "MZLog".log(3, old_key1) - require "MZLog".log(3, old_key2) - require "MZLog".log(3, old_key3) - require "MZLog".log(3, old_key4) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - - --bt_daemon -s 21 - - local old_key = old_key1.." "..old_key2.." "..old_key3.." "..old_key4 - local new_key = new_key1.." "..new_key2.." "..new_key3.." "..new_key4 - local cmd = "bt_daemon -s ".."9 "..old_key.." "..new_key - lue(cmd) - require "MZLog".log(3, cmd) - local flag = nil - for i = 1, 10 do - flag = is_set_key_ok() - if flag ~= nil then - break - else - posix.sleep(1) - end - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, ret) - if flag then - if #ret > 0 then - for k, v in pairs(ret) do - local mac = v.mac - dbfs.updateBluetoothDevice("", key, "", "", mac) - end - end - end - - if flag then - res["result"] = true - res["newKey"] = key - else - res["result"] = false - res["newKey"] = key - end - return res -end - -function nw_set_mesh_network_pwd() - local old_key = luci.http.formvalue("oldKey") - local new_key = luci.http.formvalue("newKey") - local res = set_mesh_network_pwd(old_key, new_key) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_set_mesh_network_pwd (old_key, new_key) - local res = set_mesh_network_pwd(old_key, new_key) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - -function set_lamp_brightness() - -end - -function nw_set_lamp_brightness() - local res = set_lamp_brightness() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_set_lamp_brightness() - local res = set_lamp_brightness() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - ------------------------- bluetooth -------------------- diff --git a/Me_Lua/h10/meizu/dbfs.lua b/Me_Lua/h10/meizu/dbfs.lua deleted file mode 100644 index 2629b16..0000000 --- a/Me_Lua/h10/meizu/dbfs.lua +++ /dev/null @@ -1,604 +0,0 @@ -module ("meizu.dbfs", package.seeall) - -local sqlite3 = require("lsqlite3") -local r10db = "/etc/r10db" - -function database_busy() - return true -end - -function updateDeviceNickname(mac, nickname) - local db = sqlite3.open(r10db) - local sqlStr = string.format("update maclist set devicename = '%s' where mac = '%s'", nickname, mac) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function get_dev_nick_name(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select devicename, orgname from maclist where mac like '%s'", mac) - db:busy_handler(database_busy) - local nickname = "" - for row in db:rows(sqlStr) do - if row[1] ~= "" then - nickname = row[1] - else - if row[2] ~= "" then - nickname = row[2] - end - end - end - db:close() - return nickname -end - -function initSmbBanTable() - local db = sqlite3.open(r10db) - local sqlStr = string.format("create table if not exists SmbBanTable(mac varchar(100), smb_ban varchar(100))") - db:exec(sqlStr) - return db:close() -end - -function addSmbBanList(mac, smb_ban) - local db = sqlite3.open(r10db) - local sqlStr = string.format("insert into SmbBanTable values('%s', '%s')", mac, smb_ban) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function fetchSmbBanList() - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from SmbBanTable where smb_ban = 'true'") - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["mac"] = row[1] - }) - end - end - db:close() - return result -end - -function deleteSmbBanList(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from SmbBanTable where mac = '%s' and smb_ban = 'true'", mac) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function fetchDenyDeviceInfo(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from maclist where mac = '%s'", mac) - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["mac"] = row[1], - ["orgname"] = row[2], - ["devicename"] = row[3], - ["ip"] = row[4] - }) - end - end - db:close() - return result -end - -function change_maclist_table() - local db = sqlite3.open(r10db) - local sqlStr = string.format("ALTER TABLE maclist ADD COLUMN ip varchar(100)") - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function fetchAllDeviceInfo() - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from maclist") - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["mac"] = row[1], - ["orgname"] = row[2], - ["devicename"] = row[3] - }) - end - end - db:close() - return result -end - -function updateDeviceOrgname(mac, orgname) - local db = sqlite3.open(r10db) - local sqlStr = string.format("update maclist set orgname = '%s' where mac = '%s'", orgname, mac) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function saveDeviceInfo(mac, orgname, devicename, deviceip) - local db = sqlite3.open(r10db) - local fetch = string.format("select * from maclist where mac = '%s'", mac) - db:busy_handler(database_busy) - local exist = false - for row in db:rows(fetch) do - if row then - exist = true - end - end - local sqlStr - if not exist then - sqlStr = string.format("insert into maclist values('%s','%s','%s', '%s')", mac, orgname, devicename, deviceip) - else - sqlStr = string.format("update maclist set mac = '%s', orgname = '%s', devicemame = '%s', ip = '%s' where mac = '%s'", mac, orgname, devicename, deviceip, mac) - end - db:exec(sqlStr) - return db:close() -end - -function initBatchFileTable() - local db = sqlite3.open(r10db) - local sqlStr = string.format("create table if not exists batchFilesTables(hashCode varchar(100), IMEI varchar(100))") - db:exec(sqlStr) - return db:close() -end - -function fetchAllFilesIndex(ID, path) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from FilesListTable where ID = '%s' and path = '%s'", ID, path) - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["name"] = row[3] - }) - end - end - db:close() - return result -end - -function fetchAllFilesList(ID, start, fetchEnd, path) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from FilesListTable where ID = '%s' and path = '%s' ORDER BY isfile, name limit '%s' offset '%s' ", ID, path, fetchEnd, start) - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["name"] = row[3], - ["isfile"] = row[4], - ["size"] = row[5], - ["time"] = row[6] - }) - end - end - db:close() - return result -end - - - -function addBatchFile(hashCode, IMEI) - local db = sqlite3.open(r10db) - local sqlStr = string.format("insert into batchFilesTables values('%s', '%s')", hashCode, IMEI) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function fetchAllBatchFile(IMEI) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from batchFilesTables where IMEI = '%s'",IMEI ) - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["hashCode"] = row[1] - }) - end - end - db:close() - return result -end - -function fetchBatchFileEndFlag(flag, IMEI) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from batchFilesTables where hashCode = '%s' and IMEI = '%s'", flag, IMEI) - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - result = { - ["hashCode"] = row[1] - } - end - end - db:close() - return result -end - -function deleteBatchFileEndFlag(flag, IMEI) - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from batchFilesTables where hashCode = '%s' and IMEI = '%s'", flag, IMEI) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function deleteBatchFile(IMEI) - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from batchFilesTables where IMEI = '%s'", IMEI) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function init_arp_table() - local db = sqlite3.open(r10db) - local sqlStr = string.format("create table if not exists arp(mac varchar(18), ip varchar(16))") - db:exec(sqlStr) - return db:close() -end - -function fetch_arp_mac(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from arp where mac like '%s'", mac) - db:busy_handler(database_busy) - local result = "" - for row in db:rows(sqlStr) do - if row then - result = row[1] - end - end - db:close() - return result -end - -function insert_arp_macip(mac, ip) - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from ") - sqlStr = string.format("insert into arp values('%s', '%s')", mac, ip) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function delete_arp_all_mac() - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from arp") - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function init_wireless_device_table() - local db = sqlite3.open(r10db) - local sqlStr = string.format("create table if not exists wireless_table(mac varchar(100))") - db:exec(sqlStr) - return db:close() -end - -function fetch_wireless_device_mac(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from wireless_table where mac = '%s'", mac) - db:busy_handler(database_busy) - local result = "" - for row in db:rows(sqlStr) do - if row then - result = row[1] - end - end - db:close() - return result -end - -function fetch_all_wireless_device() - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from wireless_table") - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["mac"] = row[1] - }) - end - end - db:close() - return result -end - -function insert_wireless_device_mac(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("insert into wireless_table values('%s')", mac) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function init_wire_device_table() - local db = sqlite3.open(r10db) - local sqlStr = string.format("create table if not exists wire_table(mac varchar(100), ip varchar(100))") - db:exec(sqlStr) - return db:close() -end - -function fetch_wire_device_mac(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from wire_table where mac = '%s'", mac) - db:busy_handler(database_busy) - local result = "" - for row in db:rows(sqlStr) do - if row then - result = row[1] - end - end - db:close() - return result -end - -function fetch_all_wire_device() - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from wire_table") - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["mac"] = row[1], - ["ip"] = row[2] - }) - end - end - db:close() - return result -end - -function insert_wire_device_mac(mac, ip) - local db = sqlite3.open(r10db) - local sqlStr = string.format("insert into wire_table values('%s','%s')", mac, ip) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function update_wire_device_ip(mac, ip) - local db = sqlite3.open(r10db) - local sqlStr = string.format("update wire_table set ip = '%s' where mac = '%s'", ip, mac) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function delete_wire__device(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from wire_table where mac = '%s'", mac) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function init_access_token_table() - local db = sqlite3.open(r10db) - local sqlStr = string.format("create table if not exists accessTokenTable(token varchar(100), expireTime bigint)") - db:exec(sqlStr) - return db:close() -end - -function add_access_token(token, expireTime) - local db = sqlite3.open(r10db) - local sqlStr = string.format("insert into accessTokenTable values('%s', %d)", token, expireTime) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function fetch_access_token() - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from accessTokenTable") - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["token"] = row[1], - ["expireTime"] = row[2] - }) - end - end - db:close() - return result -end - -function update_access_token(oldToken, newToken, expireTime) - local db = sqlite3.open(r10db) - local sqlStr = string.format("update accessTokenTable set token = '%s', expireTime = %d where token = '%s'", newToken, expireTime, oldToken) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function delete_access_token() - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from accessTokenTable") - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function initBluetoothTable() - local db = sqlite3.open(r10db) - local sqlStr = string.format("create table if not exists blemeshtable(id varchar(100), mac varchar(100), key varchar(100), name varchar(100), deviceType varchar(100), len varchar(100))") - db:exec(sqlStr) - return db:close() -end - -function addBluetoothDevice(id, mac, key, name, deviceType, len) - local db = sqlite3.open(r10db) - local sqlStr = string.format("insert into blemeshtable values('%s', '%s', '%s', '%s', '%s', '%s')", id, mac, key, name, deviceType, len) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function fetchAllBluetoothDevice() - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from blemeshtable") - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["mac"] = row[2], - ["deviceType"] = row[5] - }) - end - end - db:close() - return result -end - -function deleteBluetoothDevice(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from blemeshtable where mac = '%s'", mac) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function updateBluetoothDevice(id, key, name, len, mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("update blemeshtable set id = '%s', key = '%s', name = '%s', len = '%s' where mac = '%s'", id, key, name, len, mac) - db:busy_handler(database_busy) - db:exec(sqlStr) - return db:close() -end - -function fetchBluetoothDevice(mac) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from blemeshtable where mac = '%s'", mac) - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["id"] = row[1], - ["mac"] = row[2], - ["deviceType"] = row[5], - ["name"] = row[4] - }) - end - end - db:close() - return result -end - -function fetchBluetoothDeviceKey() - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from blemeshtable where key != ''") - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["mac"] = row[2], - ["key"] = row[3] - }) - end - end - db:close() - return result -end - -function getBluetoothDevice(id) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from blemeshtable where id = '%s'", id) - db:busy_handler(database_busy) - local result = "" - for row in db:rows(sqlStr) do - if row then - result = row[2] - end - end - db:close() - return result -end - -function fetchAllBleMeshDevice() - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from blemeshtable where id !=''") - db:busy_handler(database_busy) - local result = {} - for row in db:rows(sqlStr) do - if row then - table.insert(result,{ - ["mac"] = row[2], - ["deviceType"] = row[5], - ["name"] = row[4] - }) - end - end - db:close() - return result -end - -function getBleDeviceNameLength(id) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from blemeshtable where id = '%s'", id) - db:busy_handler(database_busy) - local result = "" - for row in db:rows(sqlStr) do - if row then - result = row[6] - end - end - db:close() - return result -end ---[[ -function initBleTimerTable() - local db = sqlite3.open(r10db) - local sqlStr = string.format("create table if not exists bletimertable(id varchar(100), timer_id varchar(100), flag varchar(100), start_time varchar(100), end_time varchar(100))") - db:exec(sqlStr) - return db:close() -end - -function addBleTimer(id, timer_id, flag, start_time, end_time) - local db = sqlite3.open(r10db) - local sqlStr = string.format("insert into bletimertable values('%s', '%s', '%s', '%s', '%s')", id, timer_id, flag, start_time, end_time) - db:exec(sqlStr) - return db:close() -end - -function deleteBleTimer(id, timer_id) - local db = sqlite3.open(r10db) - local sqlStr = string.format("delete from bletimertable where id = '%s' and timer_id = '%s'", id, timer_id) - db:exec(sqlStr) - return db:close() -end - -function getBleTimerId(id, timer_id) - local db = sqlite3.open(r10db) - local sqlStr = string.format("select * from bletimertable where id = '%s' and timer = '%s'", id, timer_id) - local result = "" - for row in db:rows(sqlStr) do - if row then - result = row[2] - end - end - db:close() - return result -end -]] \ No newline at end of file diff --git a/Me_Lua/h10/meizu/disk.lua b/Me_Lua/h10/meizu/disk.lua deleted file mode 100644 index 1b1cfc8..0000000 --- a/Me_Lua/h10/meizu/disk.lua +++ /dev/null @@ -1,63 +0,0 @@ -module("meizu.disk", package.seeall) - -local bfs = require "meizu.bfs" -local exec_cmd_in_sh = bfs.exec_cmd_in_sh -local lue = require("luci.util").exec - -function get_disk_space() - local lu = require("luci.util") - local cmd = "df -k | grep ' /mnt' | awk '{printf $2}'" - local disk = lue(cmd) - if disk ~= "" then - return disk - else - return "0" - end -end - -function get_available_disk() - local lu = require("luci.util") - local cmd = "df -k | grep ' /mnt' | awk '{printf $4}'" - local disk = lue(cmd) - if disk ~= "" then - return disk - else - return "0" - end -end - -function get_info_imp() - local ret = {} - ret["total"] = get_disk_space() - ret["free"] = get_available_disk() - return ret; -end - -function nw_get_disk_info() - luci.http.prepare_content("application/json") - local ret = get_info_imp() - luci.http.write_json(ret) -end - -function ww_get_disk_info() - local res = {} - res = get_info_imp() - return res -end - -function disk_formatting() - local result = {} - result["result"] = false - local cmd = [[ls /dev/sda |grep -E "/dev/sd.$" |wc -l|awk '{printf $1}']] - local res = lue(cmd) - - if res == "1" then - result["result"] = true - luci.http.write_json(result) - local cmd = "hd_part.sh /dev/sda;echo $?" - exec_cmd_in_sh(cmd) - else - result["code"] = res - luci.http.write_json(result) - end -end diff --git a/Me_Lua/h10/meizu/dlfs.lua b/Me_Lua/h10/meizu/dlfs.lua deleted file mode 100644 index ef2b32f..0000000 --- a/Me_Lua/h10/meizu/dlfs.lua +++ /dev/null @@ -1,670 +0,0 @@ -module("meizu.dlfs", package.seeall) --- download functions - -local cjson = require "cjson" -local lfs = require "lfs" -local bfs = require "meizu.bfs" -local RC = require "meizu.r10config" -local nixio = require "nixio" - -local b64dec = bfs.b64dec -local bind_router = bfs.bind_router -local cal_str_md5 = bfs.cal_str_md5 -local data_to_json = bfs.data_to_json -local exec_cmd_in_sh = bfs.exec_cmd_in_sh -local exec_reboot = bfs.exec_reboot -local get_device_SN = bfs.get_device_SN -local get_device_version = bfs.get_device_version -local get_https_data = bfs.get_https_data -local rts_get_access_token = bfs.rts_get_access_token -local set_passwd = bfs.set_passwd -local silent_upgrade = bfs.silent_upgrade -local table_merge = bfs.table_merge - -local aria2rpc = "http://127.0.0.1:6800/jsonrpc" -local httpreq = require("socket.http").request -local lue = require("luci.util").exec - -function aria2_make_req_param(method, gid) - local p = [[{"jsonrpc":"2.0", "method":"]] - p = p..method..[[", ]] - p = p..[["id":1, "params":["]] - p = p..gid..'"]}' - p = p..'{"Accept=application/json, text/javascript, */*; q=0.01"}' - p = p..'{"Accept-Encoding=gzip, deflate"}' - p = p..'{"Content-Type=application/x-www-form-urlencoded; charset=UTF-8"}' - p = p..'{"Pragma=no-cache"}' - p = p..'{"Cache-Control=no-cache"}' - - return p -end - -function aria2_make_status_param(method, params) - local p = [[{"jsonrpc":"2.0", "method":"]] - p = p..method..[[", ]] - p = p..[["id":1]] - if params == "" then - p = p..'}' - else - p = p..[[, "params":[]] - p = p..params..']}' - end - p = p..'{"Accept=application/json, text/javascript, */*; q=0.01"}' - p = p..'{"Accept-Encoding=gzip, deflate"}' - p = p..'{"Content-Type=application/x-www-form-urlencoded; charset=UTF-8"}' - p = p..'{"Pragma=no-cache"}' - p = p..'{"Cache-Control=no-cache"}' - - return p -end - -function aria2_success_res(command, gid, status) - local res = [[{"result":true, "command":"]]..command..[[", "gid":"]]..gid..[[", "message":"]]..status..[["}]] - - return res -end - -function aria2_failed_res(command, gid, status) - local res = [[{"result":flase, "command":"]]..command..[[", "gid":"]]..gid..[[", "message":"]]..status..[["}]] - - return res -end - -function aria2_download_task_pause(gid, command) - local param = aria2_make_req_param("aria2.pause", gid) - local res, code, headers, status = httpreq(aria2rpc, param) - local success_res = aria2_success_res(command, gid, status) - local failed_res = aria2_failed_res(command, gid, status) - - if code == 200 then - return success_res - else - return failed_res - end -end - -function aria2_download_task_unpause(gid, command) - local param = aria2_make_req_param("aria2.unpause", gid) - local res, code, headers, status = httpreq(aria2rpc,param) - local success_res = aria2_success_res(command, gid, status) - local failed_res = aria2_failed_res(command, gid, status) - - if code == 200 then - return success_res - else - return failed_res - end -end - -function aria2_download_task_remove(gid, command) - local param = aria2_make_req_param("aria2.removeDownloadResult", gid) - local res, code, headers, status = httpreq(aria2rpc,param) - local success_res = aria2_success_res(command, gid, status) - local failed_res = aria2_failed_res(command, gid, status) - - if code == 200 then - return success_res - else - return failed_res - end -end - -function aria2_get_active_list() - local result = {} - local param = aria2_make_status_param("aria2.tellActive", "") - local res, code, headers, status = httpreq(aria2rpc, param) - - if code == 200 then - local jsd = cjson.decode(res) - for key, value in pairs(jsd.result) do - local data = {status = "", speed = nil, total = nil, - completed = nil, gid = "", file = ""} - - data.status = value.status - data.speed = tonumber(value.downloadSpeed) - data.total = tonumber(value.totalLength) - data.completed = tonumber(value.completedLength) - data.gid = value.gid - local jsd = cjson.encode(value.files) - jsd = string.sub(jsd, 2, -2) - local fn = cjson.decode(jsd) - data.file = "" - if string.match(fn.path, ".+/([^/]*%.%w+)$") then - data.file = string.match(fn.path, ".+/([^/]*%.%w+)$") - end - table.insert(result, data) - end - end - - return result -end - -function aria2_get_pause_list() - local param = aria2_make_status_param("aria2.tellWaiting", "0, 1000") - local res, code, headers, status = httpreq(aria2rpc,param) - local result = {} - if code == 200 then - local jsd = cjson.decode(res) - - for key, value in pairs(jsd.result) do - local data = {status = "", speed = nil, total = nil, - completed = nil, gid = "", file = ""} - data.status = value.status - data.speed = tonumber(value.downloadSpeed) - data.total = tonumber(value.totalLength) - data.completed = tonumber(value.completedLength) - data.gid = value.gid - local jsd = cjson.encode(value.files) - jsd = string.sub(jsd, 2, -2) - local fn = cjson.decode(jsd) - data.file = "" - if string.match(fn.path, ".+/([^/]*%.%w+)$") then - data.file = string.match(fn.path, ".+/([^/]*%.%w+)$") - end - table.insert(result, data) - end - end - - return result; -end - -function aria2_get_history_list() - local param = aria2_make_status_param("aria2.tellStopped", "0, 1000") - local result = {} - local res, code, headers, status = httpreq(aria2rpc, param) - if code == 200 then - local jsd = cjson.decode(res) - for key, value in pairs(jsd.result) do - local data = {status = "", speed = nil, total = nil, - completed = nil, gid = "", file = ""} - data.speed = tonumber(value.downloadSpeed) - data.total = tonumber(value.totalLength) - data.completed = tonumber(value.completedLength) - local jsd = cjson.encode(value.files) - jsd = string.sub(jsd, 2, -2) - local fn = cjson.decode(jsd) - data.status = value.status - data.gid = value.gid - data.file = "" - if string.match(fn.path, ".+/([^/]*%.%w+)$") then - data.file = string.match(fn.path, ".+/([^/]*%.%w+)$") - end - table.insert(result, data) - end - end - - return result -end - -function aria2_download_task_start(url) - local param = '[{"jsonrpc":"2.0", "method":"aria2.addUri", "id":"1",'.. - '"params":[['..'"'..url..'"'.."]]}]" - local res, code, headers, status = httpreq(aria2rpc, param) - local jsd = nil - if code == 200 then - res = string.sub(res, 2, -2) - jsd = cjson.decode(res) - end - local success_res = '{"result":true, "gid":'..'"'..jsd.result..'"'.. - ', "message":'..'"'..status..'"'.."}" - local failed_res = '{"result":false, "message":'..'"'..status..'"'.."}" - - if code == 200 then - return success_res - else - return failed_res - end -end - -function thunder_clean_list_log() - if nixio.fs.access("/tmp/tdal.log") then - nixio.fs.unlink("/tmp/tdal.log") - end - if nixio.fs.access("/tmp/tdhl.log") then - nixio.fs.unlink("/tmp/tdhl.log") - end -end - -function thunder_download_task_pause(gid, command) - thunder_clean_list_log() - local success_res = '{"result":true, "command":'..'"'..command..'"'.. - ', "gid":'..'"'..gid..'"'.. - ', "message":'..'"success"'.."}" - local cmd = "/usr/bin/xunleiR.py pause "..gid - local ret = lue(cmd) - - return success_res -end - -function download_task_pause(gid, command) - if string.match(gid, "^tdid_") then - local tdid = string.sub(gid, 6) - return thunder_download_task_pause(tdid, command) - else - return aria2_download_task_pause(gid, command) - end -end - -function thunder_download_task_unpause(gid, command) - thunder_clean_list_log() - local success_res = '{"result":true, "command":'.. - '"'..command..'"'..', "gid":'.. - '"'..gid..'"'..', "message":'..'"success"'.."}" - local cmd = "/usr/bin/xunleiR.py start "..gid - local ret = lue(cmd) - - return success_res -end - -function download_task_unpause(gid, command) - if string.match(gid, "^tdid_") then - local tdid = string.sub(gid, 6) - return thunder_download_task_unpause(tdid, command) - else - return aria2_download_task_unpause(gid, command) - end -end - -function thunder_download_task_remove(gid, command) - thunder_clean_list_log() - local success_res = '{"result":true, "command":'.. - '"'..command..'"'..', "gid":'.. - '"'..gid..'"'..', "message":'..'"success"'.."}" - --local cmd = "/usr/bin/xunleiR.py remove "..gid - local cmd = "/usr/bin/xunleiR.py delete "..gid - local ret = lue(cmd) - require "MZLog".log(3, ret) - - return success_res -end - -function download_task_remove(gid, command) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, gid) - require "MZLog".log(3, debug.getinfo(1).currentline) - if string.match(gid, "^tdid_") then - local tdid = string.sub(gid, 6) - return thunder_download_task_remove(tdid, command) - else - return aria2_download_task_remove(gid, command) - end -end - -function get_pause_list() - local result = aria2_get_pause_list() - local ret_msg = "" - if nil ~= next(result) then - --result = cjson.encode(result) - local jsr = data_to_json(result) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, jsr) - require "MZLog".log(3, debug.getinfo(1).currentline) - ret_msg = '{"result":true, "message":'..jsr.."}" - else - ret_msg = '{"result":false, "message":[]}' - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, ret_msg) - require "MZLog".log(3, debug.getinfo(1).currentline) - - return ret_msg -end - -function nw_get_pause_list() - local data = get_pause_list() - luci.http.write(data) -end - -function thunder_get_bind_code() - local ret = {} - local lue = require"luci.util".exec - local cmd = [[/usr/bin/xunleiR.py sysinfo|awk -F',' '{print $5}']] - local code = lue(cmd) - ret = '{"code":'..code..'}' - - return ret -end - -function nw_thunder_get_bind_code() - local data = thunder_get_bind_code() - luci.http.write(data) -end - -function ww_thunder_get_bind_code() - return thunder_get_bind_code() -end - -function thunder_state_code(code) - local ret = "active" - if code == 0 or code == 8 or code == 13 or code == 14 or code == 37 then - ret = "active" - end - if code == 9 or code == 10 then - ret = "paused" - end - if code == 11 or code == 15 then - ret = "complete" - end - - return ret -end - -function thunder_localpath_translate(path) - if type(path) == "string" then - path = string.gsub(path, "/opt/xware/mnt/", "/router/Thunder/") - end - return path -end - -function thunder_get_active_list() - local cmd = "/usr/bin/xunleiR.py list" - local ret - require "MZLog".log(3, debug.getinfo(1).currentline) - if nixio.fs.access("/tmp/tdal.log") then - local fp = io.open("/tmp/tdal.log", "r") - local data = fp:read("*a") - ret = data - fp:close() - else - ret = lue(cmd) - local fp = io.open("/tmp/tdal.log", "wb") - fp:write(ret) - fp:close() - end - local result = {} - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - if ret then - require "MZLog".log(3, debug.getinfo(1).currentline) - local jsd = cjson.decode(ret) - local tasks = jsd.tasks - for k, v in pairs(tasks) do - local data = {} - if (_G.next(v) ~= nil) then - data.speed = v.speed - data.status = thunder_state_code(v.state) - data.total = tonumber(v.size) - data.completed = tonumber(data.total * tonumber(v.progress)/10000) - data.file = v.name - data.path = thunder_localpath_translate(v.path) - data.gid = 'tdid_'..v.id - end - table.insert(result, data) - end - end - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, data_to_json(result)) - require "MZLog".log(3, debug.getinfo(1).currentline) - return result -end - -function thunder_get_rlist() - thunder_clean_list_log() - local cmd = "/usr/bin/xunleiR.py rlist" - local ret = lue(cmd) - local jsd = cjson.decode(ret) - local tasks = jsd.tasks - local result = {} - for k, v in pairs(tasks) do - local data = {} - if (_G.next(v) ~= nil) then - data.speed = v.speed - data.status = thunder_state_code(v.state) - data.total = tonumber(v.size) - data.completed = tonumber(data.total * tonumber(v.progress)/10000) - data.file = v.name - data.gid = 'tdid_'..v.id - end - table.insert(result, data) - end - - return result -end - -function get_active_list(start, refine_cnt) - local s = 0 - local cnt - if start then - s = start - end - local result = {} - local aria2_alist = aria2_get_active_list() - local thunder_alist = thunder_get_active_list() - local aria2_plist = aria2_get_pause_list() - --local thunder_rlist = thunder_get_rlist() - if _G.next(aria2_alist) then - result = table_merge(result, aria2_alist) - end - if _G.next(thunder_alist) then - result = table_merge(result, thunder_alist) - end - if _G.next(aria2_plist) then - result = table_merge(result, aria2_plist) - end - - local ret_msg = {} - local total = require("table").getn(result) - ret_msg["total"] = total - ret_msg["result"] = false - local ret = {} - if _G.next(result) then - if refine_cnt then - cnt = refine_cnt - else - cnt = total - end - local pos = 0 - for k, v in pairs(result) do - if pos >= s and (pos - s + 1 <= cnt) then - table.insert(ret, v) - pos = pos + 1 - end - end - ret_msg["result"] = true - ret_msg["message"] = ret - else - ret_msg["message"] = "[]" - end - ret_msg["start"] = s - if ret and type(ret) == "table" and _G.next(ret) then - ret_msg["count"] = require("table").getn(ret) - else - ret_msg["count"] = 0 - end - ret_msg = data_to_json(ret_msg) - require "MZLog".log(3, ret_msg) - - return ret_msg -end - -function nw_get_active_list() - local data = get_active_list() - luci.http.write(data) -end - -function thunder_get_history_list() - local cmd = "/usr/bin/xunleiR.py clist" - local ret - if nixio.fs.access("/tmp/tdhl.log") then - local fp = io.open("/tmp/tdhl.log", "r") - local data = nixio.fs.readfile("/tmp/tdhl.log") - ret = data - else - ret = lue(cmd) - local fp = io.open("/tmp/tdhl.log", "wb") - fp:write(ret) - fp:close() - end - - local jsd = cjson.decode(ret) - local tasks = jsd.tasks - local result = {} - for k, v in pairs(tasks) do - local data = {} - if (_G.next(v) ~= nil) then - data.speed = v.speed - data.total = tonumber(v.size) - data.completed = v.size - data.status = thunder_state_code(v.state) - data.file = v.name - data.path = thunder_localpath_translate(v.path) - data.gid = 'tdid_'..v.id - end - table.insert(result, data) - end - return result -end - -function get_history_list(start, refine_cnt) - local s = 0 - local cnt - require "MZLog".log(3, debug.getinfo(1).currentline) - if start then - s = start - require "MZLog".log(3, start) - end - if refine_cnt then - require "MZLog".log(3, refine_cnt) - end - require "MZLog".log(3, debug.getinfo(1).currentline) - local result = {} - local aria2_ret = aria2_get_history_list() - local thunder_ret = thunder_get_history_list() - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, data_to_json(aria2_ret)) - require "MZLog".log(3, debug.getinfo(1).currentline) - - if nil ~= _G.next(aria2_ret) then - table_merge(result, aria2_ret) - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, data_to_json(thunder_ret)) - require "MZLog".log(3, debug.getinfo(1).currentline) - if _G.next(thunder_ret) then - table_merge(result, thunder_ret) - end - - require "MZLog".log(3, debug.getinfo(1).currentline) - local total = require("table").getn(result) - local ret_msg = {} - require "MZLog".log(3, debug.getinfo(1).currentline) - ret_msg["total"] = total - ret_msg["result"] = false - if _G.next(result) then - require "MZLog".log(3, debug.getinfo(1).currentline) - local cnt - if refine_cnt then - cnt = refine_cnt - else - cnt = total - end - local ret = {} - local pos = 0 - for k, v in pairs(result) do - if pos >= s and (pos - s + 1 <= cnt) then - table.insert(ret, v) - pos = pos + 1 - end - end - ret_msg["count"] = require("table").getn(ret) - local jsd = data_to_json(ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, jsd) - require "MZLog".log(3, debug.getinfo(1).currentline) - ret_msg["result"] = true - --ret_msg["message"] = jsd - ret_msg["message"] = ret - else - ret_msg["message"] = "[]" - end - ret_msg["start"] = s - if ret and type(ret) == "table" and _G.next(ret) then - ret_msg["count"] = require("table").getn(ret) - else - ret_msg["count"] = 0 - end - require "MZLog".log(3, debug.getinfo(1).currentline) - ret_msg = data_to_json(ret_msg) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, ret_msg) - require "MZLog".log(3, debug.getinfo(1).currentline) - - return ret_msg -end - -function nw_get_history_list() - local data = get_history_list() - luci.http.write(data) -end - -function thunder_download_task_start(url) - thunder_clean_list_log() - local ret = "" - local cmd = [[/usr/bin/xunleiR.py download ']]..url..[[']] - require "MZLog".log(3, cmd) - ret = lue(cmd) - require "MZLog".log(3, ret) - local jsr = cjson.decode(ret) - ret = {} - ret["message"] = "" - ret["result"] = false - if jsr and jsr.rtn then - require "MZLog".log(3, jsr.rtn) - ret["rtn"] = jsr.rtn - if jsr.rtn == 0 or jsr.rtn == 202 then - ret["result"] = true - end - end - - if jsr and jsr.id then - ret["gid"] = "tdid_"..jsr.id - else - ret["gid"] = "tdid_0" - end - - return data_to_json(ret) -end - -function download_task_start(url, dltype) - require "MZLog".log(3, url) - require "MZLog".log(3, dltype) - local res = "" - if dltype == "thunder" then - res = thunder_download_task_start(url) - else - res = aria2_download_task_start(url) - end - require "MZLog".log(3, res) - - return res -end - -function nw_download_task_start() - local url = luci.http.formvalue("url") - local dltype = luci.http.formvalue("type") - local res = download_task_start(url, dltype) - luci.http.write(res) - - return res -end - -function download_task_operate(gid, command) - if command == "downloadpause" then - return download_task_pause(gid, command) - elseif command == "downloadunpause" then - return download_task_unpause(gid, command) - elseif command == "downloadremove" then - return download_task_remove(gid, command) - end -end - -function nw_download_task_operate() - local command = luci.http.formvalue("command") - local gid = luci.http.formvalue("gid") - local ret = download_task_operate(gid, command) - - luci.http.write(ret) -end diff --git a/Me_Lua/h10/meizu/nwfs.lua b/Me_Lua/h10/meizu/nwfs.lua deleted file mode 100644 index 104e1ac..0000000 --- a/Me_Lua/h10/meizu/nwfs.lua +++ /dev/null @@ -1,1878 +0,0 @@ -module("meizu.nwfs", package.seeall) ---network functions - -local cjson = require "cjson" -local lfs = require "lfs" -local bfs = require "meizu.bfs" -local RC = require "meizu.r10config" - -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 b64dec = bfs.b64dec -local b64enc = bfs.b64enc - -local lue = require("luci.util").exec - -function get_connect_info() - --usr/lib/lua/luci/controller/admin/network.lua lease_status() - local rv = { } - local s = require "luci.tools.status" - - luci.http.prepare_content("application/json") - rv = s.dhcp_leases() - for k, v in pairs(rv) do - v.netswitch = "true" - v.diskswitch = "true" - v.netspeed = 0 - v.onnettime = 0 - v.netflow = 0 - end - luci.http.write_json(rv) -end - -function wifi_network(wifi_device_name) - local network = require "luci.model.network".init() - local wifi_net = network:get_wifinet(wifi_device_name) - if wifi_net then - local dev = wifi_net:get_device() - if dev then - return { - id = wifi_device_name, - name = wifi_net:shortname(), - up = wifi_net:is_up(), - mode = wifi_net:active_mode(), - ssid = wifi_net:active_ssid(), - bssid = wifi_net:active_bssid(), - encryption = wifi_net:active_encryption(), - encryption_src = wifi_net:get("encryption"), - frequency = wifi_net:frequency(), - bitrate = wifi_net:bitrate(), - ifname = wifi_net:ifname(), - assoclist = wifi_net:assoclist(), - country = wifi_net:country(), - key = wifi_net:get("key"), - key1 = wifi_net:get("key1"), - hidden = wifi_net:get("hidden"), - device = { - up = dev:is_up(), - device = dev:name(), - name = dev:get_i18n() - } - } - end - end - return {} -end - -function wifi_networks() - 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 wifi_net - for _, wifi_net in ipairs(dev:get_wifinets()) do - rd.networks[#rd.networks+1] = { - name = wifi_net:shortname(), - up = wifi_net:is_up(), - mode = wifi_net:active_mode(), - ssid = wifi_net:active_ssid(), - bssid = wifi_net:active_bssid(), - encryption = wifi_net:active_encryption(), - frequency = wifi_net:frequency(), - channel = wifi_net:channel(), - signal = wifi_net:signal(), - quality = wifi_net:signal_percent(), - noise = wifi_net:noise(), - bitrate = wifi_net:bitrate(), - ifname = wifi_net:ifname(), - assoclist = wifi_net:assoclist(), - country = wifi_net:country(), - key = wifi_net:get("key"), - key1 = wifi_net:get("key1"), - encryption_src = wifi_net:get("encryption"), - hidden = wifi_net:get("hidden"), - } - end - result[#result+1] = rd - end - return result -end - -function nw_get_wifi_settings() - luci.http.prepare_content("application/json") - local app_version = luci.http.formvalue("appVer") - if app_version == nil then - app_version = 0 - end - local list = get_wifi_settings(app_version) - luci.http.write(list) -end - -function ww_get_wifi_settings(app_version) - local list = get_wifi_settings(app_version) - --return data_to_json(list) - return list -end - -function get_wifi_settings(app_version) - local network = require "luci.model.network".init() - local info_list = {} - local wifis = wifi_networks() - for i,wifi_net in ipairs(wifis) do - local item = {} - local index = 1 - - if wifi_net.device == "wl0" then - local wifi_net_wl0 = network:get_wifinet('wl0.network1') - if wifi_net_wl0:get("disabled") == "1" then - item["status"] = "false" - else - item["status"] = "true" - end - end - - if wifi_net.device == "wl1" then - local wifi_net_wl1 = network:get_wifinet('wl1.network1') - if wifi_net_wl1:get("disabled") == "1" then - item["status"] = "false" - else - item["status"] = "true" - end - end - - local encryption = wifi_net.networks[index].encryption_src - local key = wifi_net.networks[index].key - if encryption == "wep-open" then - key = wifi_net.networks[index].key1 - if key:len()>4 and key:sub(0,2)=="s:" then - key = key:sub(3) - end - end - item["name"] = wifi_net.networks[index].ifname - item["ssid"] = wifi_net.networks[index].ssid - if key == nil then - key = "" - end - item["password"] = key - item["encryption"] = encryption - info_list[#wifis+1-i] = item - end - local guestwifi = get_guest_wifi(1) - if guestwifi then - table.insert(info_list, guestwifi) - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, info_list) - if tonumber(app_version) >= 5 then - return b64enc(cjson.encode(info_list)) - else - return cjson.encode(info_list) - end -end - -function get_wifi_ssids() - local wifis = wifi_networks() - local ssid1 = "" - local ssid2 = "" - for i, wifi_net in ipairs(wifis) do - if i == 1 then - ssid1 = wifi_net.networks[1].ssid - end - if i == 2 then - ssid2 = wifi_net.networks[1].ssid - end - end - - return ssid1, ssid2 -end - -function nw_wifi_settings() - - luci.http.prepare_content("application/json") - local data = luci.http.formvalue("data") - local app_version = luci.http.formvalue("appVer") - if app_version == nil then - app_version = 0 - end - local switch_2g = nil - local switch_5g = nil - local switch_guest = nil - local ssid_2g = nil - local ssid_5g = nil - local ssid_guest = nil - local pwd_2g = nil - local pwd_5g = nil - local pwd_guest = nil - local encry_2g = nil - local encry_5g = nil - local encry_guest = nil - - if tonumber(app_version) >= 5 then - local data = b64dec(data) - data = cjson.decode(data) - - for k, v in pairs(data) do - if v.name == "wl0" then - switch_2g = v.on - ssid_2g = v.ssid - pwd_2g = v.pwd - encry_2g = v.encryption - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - elseif v.name == "wl1" then - switch_5g = v.on - ssid_5g = v.ssid - pwd_5g = v.pwd - encry_5g = v.encryption - else - switch_guest = v.on - ssid_guest = v.ssid - pwd_guest = v.pwd - encry_guest = v.encryption - end - end - else - switch_2g = luci.http.formvalue("on1") - ssid_2g = luci.http.formvalue("ssid1") - pwd_2g = luci.http.formvalue("pwd1") - encry_2g = luci.http.formvalue("encryption1") - - switch_5g = luci.http.formvalue("on2") - ssid_5g = luci.http.formvalue("ssid2") - pwd_5g = luci.http.formvalue("pwd2") - encry_5g = luci.http.formvalue("encryption2") - - switch_guest = luci.http.formvalue("on3") - ssid_guest = luci.http.formvalue("ssid3") - pwd_guest = luci.http.formvalue("pwd3") - encry_guest = luci.http.formvalue("encryption3") - end - - local res = wifi_settings(switch_2g, ssid_2g, pwd_2g, encry_2g, switch_5g, ssid_5g, pwd_5g, encry_5g, switch_guest, ssid_guest, pwd_guest, encry_guest) - luci.http.write_json(res) -end - -function wifi_settings(switch_2g, ssid_2g, pwd_2g, encry_2g, switch_5g, ssid_5g, pwd_5g, encry_5g, switch_guest, ssid_guest, pwd_guest, encry_guest) - local result = {} - local res = {} - local details = {} - --local code = 0 - local code_2g = 0 - local code_5g = 0 - local code_guest = 0 - local code_2g = check_ssid(ssid_2g, 31) - local code_5g = check_ssid(ssid_5g, 31) - local code_guest = check_ssid(ssid_guest, 31) - local succeed_2g = false - local succeed_5g = false - local succeed_guest = false - - if switch_2g == "false" then - succeed_2g = set_wifi_basic_info(1, nil, nil, nil, switch_2g) - else - if code_2g == 1 then - succeed_2g = set_wifi_basic_info(1, ssid_2g, pwd_2g, encry_2g, switch_2g) - end - end - - if switch_5g == "false" then - succeed_5g = set_wifi_basic_info(2, nil, nil, nil, switch_5g) - else - if code_5g == 1 then - succeed_5g = set_wifi_basic_info(2, ssid_5g, pwd_5g, encry_5g, switch_5g) - end - end - - local wifirestart = true - if switch_guest == "true" then - switch_guest = 1 - if set_guest(1, ssid_guest, encry_guest, pwd_guest, 1, switch_guest) then - succeed_guest = true - --code = 0 - else - succeed_guest = false - wifirestart = false - end - elseif switch_guest == "false" then - switch_guest = 0 - if set_guest(1, nil, nil, nil, 0, switch_guest) then - succeed_guest = true - end - else - return nil - end - - if code_2g ~= 0 and code_5g ~= 0 and code_guest ~= 0 and succeed_2g ~= false - and succeed_5g ~= false and succeed_guest ~= false then - - res["result"] = true - if wifirestart then - fork_restart_wifi() - end - else - res["result"] = false - end - - return res -end - -function set_wifi_basic_info(wifi_index, ssid, password, encryption, on) - - local network = require "luci.model.network".init() - if wifi_index == 1 then - wifi_net = network:get_wifinet('wl0.network1') - wifi_dev = network:get_wifidev('wl0') - end - - if wifi_index == 2 then - wifi_net = network:get_wifinet('wl1.network1') - wifi_dev = network:get_wifidev('wl1') - end - - if wifi_net == nil then - return false - end - - if wifi_dev then - if on == "true" then - wifi_net:set("disabled", "0") - elseif on == "false" then - wifi_net:set("disabled", "1") - end - end - - if not is_str_nil(ssid) and check_ssid(ssid) then - wifi_net:set("ssid",ssid) - end - - local code = check_wifi_passwd(password,encryption) - if code == 0 then - wifi_net:set("encryption",encryption) - wifi_net:set("key",password) - if encryption == "none" then - wifi_net:set("key","") - elseif encryption == "wep-open" then - wifi_net:set("key1","s:"..password) - wifi_net:set("key",1) - end - elseif code > 1502 then - return false - end - - network:save("wireless") - network:commit("wireless") - return true -end - -function is_str_nil(str) - return (str == nil or str == "") -end - -function check_ssid(ssid) - if is_str_nil(ssid) then - return 0 - end - - return 1 - --[[ - if string.match(ssid,"^%w[%w_.-]*%w$") or string.match(ssid, "^%w$") or - string.match(ssid, "^%w[%w_.-]*$") or string.match(ssid,"^[%w_.-]*$") or - string.match(ssid, "^[%w_.-]*%w$") then - return 1 - else - return 0 - end - ]] -end - -function check_wifi_passwd(passwd,encryption) - if is_str_nil(encryption) or (encryption and encryption ~= "none" and is_str_nil(passwd)) then - return 1502 - end - if encryption == "psk" or encryption == "psk2" then - if passwd:len() < 8 then - return 1520 - end - elseif encryption == "mixed-psk" then - if passwd:len()<8 or passwd:len()>63 then - return 1521 - end - elseif encryption == "wep-open" then - if passwd:len()~=5 and passwd:len()~=13 then - return 1522 - end - end - --[[ - if passwd ~= "" then - local ret = string.match(passwd, "^%w[^&\\%%+]*%w$") or string.match(passwd, "^%w[^&\\%%+]*$") - if ret == nil or string.find(passwd,'"') then - return 1523 - end - end - ]] - return 0 -end - -function fork_restart_wifi() - local FORK_RESTART_WIFI = "sleep 1; /sbin/wifi >/dev/null 2>/dev/null; /etc/init.d/minidlna restart; /etc/init.d/samba restart; /usr/bin/gettraffic flush_wl_dev >/dev/null 2>/dev/null" - exec_cmd_in_sh(FORK_RESTART_WIFI) -end - -function fork_restart_network() - local FORK_RESTART_WORK= "/etc/init.d/network restart" - exec_cmd_in_sh(FORK_RESTART_WORK) -end - -function fork_smart_wifi_shutdown(wnet, close_time, open_time) - local close_interval = close_time - os.time() - local open_interval = open_time - os.time() - local cmd = string.format("sleep 15; /sbin/wifi down "..wnet.."; sleep 15; /sbin/wifi up "..wnet) - - --local cmd = string.format("sleep %s; /sbin/wifi down; sleep %s; /sbin/wifi up;", tostring(close_interval), tostring(open_interval)) - --local cmd = "/sbin/wifi "..switch.." "..wnet - --local cmd = string.format("sleep %s; /sbin/wifi down; sleep %s; /sbin/wifi up;", tostring(close_interval), tostring(open_interval)) - local cmd = string.format("/sbin/wifi down") - luci.http.status(200, shutdown and "Shutdown" or "Reconnected") - exec_cmd_in_sh(cmd) -end - - ---[[ ---function: 定时wifi开关 ---author: rh_Jameson ---]]-- ---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: 定时wifi开关shell形式 ---author: rh_Jameson -function smart_wifi_shutdown() - local wnet = 'WL1' - local info = {} - local switch = luci.http.formvalue("switch") - - --get para - --close_time = luci.http.formvalue("close_time") - --open_time = luci.http.formvalue("open_time") - - --test normal - close_time = os.time() + 5 - restart_time = os.time() + 10 - - --test exception - --close_time = os.time() - 5 - --restart_time = os.time() - 10 - - --para err manage - if close_time < os.time() or restart_time < close_time then - info["SUCCESS"] = false - else - info["SUCCESS"] = true - end - fork_smart_wifi_shutdown(switch, wnet, close_time, restart_time) - luci.http.write_json(info) -end - - ---[[ ---function: 定时wifi开关 ---author: rh_Jameson -function smart_wifi_shutdown() - local wnet = 'mt7628.network1' - local table = {} - - --get para - --local close_time = luci.http.formvalue("close_time") - --local open_time = luci.http.formvalue("open_time") - - --test normal - --local close_time = os.time() + 5 - --local restart_time = os.time() + 10 - - --test exception - local close_time = os.time() - 5 - local restart_time = os.time() - 10 - - --para err manage - if close_time < os.time() or restart_time < close_time then - table["err"] = true - luci.http.write_json(table) - return - end - --do close - while true do - if os.time() ~= close_time then - posix.sleep(1) - else - wifi_shutdown(wnet) - table["close"] = true - luci.http.write_json(table) - break - end - end - - --do restart - while true do - if os.time() ~= restart_time then - posix.sleep(1) - else - wifi_reconnect(wnet) - table["restart"] = true - luci.http.write_json(table) - break - end - end -end - ---]]-- - -function check_guest_wifi() - local uci = require("luci.model.uci").cursor() - local guest = uci:get_all("network", "eth0_3") - if guest then - return true - else - return false - end -end - -function set_guest(wifi_index, ssid, encryption, key, enabled, open) - local success = set_guest_wifi(wifi_index, ssid, encryption, key, enabled, open) - if not success then - return false - end - local networkrestart = true - if check_guest_wifi() then - networkrestart = false - end - if networkrestart then - local lanip = get_lan_ip() - local lan = lanip:gsub(".%d+.%d+$", "") - local cip = tonumber(lanip:match(".(%d+).%d+$")) - local nixio = require("nixio") - local bit = nixio.bit - cip = bit.bor(bit.band(1, cip + 1), bit.lshift(bit.rshift(cip, 1), 1)) - lanip = lan.."."..tostring(cip)..".1" - exec_cmd_in_sh("sleep 4; /usr/sbin/guest_ssid_network start "..lanip.." 255.255.255.0 >/dev/null 2>/dev/null") - else - fork_restart_wifi() - end - return true -end - -function set_guest_wifi(wifi_index, ssid, encryption, key, enabled, open) - local uci = require("luci.model.uci").cursor() - local wifinetid, ifname - local enabled = tonumber(enabled) == 1 and 1 or 0 - local open = tonumber(open) == 1 and 1 or 0 - if tonumber(wifi_index) == 1 then - wifinetid = "wl0iface1" - ifname = uci:get_all("wireless", "@wifi-iface[1]","ifname") - else - return false - end - guestwifi = uci:get_all("wireless", wifinetid) - if guestwifi then - guestwifi["ifname"] = ifname - if not is_str_nil(ssid) and check_ssid(ssid) then - guestwifi["ssid"] = ssid - end - if encryption and string.lower(tostring(encryption)) == "none" then - guestwifi["encryption"] = "none" - guestwifi["key"] = "" - end - if enabled == 1 then - guestwifi["disabled"] = 0 - elseif enabled == 0 then - guestwifi["disabled"] = 1 - else - end - - if open then - guestwifi["open"] = open - end - if encryption and string.lower(tostring(encryption)) ~= "none" and not is_str_nil(key) then - local check = check_wifi_passwd(key,encryption) - if check == 0 then - guestwifi["encryption"] = encryption - guestwifi["key"] = key - else - return false - end - end - else - if is_str_nil(ssid) or is_str_nil(encryption) then - return false - end - guestwifi = { - ["ifname"] = ifname, - ["network"] = "guest", - ["ssid"] = ssid, - ["mode"] = "ap", - ["encryption"] = encryption, - ["key"] = key, - ["open"] = open, - ["enabled"] = enabled - } - end - uci:section("wireless", "wifi-iface", wifinetid, guestwifi) - uci:commit("wireless") - return true -end - -function get_lan_ip() - local uci = require("luci.model.uci").cursor() - local lan = uci:get_all("network", "lan") - return lan.ipaddr -end - -function get_guest_wifi(wifiIndex) - local uci = require("luci.model.uci").cursor() - local index = tonumber(wifiIndex) - local status - local guestwifi - guestwifi = uci:get_all("wireless","wl0iface1") - if guestwifi then - if guestwifi.disabled == "1" then - status = "false" - else - status = "true" - end - - if guestwifi.key == nil then - guestwifi.key = "none" - end - - return { - ["name"] = "guest", - ["ssid"] = guestwifi.ssid, - ["encryption"] = guestwifi.encryption, - ["password"] = guestwifi.key, - ["status"] = status, - } - end - return guestwifi -end - -function macFormat(mac) - if mac then - return string.upper(string.gsub(mac, "-", ":")) - else - return "" - end -end - -function getAllWifiConnetDeviceDict() - local result = {} - for index = 1,3 do - local wifilist = getWifiConnectDeviceList(index) - for _, mac in pairs(wifilist) do - local item = {} - item['wifiIndex'] = index - result[macFormat(mac)] = item - end - end - return result -end - -function getWifiConnectDeviceList(wifiIndex) - local assoclist = {} - if tonumber(wifiIndex) == 1 then - assoclist = wifi_network('wl0.network1').assoclist or {} - elseif tonumber(wifiIndex) == 2 then - assoclist = wifi_network('wl1.network1').assoclist or {} - else - assoclist = wifi_network('wl0.network2').assoclist or {} - end - local dlist = {} - for mac, info in pairs(assoclist) do - table.insert(dlist, macFormat(mac)) - end - return dlist -end - -function getDHCPLists() - local NixioFs = require("nixio.fs") - local LuciUci = require("luci.model.uci") - local uci = LuciUci.cursor() - local result = {} - local leasefile = "/var/dhcp.leases" - uci:foreach("dhcp", "dnsmasq", - function(s) - if s.leasefile and NixioFs.access(s.leasefile) then - leasefile = s.leasefile - return false - end - end) - local dhcp = io.open(leasefile, "r") - if dhcp then - for line in dhcp:lines() do - if line then - local ts, mac, ip, name = line:match("^(%d+) (%S+) (%S+) (%S+)") - if name == "*" then - name = "" - end - if ts and mac and ip and name then - result[#result+1] = { - mac = macFormat(mac), - ip = ip, - name = name, - sp = 0 - } - end - end - end - dhcp:close() - return result - else - return false - end -end - -function getDHCPDict() - local dhcpDict = {} - local dhcpList = getDHCPLists() - for _,value in ipairs(dhcpList) do - dhcpDict[value.mac] = value - end - return dhcpDict -end - -function getDHCPIpDicts() - local dhcpDict = {} - local dhcpList = getDHCPLists() - for _,value in ipairs(dhcpList) do - dhcpDict[value.ip] = value - end - return dhcpDict -end - -function getDeviceInfoFromDB() - local dbfs = require("meizu.dbfs") - local result = {} - local deviceList = dbfs.fetchAllDeviceInfo() - if #deviceList > 0 then - for _, device in ipairs(deviceList) do - result[device.mac] = device - end - end - return result -end - -function is_device_online(ip) - local lu = require("luci.util") - --local cmd = "ping -W 2 -c 1 www.baidu.com > /dev/null ;echo -n $?" - local cmd = "ping -W 2 -c 1 " .. ip .. " > /dev/null ;echo -n $?" - local pingresult = lu.exec(cmd) - - local res = nil - if pingresult == "0" then - res = true - else - res = false - - end - - return res -end - -function get_connect_device_list() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, require"socket".gettime()*1000) - local dbfs = require("meizu.dbfs") - dbfs.change_maclist_table() - local LuciUtil = require("luci.util") - local deviceList = {} - local dhcpDeviceDict = getDHCPDict() - local wifiDeviceDict = getAllWifiConnetDeviceDict() - -- local dhcpDevIpDict = getNetConnect() - - local blacklist0 = getMacfilterList(0) - if next(blacklist0) ~= nil then - for _, mac in pairs(blacklist0) do - local flag = 0 - for key, value in pairs(dhcpDeviceDict) do - if value.mac == mac then - flag = 1 - break - end - end - if flag == 0 then - local res = dbfs.fetchDenyDeviceInfo(mac) - if #res > 0 then - for _, device in ipairs(res) do - dhcpDeviceDict[device.mac] = device - end - end - end - end - end - - 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 wire_table = {} - for k, v in pairs(ipmacs) do - local ipmac = strsplit(v, ',') - local ip = ipmac[1] - local mac = string.upper(ipmac[2]) - local flag = false - local res = dbfs.fetch_all_wireless_device() - - if #res > 0 then - for key, value in pairs(res) do - if mac == value.mac then - flag = true - break - end - end - end - if flag == false then - local res = {} - res.mac = mac - res.ip = ip - res.name = "" - table.insert(wire_table, res) - end - end - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, wire_table) - for k, v in pairs(wire_table) do - local flag = false - for key, value in pairs(dhcpDeviceDict) do - local mac = macFormat(key) - - if v.mac == mac then - local dhcpinfo = dhcpDeviceDict[mac] - v["name"] = dhcpinfo.name - dbfs.updateDeviceOrgname(mac, dhcpinfo.name) - flag = true - break - end - end - if flag == false then - dhcpDeviceDict[v.mac] = v - end - end - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - - local deviceDBDict = getDeviceInfoFromDB() - for key, item in pairs(dhcpDeviceDict) do - local item = {} - local mac = macFormat(key) - local deviceDB = deviceDBDict[mac] - local dhcpinfo = dhcpDeviceDict[mac] - if deviceDB ~= nil then - item["devicename"] = deviceDB.orgname - if deviceDB.devicename ~= '' then - item["devicename"] = deviceDB.devicename - end - else - item["devicename"] = dhcpinfo.name - dbfs.saveDeviceInfo(mac, dhcpinfo.name, "", dhcpinfo.ip) - end - - local black0 = blacklist0[mac] - if black0 ~= nil then - item["enable"] = false - else - item["enable"] = true - end - - local wifiType = wifiDeviceDict[mac] - local online = dhcpDeviceDict[mac] - if wifiType ~= nil then - if wifiType.wifiIndex == 1 or wifiType.wifiIndex == 3 then - item["type"] = "2.4G" - elseif wifiType.wifiIndex == 2 then - item["type"] = "5G" - end - elseif wifiType == nil and online ~= nil and black0 == nil then - local wireless_res = dbfs.fetch_wireless_device_mac(mac) - if wireless_res == "" and mac ~= "00:00:00:00:00:00" then - item["type"] = "wire" - else - item["type"] = "unknown" - end - else - item["type"] = "unknown" - end - - if online ~= nil and black0 == nil and item["type"] ~= "unknown" then - item["online"] = true - else - item["online"] = false - end - - item["ip"] = dhcpinfo.ip - item["mac"] = mac - -- item["netSpeed"] = tostring(dhcpinfo.ip.rx_bytes or 0) - deviceList[#deviceList+1] = item - end - --[[ - if blacklist0 ~= nil then - for _, mac in pairs(blacklist0) do - local item = {} - local mac = macFormat(mac) - local deviceDB = deviceDBDict[mac] - local dhcpdevice = dhcpDeviceDict[mac] - if dhcpdevice == nil then - if deviceDB ~= nil then - item["devicename"] = deviceDB.orgname - if deviceDB.devicename ~= '' then - item["devicename"] = deviceDB.devicename - end - end - local wifiType = wifiDeviceDict[mac] - if wifiType ~= nil then - if wifiType.wifiIndex == 1 then - item["type"] = "2.4G" - elseif wifiType.wifiIndex == 2 then - item["type"] = "5G" - end - else - item["type"] = "lan" - end - item["enable"] = false - item["online"] = false - item["ip"] = "null" - item["mac"] = mac - --item["diskaccess"] = false - -- item["netSpeed"] = tostring(dhcpinfo.ip.rx_bytes or 0) - deviceList[#deviceList+1] = item - end - end - end - if blacklist1 ~= nil then - for _,mac in pairs(blacklist1) do - local item = {} - local mac = macFormat(mac) - local deviceDB = deviceDBDict[mac] - local dhcpdevice = dhcpDeviceDict[mac] - if dhcpdevice == nil then - if deviceDB ~= nil then - item["devicename"] = deviceDB.orgname - if deviceDB.devicename ~= '' then - item["devicename"] = deviceDB.devicename - end - end - - local wifiType = wifiDeviceDict[mac] - if wifiType ~= nil then - if wifiType.wifiIndex == 1 then - item["type"] = "2.4G" - elseif wifiType.wifiIndex == 2 then - item["type"] = "5G" - end - else - item["type"] = "lan" - end - item["enable"] = false - item["online"] = false - item["ip"] = "null" - item["mac"] = mac - --item["diskaccess"] = false - -- item["netSpeed"] = tostring(dhcpinfo.ip.rx_bytes or 0) - deviceList[#deviceList+1] = item - end - end - end - ]] - --[[ - local str = 0xffdddddd - str = string.format("%u",str) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, str) - require "MZLog".log(3, debug.getinfo(1).currentline) - ]] - require "MZLog".log(3, require"socket".gettime()*1000) - return deviceList -end - -function ww_get_connect_device_list() - local result = get_connect_device_list() - return result -end - -function nw_get_connect_device_list() - luci.http.prepare_content("application/json") - local result = get_connect_device_list() - luci.http.write_json(result) -end - -function nw_set_device_name() - local mac = luci.http.formvalue("mac") - local devicename = luci.http.formvalue("devicename") - set_device_name(mac,devicename) -end - -function set_device_name(mac,devicename) - local code = 0 - local deviceList = {} - local dbfs = require("meizu.dbfs") - - if is_str_nil(mac) or is_str_nil(devicename) then - code = 1502 - else - code = save_device_name(mac,devicename) - end - return code -end - -function save_device_name(mac,name) - local code = 0 - local dbfs = require("meizu.dbfs") - local code = dbfs.updateDeviceNickname(macFormat(mac),name) - if code == 0 then - return true - else - return false - end -end - -function getMacfilterList(mode) - mode = tonumber(mode) - local maclist = {} - local dlist = {} - local uci = require("luci.model.uci").cursor() - if mode == 0 then - maclist = uci:get_list("wireless", "wl0iface0", "maclist") - else - maclist = uci:get_list("wireless", "wl1iface0", "maclist") - end - if #maclist > 0 then - for _, mac in pairs(maclist) do - dlist[macFormat(mac)] = mac - end - end - return dlist -end - -function set_disk_access(mac, enable) - - local result = {} - local code = false - local uci = require("luci.model.uci").cursor() - local dbfs = require("meizu.dbfs") - dbfs.initSmbBanTable() - if is_str_nil(mac) then - return - else - mac = macFormat(mac) - enable = tonumber(enable) - end - if enable == 0 then - local cmd = "samba_ban add "..mac - local smb_ban = "true" - exec_cmd_in_sh(cmd) - dbfs.addSmbBanList(mac, smb_ban) - code = false - else - local cmd = "samba_ban remove "..mac - exec_cmd_in_sh(cmd) - dbfs.deleteSmbBanList(mac) - code = true - end - result["result"] = code - return result -end - -function set_wan_switch(mac, mode, enable) - local result = {} - local code = false - local uci = require("luci.model.uci").cursor() - if is_str_nil(mac) then - return - else - mac = macFormat(mac) - enable = tonumber(enable) - end - uci:set("wireless", "wl0iface0", "macfilter", "deny") - local maclist = uci:get_list("wireless", "wl0iface0", "maclist") - if enable == 0 then - for _, macaddr in ipairs(maclist) do - if mac == macaddr then - code = "same black" - return code - end - end - table.insert(maclist, mac) - code = true - else - local pos = -1 - for i, macaddr in ipairs(maclist) do - if mac == macaddr then - pos = i - end - end - if pos >= 0 then - table.remove(maclist, pos) - code = true - else - code = "same white" - return code - end - end - if #maclist > 0 then - uci:set_list("wireless", "wl0iface0", "maclist", maclist) - else - uci:delete("wireless", "wl0iface0", "maclist") - end - - uci:set("wireless", "wl0iface1", "macfilter", "deny") - local maclist = uci:get_list("wireless", "wl0iface1", "maclist") - if enable == 0 then - for _, macaddr in ipairs(maclist) do - if mac == macaddr then - code = "same black" - return code - end - end - table.insert(maclist, mac) - code = true - else - local pos = -1 - for i, macaddr in ipairs(maclist) do - if mac == macaddr then - pos = i - end - end - if pos >= 0 then - table.remove(maclist, pos) - code = true - else - code = "same white" - return code - end - end - if #maclist > 0 then - uci:set_list("wireless", "wl0iface1", "maclist", maclist) - else - uci:delete("wireless", "wl0iface1", "maclist") - end - - uci:set("wireless", "wl1iface0", "macfilter", "deny") - local maclist = uci:get_list("wireless", "wl1iface0", "maclist") - if enable == 0 then - for _, macaddr in ipairs(maclist) do - if mac == macaddr then - code = "same black" - return code - end - end - table.insert(maclist, mac) - code = true - else - local pos = -1 - for i, macaddr in ipairs(maclist) do - if mac == macaddr then - pos = i - end - end - if pos >= 0 then - table.remove(maclist, pos) - code = true - else - code = "same white" - return code - end - end - if #maclist > 0 then - uci:set_list("wireless", "wl1iface0", "maclist", maclist) - else - uci:delete("wireless", "wl1iface0", "maclist") - end - uci:commit("wireless") - fork_restart_wifi() - result["result"] = code - - return result -end - -function nw_set_wan_switch() - local result = {} - local code = false - local mac = luci.http.formvalue("mac") - local mode = luci.http.formvalue("mode") - local enable = luci.http.formvalue("enable") - - code = set_wan_switch(mac,mode,enable) - result["result"] = code - luci.http.write_json(result) -end - -function nw_set_disk_access() - local result = {} - local code = false - local mac = luci.http.formvalue("mac") - local enable = luci.http.formvalue("enable") - code = set_disk_access(mac,enable) - result["enable"] = enable - luci.http.write_json(result) -end - -function getNetConnect(ip) - local sys = require "luci.sys" - local res = {} - res["bytes"] = 0 - local conn = sys.net.conntrack() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, conn) - for _, value in pairs(conn) do - if value.src == ip then - res["bytes"] = value.bytes + res["bytes"] - end - end - return res - --[[ - table.sort(conn, function(a,b) - return(a.src < b.src) - end) - local dhcpDevIpDict = getDHCPIpDicts() - for _,ip in pairs(conn) do - if dhcpDevIpDict[ip.src] ~= nil then - dhcpDevIpDict[ip.src].sp = dhcpDevIpDict[ip.src].sp + ip.bytes - - end - end - - return dhcpDevIpDict - ]] -end - -function get_net_device() - local ntm = require "luci.model.network".init() - local dev - local devices = { } - for _, dev in luci.util.vspairs(luci.sys.net.devices()) do - if dev ~= "lo" and not ntm:ignore_interface(dev) then - devices[#devices+1] = dev - end - end - local curdev = luci.dispatcher.context.requestpath - curdev = curdev[#curdev] ~= "bandwidth" and curdev[#curdev] or devices[1] - luci.http.write_json(devices) -end - -function nw_check_sys_password() - local password = luci.http.formvalue("password") - check_sys_password(password) -end - -function check_sys_password(password) - local result={} - if not is_str_nil(password) then - local check = check_sys_pwd(password) - if check then - code = true - else - code = false - end - end - result["result"] = code - luci.http.write_json(result) -end - -function get_wan_type() - local LuciNetwork = require("luci.model.network").init() - local wanNetwork = LuciNetwork:get_network("wan") - local wanDetails = {} - if wanNetwork then - local wanType = wanNetwork:proto() - - if wanType == "static" then - wanDetails["ipaddr"] = wanNetwork:get_option_value("ipaddr") - wanDetails["netmask"] = wanNetwork:get_option_value("netmask") - wanDetails["gateway"] = wanNetwork:get_option_value("gateway") - elseif wanType == "pppoe" then - wanDetails["type"] = "pppoe" - wanDetails["pppoeName"] = wanNetwork:get_option_value("username") - wanDetails["pppoePwd"] = wanNetwork:get_option_value("password") - elseif wanType == "dhcp" then - wanDetails["type"] = "dhcp" - wanDetails["pppoeName"] = "" - wanDetails["pppoePwd"] = "" - end - return wanDetails - else - return nil - end -end - -function ww_get_wan_type() - local result = get_wan_type() - return data_to_json(result) -end - -function nw_get_wan_type() - local result = get_wan_type() - luci.http.write_json(result) -end - -function nw_set_wan_type() - local wan_type = luci.http.formvalue("type") - local pppoe_name = luci.http.formvalue("pppoeName") - local pppoe_pwd = luci.http.formvalue("pppoePwd") - set_wan_type(wan_type, pppoe_name, pppoe_pwd) -end - -function set_wan_type(wan_type, pppoe_name, pppoe_pwd) - local result = {} - local code = true - local needRestartWifi = false - if not is_str_nil(wan_type) then - local succeed - if wan_type == "pppoe" and not is_str_nil(pppoe_name) and not is_str_nil(pppoe_pwd) then - succeed = setWanPPPoE(pppoe_name, pppoe_pwd) - elseif wan_type == "dhcp" then - succeed = setWanDHCP() - end - if not succeed then - code = false - else - needRestartWifi = true - end - end - result["result"] = code - luci.http.write_json(result) - if needRestartWifi then - fork_restart_network() - end - luci.http.close() -end - -function setWanPPPoE(name, password) - local LuciNetwork = require("luci.model.network").init() - local uci = require("luci.model.uci").cursor() - local iface = "wan" - local ifname = getWanEth() - local oldconf = uci:get_all("network", "wan") or {} - local wanrestart = true - if oldconf.username == name and oldconf.password == password then - wanrestart = false - end - local wanNet = LuciNetwork:del_network(iface) - local mtuvalue = 1480 - wanNet = LuciNetwork:add_network( - iface, { - proto ="pppoe", - ifname = ifname, - username = name, - password = password, - mtu = mtuvalue - }) - if wanNet then - LuciNetwork:save("network") - LuciNetwork:commit("network") - if wanrestart then - wanRestart() - end - return true - else - return false - end -end - -function setWanDHCP() - local LuciNetwork = require("luci.model.network").init() - local uci = require("luci.model.uci").cursor() - local oldconf = uci:get_all("network", "wan") or {} - local iface = "wan" - local ifname = getWanEth() - local wanrestart = true - - local wanNet = LuciNetwork:del_network(iface) - if oldconf.proto == "dhcp" then - wanrestart = false - end - local network = { - proto = "dhcp", - ifname = ifname - } - wanNet = LuciNetwork:add_network(iface, network) - if wanNet then - LuciNetwork:save("network") - LuciNetwork:commit("network") - if wanrestart then - wanRestart() - end - return true - else - return false - end -end - -function check_sys_pwd(oldPassword) - local LuciSys = require("luci.sys") - return LuciSys.user.checkpasswd("root", oldPassword) -end - -function getWanEth() - local LuciNetwork = require("luci.model.network").init() - local wanNetwork = LuciNetwork:get_network("wan") - return wanNetwork:get_option_value("ifname") -end - -function wanRestart() - local LuciUtil = require("luci.util") - LuciUtil.exec("env -i /sbin/ifup wan") -end - -function real_time_net_speed() - local res = {} - local cmd = [[luci-bwc -i eth0.2|tail -n 5|sed -e 's#.*\[\s*\(.*\)\s*\].*#\1#']] - local eth02_speed = io.popen(cmd) - local speed_table = {} - for line in eth02_speed:lines() do - table.insert(speed_table, line) - end - eth02_speed:close() - local rx = 0 - local tx = 0 - local speed, tb, rxb, txb - local n = 0 - for k, v in ipairs(speed_table) do - speed = strsplit(v, ',') - if (k == 1) then - tb = tonumber(speed[1]) - rxb = tonumber(speed[2]) - txb = tonumber(speed[4]) - else - n = n + 1 - local tmp - local td - tmp = tonumber(speed[1]) - td = tmp - tb - tb = tmp - - tmp = tonumber(speed[2]) - rx = rx + (tmp - rxb) / td - rxb = tmp - - tmp = tonumber(speed[4]) - tx = tx + (tmp - txb) / td - txb = tmp - end - end - res["rx"] = string.format("%6.2f", rx/n) - res["tx"] = string.format("%6.2f", tx/n) - - return res -end - -function set_smb_switch(smbswitch) - local result = {} - local code = false - local onoff = smbswitch - if (tonumber)(onoff) == 1 then - luci.sys.init.enable("samba") - exec_cmd_in_sh("sleep 1") - if luci.sys.init.enabled("samba") == true then - code = true - else - code = false - end - elseif (tonumber)(onoff) == 0 then - luci.sys.init.disable("samba") - exec_cmd_in_sh("sleep 1") - if luci.sys.init.enabled("samba") == true then - code = false - else - code = true - end - end - - result["result"] = code - return data_to_json(result) - -end - -function get_smb_switch() - local smbswitch = {} - local code = false - code = luci.sys.init.enabled("samba") - smbswitch["smbswitch"] = code - return data_to_json(smbswitch) -end - -function nw_set_smbswitch() - local res = {} - local smbswitch = luci.http.formvalue("smbswitch") - res = set_smb_switch(smbswitch) - luci.http.write(res) -end - -function nw_get_smbswitch() - local res = {} - res = get_smb_switch() - luci.http.write(res) -end - -function make_get_device_details_cmd(mac, patten) - local cmd = [[((wl -i wl0 sta_info ]]..mac..[[ 2>/dev/null| ]] - cmd = cmd..[[grep -E ']]..patten..[[')||]] - cmd = cmd..[[(wl -i wl1 sta_info ]]..mac..[[ 2>/dev/null| ]] - cmd = cmd..[[grep -E ']]..patten..[[')||]] - cmd = cmd..[[(wl -i wl0.1 sta_info ]]..mac..[[ 2>/dev/null| ]] - cmd = cmd..[[grep -E ']]..patten..[['))]] - cmd = cmd..[[|sed -e 's/[^0-9]//g'|awk '{printf $1}']] - return cmd -end - -function get_device_details_duration(mac) - local patten = "in network" - local cmd = make_get_device_details_cmd(mac, patten) - local ret = lue(cmd) - if ret == "" then - ret = "0" - end - - return ret -end - -function get_device_details_tx(mac) - local patten = "tx data bytes" - local cmd = make_get_device_details_cmd(mac, patten) - local ret = lue(cmd) - if ret == "" then - ret = "0" - end - - return ret -end - -function get_device_details_rx(mac) - local patten = "rx data bytes" - local cmd = make_get_device_details_cmd(mac, patten) - local ret = lue(cmd) - if ret == "" then - ret = "0" - end - - return ret -end - -function get_device_details(mac) - local dbfs = require("meizu.dbfs") - dbfs.change_maclist_table() - local item = {} - mac = string.upper(mac) - local sec = 0 - local tx = 0 - local rx = 0 - local smbBanList = {} - dbfs.initSmbBanTable() - smbBanList = dbfs.fetchSmbBanList() - local flag = 0 - if next(smbBanList) ~= nil then - for _, value in pairs(smbBanList) do - if value.mac == mac then - flag = 1 - break - end - end - end - - if flag == 0 then - item["diskaccess"] = true - else - item["diskaccess"] = false - end - - local blacklist0 = getMacfilterList(0) - local black0 = blacklist0[mac] - if black0 ~= nil then - item["enable"] = false - else - item["enable"] = true - end - - local dhcpDeviceDict = getDHCPDict() - local res = dbfs.fetch_all_wire_device() - if #res > 0 then - for k, v in pairs(res) do - v["name"] = "" - for key, value in pairs(dhcpDeviceDict) do - local mac = macFormat(key) - if v.mac == mac then - local dhcpinfo = dhcpDeviceDict[mac] - v["name"] = dhcpinfo.name - --dbfs.saveDeviceInfo(mac, dhcpinfo.name, "", dhcpinfo.ip) - dbfs.updateDeviceOrgname(mac, dhcpinfo.name) - break - end - end - dhcpDeviceDict[v.mac] = v - end - end - - local dhcpinfo = dhcpDeviceDict[mac] - local online = dhcpDeviceDict[mac] - local wifiDeviceDict = getAllWifiConnetDeviceDict() - local wifiType = wifiDeviceDict[mac] - if wifiType ~= nil then - sec = get_device_details_duration(mac) - tx = get_device_details_tx(mac) - rx = get_device_details_rx(mac) - if wifiType.wifiIndex == 1 or wifiType.wifiIndex == 3 then - item["type"] = "2.4G" - elseif wifiType.wifiIndex == 2 then - item["type"] = "5G" - end - elseif wifiType == nil and black0 == nil then - local wireless_res = dbfs.fetch_wireless_device_mac(mac) - if wireless_res == "" and mac ~= "00:00:00:00:00:00" then - item["type"] = "wire" - local ret = getNetConnect(dhcpinfo.ip) - tx = ret.bytes or 0 - else - item["type"] = "unknown" - end - else - item["type"] = "unknown" - end - - if black0 == nil and item["type"] ~= "unknown" then - item["online"] = true - else - item["online"] = false - end - if dhcpinfo then - item["ip"] = dhcpinfo.ip - else - item["ip"] = "" - end - local deviceDBDict = getDeviceInfoFromDB() - local deviceDB = deviceDBDict[mac] - item["devicename"] = "" - if deviceDB ~= nil then - item["devicename"] = deviceDB.orgname - if deviceDB.devicename ~= '' then - item["devicename"] = deviceDB.devicename - end - else - if dhcpinfo then - dbfs.saveDeviceInfo(mac, dhcpinfo.name, "", dhcpinfo.ip) - end - end - - item["mac"] = mac - item["speed"] = 0 - item["time"] = sec - item["upload"] = rx - item["download"] = tx - - return item -end - -function nw_get_device_details() - local mac = luci.http.formvalue("mac") - local res = get_device_details(mac) - luci.http.write_json(res) -end - -function get_wireless_channel() - local res = false - local uci = require("luci.model.uci").cursor() - local channel = uci.get("wireless", "wl0", "channel") - local htmode = uci.get("wireless", "wl0", "htmode") - local extch = 1 - if "auto" == channel then - channel = "0" - end - local mode = string.sub(htmode,3,4) - if "20" == mode then - extch = 0 -end - - local ret = {} - ret["channel"] = channel - ret["extch"] = extch - return ret -end -function nw_get_wireless_channel() - local ret = get_wireless_channel() - luci.http.write_json(ret) -end - -function ww_get_wireless_channel() - local ret = get_wireless_channel() - return cjson.encode(ret) -end - -function set_wireless_channel(channel, extch) - local res = false - local uci = require("luci.model.uci").cursor() - if "0" == channel then - res = uci.set("wireless", "wl0", "channel", "auto") - else - local c = tonumber(channel) - local tab = "+" - local mode = "40" - if c >= 7 and c <= 13 then - tab = "-" - end - if extch == "0" then - mode = "20" - end - local htmode = "HT"..mode..tab - res = uci.set("wireless", "wl0", "channel", channel) - res = uci.set("wireless", "wl0", "htmode", htmode) - end - uci.commit("wireless") - fork_restart_wifi() - - return res -end - -function nw_set_wireless_channel(channel, extch) - local channel = luci.http.formvalue("channel") - local extch = luci.http.formvalue("extch") - local res = set_wireless_channel(channel, extch) - local ret = {} - ret["result"] = res - luci.http.write_json(ret) -end - -function ww_set_wireless_channel(channel, extch) - local res = set_wireless_channel(channel, extch) - local ret = {} - ret["result"] = res - return ret -end - -function ww_get_device_details(mac) - local res = get_device_details(mac) - return res -end - -function get_tx_power_mode(mode) - local res = false - local uci = require("luci.model.uci").cursor() - local txpower = tonumber(uci.get("wireless", "wl0", "txpower")); - local mode = "normal" - if txpower > 15 then - mode = "enhance" - --[[ - [else - [ if txpower < 12 then - [ mode = "green" - [ end - ]] - end - - return mode -end - -function nw_get_tx_power_mode(mode) - local mode = get_tx_power_mode() - local ret = {} - ret["mode"] = mode - luci.http.write_json(ret) -end - -function ww_get_tx_power_mode(mode) - local ret = {} - local mode = get_tx_power_mode(mode) - ret["mode"] = mode - return data_to_json(ret) -end - -function set_tx_power_mode(mode) - local res = false - local uci = require("luci.model.uci").cursor() - if mode == "normal" then - res = uci.set("wireless", "wl0", "txpower", "15") - res = uci.set("wireless", "wl1", "txpower", "15") - else - if mode == "enhance" then - res = uci.set("wireless", "wl0", "txpower", "22") - res = uci.set("wireless", "wl1", "txpower", "22") - end - end - uci.commit("wireless") - - return res -end - -function nw_set_tx_power_mode(mode) - local mode = luci.http.formvalue("mode") - local res = set_tx_power_mode(mode) - local ret = {} - ret["result"] = res - luci.http.write_json(ret) -end - -function ww_set_tx_power_mode(mode) - local ret = {} - local res = set_tx_power_mode(mode) - ret["result"] = res - return ret -end - -function is_wan_connected() - local lu = require("luci.util") - local cmd = "ping -W 2 -c 1 www.baidu.com > /dev/null ;echo -n $?" - local pingresult = lu.exec(cmd) - - local res = {} - if pingresult == "0" then - res["result"] = true - else - res["result"] = false - - end - - return res -end diff --git a/Me_Lua/h10/meizu/r10config.lua b/Me_Lua/h10/meizu/r10config.lua deleted file mode 100644 index e3fdb3c..0000000 --- a/Me_Lua/h10/meizu/r10config.lua +++ /dev/null @@ -1,3 +0,0 @@ -upgradeFlagFile = "/tmp/upgradeFlagFile" -upgradeLOCK = "/bin/touch "..upgradeFlagFile -upgradeUNLOCK = "/bin/rm "..upgradeFlagFile diff --git a/Me_Lua/h10/meizu/sipfs.lua b/Me_Lua/h10/meizu/sipfs.lua deleted file mode 100644 index 21b5f44..0000000 --- a/Me_Lua/h10/meizu/sipfs.lua +++ /dev/null @@ -1,906 +0,0 @@ -module("meizu.sipfs", package.seeall) ---sip functions - -local bfs = require "meizu.bfs" -local cjson = require "cjson" -local disk = require "meizu.disk" -local dlfs = require "meizu.dlfs" -local nwfs = require "meizu.nwfs" -local RC = require "meizu.r10config" -local sipfs = require "meizu.sipfs" -local upgdfs = require "meizu.upgdfs" -local dbfs = require "meizu.dbfs" -local btfs = require "meizu.btfs" - -local b64dec = bfs.b64dec -local batchfile_checklist = bfs.batchfile_checklist -local batchfile_compare_upload = bfs.batchfile_compare_upload -local bind_router = bfs.bind_router -local data_to_json = bfs.data_to_json -local exec_cmd_in_sh = bfs.exec_cmd_in_sh -local exec_reboot = bfs.exec_reboot -local findInDir = bfs.findInDir -local get_device_SN = bfs.get_device_SN -local get_device_version = bfs.get_device_version -local get_https_data = bfs.get_https_data -local factory_reset = bfs.factory_reset -local rts_get_access_token = bfs.rts_get_access_token -local set_passwd = bfs.set_passwd -local silent_upgrade = bfs.silent_upgrade -local get_files_list = bfs.get_files_list - -local ww_get_disk_info = disk.ww_get_disk_info - -local get_smb_switch = nwfs.get_smb_switch -local real_time_net_speed = nwfs.real_time_net_speed -local set_device_name = nwfs.set_device_name -local set_disk_access = nwfs.set_disk_access -local set_smb_switch = nwfs.set_smb_switch -local set_wan_switch = nwfs.set_wan_switch -local wifi_settings = nwfs.wifi_settings -local ww_get_connect_device_list = nwfs.ww_get_connect_device_list -local ww_get_device_details = nwfs.ww_get_device_details -local ww_get_wifi_settings = nwfs.ww_get_wifi_settings -local ww_get_tx_power_mode = nwfs.ww_get_tx_power_mode -local ww_set_tx_power_mode = nwfs.ww_set_tx_power_mode -local ww_get_wireless_channel = nwfs.ww_get_wireless_channel -local ww_set_wireless_channel = nwfs.ww_set_wireless_channel - -local ww_scan_ble_switch = btfs.ww_scan_ble_switch -local ww_add_ble_mesh_device = btfs.ww_add_ble_mesh_device -local ww_get_ble_device_list = btfs.ww_get_ble_device_list -local ww_get_ble_device_status = btfs.ww_get_ble_device_status -local ww_set_mesh_device_attr = btfs.ww_set_mesh_device_attr -local ww_get_mesh_device_list = btfs.ww_get_mesh_device_list -local ww_unmesh_all_device = btfs.ww_unmesh_all_device -local ww_set_mesh_network_pwd = btfs.ww_set_mesh_network_pwd -local ww_set_lamp_brightness = btfs.ww_set_lamp_brightness - -local check_upgrade = upgdfs.check_upgrade -local do_upgrade = upgdfs.do_upgrade -local local_upgrade = upgdfs.local_upgrade - -local download_task_operate = dlfs.download_task_operate -local get_active_list = dlfs.get_active_list -local get_history_list = dlfs.get_history_list -local get_pause_list = dlfs.get_pause_list -local remove_download_result = dlfs.remove_download_result -local download_task_start = dlfs.download_task_start -local start_download_intranet = dlfs.start_download_intranet -local ww_thunder_get_bind_code = dlfs.ww_thunder_get_bind_code - -local table_merge = bfs.table_merge - -local delete_access_token = dbfs.delete_access_token - -function sip_get_parameters(commandId) - local url = "https://router.meizu.com/oauth/router/command/routerRequest?" - local https = require("ssl.https") - local access_token = rts_get_access_token() - local newurl = url.."access_token="..access_token - newurl = newurl.."&commandId="..commandId - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, url) - require "MZLog".log(3, debug.getinfo(1).currentline) - local res, code, headers, status = https.request(newurl) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, code) - require "MZLog".log(3, status) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if code == 401 then - delete_access_token() - access_token = rts_get_access_token() - local newurl = url.."access_token="..access_token - newurl = newurl.."&commandId="..commandId - res, code, headers, status = https.request(newurl) - end - - return res -end - -function sip_response_uploader(cmd, commandId, data, finishstatus) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, data) - if data == nil or data == "" then - return - end - local data = data - if (type(data) == "string") then - data = require("luci.http").urlencode(data) - end - require "MZLog".log(3, debug.getinfo(1).currentline) - local url="https://router.meizu.com/oauth/router/command/updateResponse" - local https = require("ssl.https") - local timemini = os.date("%s") - local access_token = rts_get_access_token() - local pd = init_update_resp_pd(access_token, commandId, data, finishstatus, timemini) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, url) - require "MZLog".log(3, "sip_response_uploader data len:"..string.len(pd)) - require "MZLog".log(3, pd) - local res, code, headers, status = https.request(url, pd) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, code) - require "MZLog".log(3, status) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if code == 401 then - delete_access_token() - access_token = rts_get_access_token() - pd = init_update_resp_pd(access_token, commandId, data, finishstatus, timemini) - res, code, headers, status = https.request(url, pd) - end - return res -end - -function init_update_resp_pd(access_token, commandId, data, finishstatus, timemini) - local pd = "access_token="..access_token - pd = pd.."&commandId="..commandId - pd = pd.."&commandResponse="..(data or "") - local status = 2 - if finishstatus then - status = finishstatus - end - pd = pd.."&status="..status - pd = pd.."&lastExcuteTime="..timemini - return pd -end - -function download_list_post_process(data, refine_cnt) - local new_data = {} - local jsd = cjson.decode(data) - local nd_msg = {} - if type(jsd) == "table" then - local msg = "" - for k, v in pairs(jsd) do - if k and k == "message" then - msg = v - else - new_data[k] = v - end - end - if type(msg) == "table" and _G.next(msg) ~= nil then - local cnt = 0 - for k, v in pairs(msg) do - if cnt < refine_cnt then - table.insert(nd_msg, v) - cnt = cnt + 1 - end - end - end - if _G.next(nd_msg) ~= nil then - new_data["message"] = nd_msg - else - new_data["message"] = "[]" - end - end - - return nd_msg -end - -function download_task_operate_process(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local gid = jsr.gid - ret = download_task_operate(gid, cmd) - end - end - end - sip_response_uploader(cmd, cmdid, ret) -end - -function ww_exec_reboot(cmd, cmdid) - local ret = {} - ret["result"] = true - sip_response_uploader(cmd, cmdid, data_to_json(ret)) - exec_reboot() -end - -sip_cmd_process_action = { - ["getFilesList"] = function (cmd, cmdid) - local data = sip_get_parameters(cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local jsr = cjson.decode(data) - local value = jsr.value - local path = nil - local start = nil - local count = nil - local IMEI = nil - for k, v in pairs(value) do - if k == "commandRequest" then - require "MZLog".log(3, v) - local jsr = cjson.decode(v) - path = jsr.path - start = jsr.start - count = jsr.count - IMEI = jsr.IMEI - require "MZLog".log(3, path) - require "MZLog".log(3, start) - require "MZLog".log(3, count) - require "MZLog".log(3, IMEI) - end - end - path = string.gsub(path, "router", "mnt") - require "MZLog".log(3, path) - local data = get_files_list(path, start, count, IMEI) - require "MZLog".log(3, data) - --luci.http.write(data) - sip_response_uploader(cmd, cmdid, data) - end, - ["downloadstart"] = function (cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local url_jsr = cjson.decode(v) - local url = url_jsr.url - local dltype = url_jsr.type - require "MZLog".log(3, url) - require "MZLog".log(3, dltype) - ret = download_task_start(url, dltype) - require "MZLog".log(3, ret) - end - end - end - sip_response_uploader(cmd, cmdid, ret) - end, - ["downloadpause"] = function (cmd, cmdid) - download_task_operate_process(cmd, cmdid) - end, - ["downloadunpause"] = function (cmd, cmdid) - download_task_operate_process(cmd, cmdid) - end, - ["downloadremove"] = function (cmd, cmdid) - download_task_operate_process(cmd, cmdid) - end, - ["getPauseList"] = function (cmd, cmdid) - local data = get_pause_list() - --data = download_list_post_process(data, 4) - sip_response_uploader(cmd, cmdid, data) - end, - ["getActiveList"] = function (cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = sip_get_parameters(cmdid) - require "MZLog".log(3, data) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - require "MZLog".log(3, debug.getinfo(1).currentline) - for k, v in pairs(value) do - require "MZLog".log(3, debug.getinfo(1).currentline) - if k == "commandRequest" then - local cr_jsr = cjson.decode(v) - local start = cr_jsr.start - local count = cr_jsr.count - ret = get_active_list(start, count) - end - end - end - sip_response_uploader(cmd, cmdid, ret) - end, - ["getHistoryList"] = function (cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = sip_get_parameters(cmdid) - require "MZLog".log(3, data) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - require "MZLog".log(3, debug.getinfo(1).currentline) - for k, v in pairs(value) do - require "MZLog".log(3, debug.getinfo(1).currentline) - if k == "commandRequest" then - local cr_jsr = cjson.decode(v) - local start = cr_jsr.start - local count = cr_jsr.count - ret = get_history_list(start, count) - end - end - end - sip_response_uploader(cmd, cmdid, ret) - end, - ["thundergetbindcode"] = function (cmd, cmdid) - local data = ww_thunder_get_bind_code() - sip_response_uploader(cmd, cmdid, data) - end, - ["realtimenetspeed"] = function(cmd, cmdid) - local data = data_to_json(real_time_net_speed()) - sip_response_uploader(cmd, cmdid, data, 2) - end, - ["factoryreset"] = function(cmd, cmdid) - local data = '{'..'status:"reset factory ok."'..'}' - local data = factory_reset() - sip_response_uploader(cmd, cmdid, data_to_json(data)) - end, - ["getDeviceList"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = ww_get_connect_device_list() - data = data_to_json(data) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, data) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, data) - end, - ["getwifisettings"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = sip_get_parameters(cmdid) - require "MZLog".log(3, data) - local app_version = nil - local jsr = cjson.decode(data) - local value = jsr.value - for k, v in pairs(value) do - if k == "commandRequest" then - if #v > 1 then - local value = cjson.decode(v) - app_version = value.appVer - end - end - end - - if app_version == nil then - app_version = 0 - end - require "MZLog".log(3, app_version) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = ww_get_wifi_settings(app_version) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, data) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, data) - end, - ["setwifisettings"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - require "MZLog".log(3, debug.getinfo(1).currentline) - - local value = jsr.value - local switch_2g = nil - local switch_5g = nil - local switch_guest = nil - local ssid_2g = nil - local ssid_5g = nil - local ssid_guest = nil - local pwd_2g = nil - local pwd_5g = nil - local pwd_guest = nil - local encry_2g = nil - local encry_5g = nil - local encry_guest = nil - - for k, v in pairs(value) do - if k == "commandRequest" then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, v) - - require "MZLog".log(3, debug.getinfo(1).currentline) - local value = cjson.decode(v) - require "MZLog".log(3, value) - local base64 = value.base64 - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, base64) - local app_version = value.appVer - if app_version == nil then - app_version = 0 - end - require "MZLog".log(3, app_version) - - if tonumber(app_version) >= 5 then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, base64) - v = b64dec(base64) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, v) - local jsr = cjson.decode(v) - for key, value in pairs(jsr) do - if value.name == "wl0" then - switch_2g = value.on - ssid_2g = value.ssid - pwd_2g = value.pwd - encry_2g = value.encryption - elseif value.name == "wl1" then - switch_5g = value.on - ssid_5g = value.ssid - pwd_5g = value.pwd - encry_5g = value.encryption - else - switch_guest = value.on - ssid_guest = value.ssid - pwd_guest = value.pwd - encry_guest = value.encryption - end - end - else - local value = cjson.decode(v) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, value) - switch_2g = value.on1 - ssid_2g = value.ssid1 - pwd_2g = value.pwd1 - encry_2g = value.encryption1 - switch_5g = value.on2 - ssid_5g = value.ssid2 - pwd_5g = value.pwd2 - encry_5g = value.encryption2 - switch_guest = value.on3 - ssid_guest = value.ssid3 - pwd_guest = value.pwd3 - encry_guest = value.encryption3 - end - end - end - local data = wifi_settings(switch_2g, ssid_2g, pwd_2g, encry_2g, switch_5g, ssid_5g, pwd_5g, encry_5g, switch_guest, ssid_guest, pwd_guest, encry_guest) - - require "MZLog".log(3, debug.getinfo(1).currentline) - data = cjson.encode(data) - require "MZLog".log(3, data) - sip_response_uploader(cmd, cmdid, data) - end, - ["checkRouterUpdate"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = check_upgrade() - require "MZLog".log(3, data) - sip_response_uploader(cmd, cmdid, data) - end, - ["executeRouterUpdate"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = do_upgrade() - if data ~= "" then - require "MZLog".log(3, data) - sip_response_uploader(cmd, cmdid, data) - end - end, - ["setDeviceName"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local mac = nil - local devicename = nil - - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - mac = jsr.mac - devicename = jsr.devicename - end - end - - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = set_device_name(mac, devicename) - require "MZLog".log(3, data) - sip_response_uploader(cmd, cmdid, data) - end, - ["setWanSwitch"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local mac = nil - local mode = nil - local enable = nil - local value = jsr.value - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - mac = jsr.mac - mode = jsr.mode - enable = jsr.enable - end - end - local data = set_wan_switch(mac, mode, enable) - data = data_to_json(data) - require "MZLog".log(3, data) - sip_response_uploader(cmd, cmdid, data) - end, - ["setDiskAccess"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local mac = nil - local enable = nil - local value = jsr.value - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - mac = jsr.mac - enable = jsr.enable - end - end - local data = set_disk_access(mac, enable) - require "MZLog".log(3, data) - data = data_to_json(data) - sip_response_uploader(cmd, cmdid, data) - end, - ["getSmbSwitch"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = get_smb_switch() - require "MZLog".log(3, data) - sip_response_uploader(cmd, cmdid, data) - end, - ["setSmbSwitch"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local smbswitch = nil - local value = jsr.value - - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - smbswitch = jsr.smbswitch - end - end - local data = set_smb_switch(smbswitch) - require "MZLog".log(3, data) - sip_response_uploader(cmd, cmdid, data) - end, - ["setReboot"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - ww_exec_reboot(cmd, cmdid) - end, - ["getdevicedetails"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - ret = data_to_json(ww_get_device_details(mac)) - end - end - end - sip_response_uploader(cmd, cmdid, ret) - end, - ["getDiskInfo"] = function(cmd, cmdid) - local data = ww_get_disk_info() - data = data_to_json(data) - sip_response_uploader(cmd, cmdid, data) - end, - ["getsysinfo"] = function(cmd, cmdid) - local data = require "meizu.bfs".sysinfo() - data = data_to_json(data) - sip_response_uploader(cmd, cmdid, data) - end, - ["gettxpowermode"] = function(cmd, cmdid) - local ret = ww_get_tx_power_mode() - sip_response_uploader(cmd, cmdid, ret) - end, - ["settxpowermode"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mode = jsr.mode - ret = data_to_json(ww_set_tx_power_mode(mode)) - end - end - end - sip_response_uploader(cmd, cmdid, ret) - end, - ["getWirelessChannel"] = function(cmd, cmdid) - local ret = ww_get_wireless_channel() - sip_response_uploader(cmd, cmdid, ret) - end, - ["setWirelessChannel"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local channel = jsr.channel - ret = data_to_json(ww_set_wireless_channel(channel)) - end - end - end - end, - - ["scanBleSwitch"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local status = jsr.status - ret = ww_scan_ble_switch(status) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["getBleDeviceList"] = function(cmd, cmdid) - local data = ww_get_ble_device_list() - require "MZLog".log(3, data) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, data) - end, - ["addMeshDevice"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - ret = ww_add_ble_mesh_device(mac) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["getMeshDeviceDetail"] = function(cmd, cmdid) - require "MZLog".log(3, debug.getinfo(1).currentline) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, value) - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - ret = ww_get_ble_device_status(mac) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["removeblefrommesh"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - ret = ww_remove_ble_from_mesh(mac) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["getMeshDeviceList"] = function(cmd, cmdid) - local data = ww_get_mesh_device_list() - require "MZLog".log(3, data) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, data) - end, - ["setMeshDeviceAttr"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - local key = jsr.key - local value = jsr.value - ret = ww_set_mesh_device_attr(mac, key, value) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["rebootmeshdevice"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - ret = ww_reboot_mesh_device(mac) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["unmeshalldevice"] = function(cmd, cmdid) - local data = ww_unmesh_all_device() - require "MZLog".log(3, data) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, data) - end, - ["setmeshdevicetimer"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - local timer_id = jsr.timerId - local flag = jsr.flag - local start = jsr.start - local ends = jsr.ends - ret = ww_set_mesh_device_timer(mac, timer_id, flag, start, ends) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["setMeshNetWorkPassword"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local old_key = jsr.oldkey - local new_key = jsr.newkey - ret = ww_set_mesh_network_pwd(old_key, new_key) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["setLampBrightness"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - local timer_id = jsr.timerId - local flag = jsr.flag - local start = jsr.start - local ends = jsr.ends - ret = ww_set_lamp_brightness(mac, timer_id, flag, start, ends) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, - ["delmeshdevicetimer"] = function(cmd, cmdid) - local data = sip_get_parameters(cmdid) - local jsr = cjson.decode(data) - local value = jsr.value - local ret = "" - if (jsr.code) == "200" then - for k, v in pairs(value) do - if k == "commandRequest" then - local jsr = cjson.decode(v) - local mac = jsr.mac - local timer_id = jsr.timerId - ret = ww_del_mesh_device_timer(mac, timer_id) - end - end - end - require "MZLog".log(3, ret) - require "MZLog".log(3, debug.getinfo(1).currentline) - sip_response_uploader(cmd, cmdid, ret) - end, -} - ---"{ \"size\": \"14.12MB\", \"version\": \"1.0.10\" }" -function OTA_process_action(vs_info) - require "MZLog".log(3, "get OTA new Version:") - require "MZLog".log(3, vs_info) - require "meizu.upgdfs".push_new_version_msg() -end - ---sip data format: ---{ "push_event": [ { "appid": "com.meizu.router", "data": { "business": "1", "commandId": "54", "type": "realtimenetspeed" } } ] } ---post d = '{"business":"1","commandId":"53","type":"speed"}' -function sip() - local ret; - --local data = '{"business":"1","commandId":"53","type":"speed"}' - local data = luci.http.formvalue("d") - require "MZLog".log(3, data) - if data ~= nil then - local data = b64dec(data) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, data) - require "MZLog".log(3, debug.getinfo(1).currentline) - local jsr = cjson.decode(data) - if jsr.type ~= nil then - ret = sip_cmd_process_action[jsr.type](jsr.type, jsr.commandId) - else - if jsr["com.meizu.router"] ~= nil then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, "OTA push message:") - require "MZLog".log(3, data) - require "MZLog".log(3, debug.getinfo(1).currentline) - OTA_process_action(jsr["com.meizu.router"]) - end - end - end - luci.http.write_json("sip done.") -end - -function pysip() - local ret; - local cmd = luci.http.formvalue("cmd") - local commandId = luci.http.formvalue("commandId") - if cmd ~= nil then - ret = sip_cmd_process_action[cmd](cmd, commandId) - end - luci.http.write_json("pysip: "..cmd.." "..commandId.." done.") - luci.http.close() -end - -function upload_router_log(logdata, logtype) - local https = require("ssl.https") - local url="https://router.meizu.com/oauth/router/upLog" - local access_token = rts_get_access_token() - local pd = init_upload_router_log_pd(access_token, logtype, logdata) - local res, code, headers, status = https.request(url, pd) - if code == 401 then - delete_access_token() - access_token = rts_get_access_token() - pd = init_upload_router_log_pd(access_token, logtype, logdata) - res, code, headers, status = https.request(url, pd) - end - return res, code, headers, status -end - -function init_upload_router_log_pd(access_token, logtype, logdata) - local pd = "access_token="..access_token - if logtype then - pd = pd.."&type="..logtype - else - pd = pd.."&type=".."4" - end - pd = pd.."&content="..(logdata or "") - return pd -end diff --git a/Me_Lua/h10/meizu/upgdfs.lua b/Me_Lua/h10/meizu/upgdfs.lua deleted file mode 100644 index 11559ff..0000000 --- a/Me_Lua/h10/meizu/upgdfs.lua +++ /dev/null @@ -1,256 +0,0 @@ -module("meizu.upgdfs", package.seeall) - -local cjson = require "cjson" -local bfs = require "meizu.bfs" -local sipfs = require "meizu.sipfs" - -local b64dec = bfs.b64dec -local batchfile_checklist = bfs.batchfile_checklist -local batchfile_compare_upload = bfs.batchfile_compare_upload -local bind_router = bfs.bind_router -local cal_str_md5 = bfs.cal_str_md5 -local data_to_json = bfs.data_to_json -local exec_cmd_in_sh = bfs.exec_cmd_in_sh -local exec_reboot = bfs.exec_reboot -local findInDir = bfs.findInDir -local get_device_SN = bfs.get_device_SN -local get_device_version = bfs.get_device_version -local get_https_data = bfs.get_https_data -local rts_get_access_token = bfs.rts_get_access_token -local set_passwd = bfs.set_passwd -local silent_upgrade = bfs.silent_upgrade -local table_merge = bfs.table_merge - -function upgrade_lock() - return os.execute(RC.upgrade_lock) -end - -function upgrade_unlock() - return os.execute(RC.upgrade_unlock) -end - -function push_new_version_msg() - --type:4 (有新固件更新) - --msg = "{\"size\": \"14.12MB\", \"version\": \"1.0.10\" }" - local logtype = 4 - local msg = check_upgrade() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, "OTA push_new_version_msg:"..data) - require "MZLog".log(3, debug.getinfo(1).currentline) - sipfs.upload_router_log(msg, logtype) -end - -function push_fw_upgrading_msg(url) - local logtype = 6 - local msg = {} - msg["code"] = 2005 - msg["result"] = "upgrading...." - msg = data_to_json(msg) - local res, code, headers, status = sipfs.upload_router_log(msg, logtype) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, res) - require "MZLog".log(3, code) - require "MZLog".log(3, headers) - require "MZLog".log(3, status) - require "MZLog".log(3, debug.getinfo(1).currentline) -end - -function push_upgrade_finish_msg() - --(5) type:5 (固件更新完成) - local logtype = 5 - local msg = {} - --"content": "{ \"version\": \"5.0\", \"size\": \"14088999\" }" - msg["version"] = get_device_version() - msg["size"] = 0 - msg = data_to_json(msg) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, "push_upgrade_finish_msg:"..msg) - require "MZLog".log(3, debug.getinfo(1).currentline) - local res, code, headers, status = sipfs.upload_router_log(msg, logtype) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, res) - require "MZLog".log(3, code) - require "MZLog".log(3, headers) - require "MZLog".log(3, status) - require "MZLog".log(3, debug.getinfo(1).currentline) -end - -function subscribe_auto_upgrade() - local http = require("socket.http") - local url = "http://u.meizu.com/api/v1/upgrade/subscribe" - local serviceCode = "com.meizu.router" - local pd = "serviceCode="..serviceCode - local sn = get_device_SN() - local sipToken = sn.."100032" - pd = pd.."&sipToken="..sipToken - local device = sn - pd = pd.."&device="..device - local version = get_device_version() - pd = pd.."&version="..version - local deviceModel = "R10" - pd = pd.."&deviceModel="..deviceModel - local key = "2635881a7ab0593849fe89e685fc56cd" - local toSignStr = serviceCode..sipToken..version..key - require "MZLog".log(3, url) - require "MZLog".log(3, pd) - pd = pd.."&sign="..cal_str_md5(toSignStr) - local res, code, headers, status = http.request(url, pd) - - require "MZLog".log(3, res, code, headers, status) - return res, code, headers, status -end - -function gen_check_fw_url_pd() - local serviceCode = "com.meizu.router" - local pd = "serviceCode="..serviceCode - local sn = get_device_SN() - local device = sn - pd = pd.."&device="..device - local deviceModel = "R10" - pd = pd.."&deviceModel="..deviceModel - local root = "true" - pd = pd.."&root="..root - local version = get_device_version() - pd = pd.."&version="..version - local key = "2635881a7ab0593849fe89e685fc56cd" - local toSignStr = serviceCode..device..deviceModel..root..version..key - pd = pd.."&sign="..cal_str_md5(toSignStr) - - return pd -end - -function check_upgrade() - local ret = {} - local http = require("socket.http") - local url = "http://u.meizu.com/api/v1/upgrade/check/router" - local pd = gen_check_fw_url_pd() - local res, code, headers, status = http.request(url, pd) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, pd) - require "MZLog".log(3, debug.getinfo(1).currentline) - if res == nil then - require "MZLog".log(3, "get "..url.." failed!") - ret["code"] = code; - return data_to_json(ret) - else - return res; - end -end - -function do_upgrade() - local ret = {} - local http = require("socket.http") - local url = "http://u.meizu.com/api/v1/upgrade/check/router" - local serviceCode = "com.meizu.router" - local pd = gen_check_fw_url_pd() - local res, code, headers, status = http.request(url, pd) - if res == nil then - require "MZLog".log(3, "do_upgrade get "..url.." failed!") - ret["result"] = code; - return data_to_json(ret) - end - local data = cjson.decode(res) - local value = data.value - local digest = "" - local filesize = 0 - local upgrade_url = "" - if (data.code) == 200 then - for k,v in pairs(value) do - if k == "size" then - filesize = v - end - if k == "url" then - upgrade_url = v - end - if k == "digest" then - digest = v - end - if k == "version" then - version = v - end - end - end - if upgrade_url ~= "" then - require "MZLog".log(3, upgrade_urogtype) - push_fw_upgrading_msg(upgrade_url) - local ota_img = "/tmp/ota.trx" - local cmd = "wget '"..upgrade_url.."' -O "..ota_img..[[;]] - cmd = cmd..[[nvram set upgrading=1;nvram commit;]] - cmd = cmd..[[killall dropbear uhttpd; sleep 1;]] - cmd = cmd..[[/sbin/sysupgrade -v ]]..ota_img..[[|tee -a /tmp/ota.log;]] - ret = exec_cmd_in_sh(cmd) - --to do : add UCI set upgrade flag . - end -end - -function check_mandatory_upgrade() - local ret = {} - local http = require("socket.http") - local url = "http://u.meizu.com/api/v1/upgrade/check/router" - local pd = gen_check_fw_url_pd() - local res, code, headers, status = http.request(url, pd) - local upgrade_url = "" - local flag = false - if code == 200 then - local data = cjson.decode(res) - local value = data.value - if (data.code) == 200 then - for k, v in pairs(value) do - if k == "url" then - upgrade_url = v - end - if k == "mandatoryClear" and v == true then - flag = true - end - end - if flag then - do_upgrade() - end - end - end -end - -function local_upgrade() - local fd = nil - local nixio = require "nixio" - local image = "/tmp/ota.trx" - local touchcmd = "touch "..image - exec_cmd_in_sh(touchcmd) - local function image_supported() - return ( 0 == os.execute( - ". /lib/functions.sh; " .. - "include /lib/upgrade; " .. - "platform_check_image %q >/dev/null" - % image - )) - end - luci.http.setfilehandler( - function(field, chunk, eof) - if not fd then - fd = nixio.open(image, "w") - end - fd:write(chunk) - if eof and fd then - fd:close() - fd = nil - end - end - ) - local clean = (luci.http.formvalue("clean") == "1") and "-n" or "" - if image_supported() then - local lue = require"luci.util".exec - local cmd = [[nvram set upgrading=1;nvram commit;]] - lue(cmd) - luci.http.write("updating") - exec_cmd_in_sh("killall dropbear uhttpd; sleep 1; /sbin/sysupgrade -v %s %q" %{ clean, image }) - luci.http.write("update finished!") - else - luci.http.write("image_supported check failed!") - end -end - ---push_new_version_msg("test") ---subscribe_auto_upgrade() ---local res = check_upgrade() ---print(res) ---do_upgrade() diff --git a/Me_Lua/h10/mime.lua b/Me_Lua/h10/mime.lua deleted file mode 100644 index f559150..0000000 --- a/Me_Lua/h10/mime.lua +++ /dev/null @@ -1,90 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h10/mime.so.1.0.3 b/Me_Lua/h10/mime.so.1.0.3 deleted file mode 100644 index 022ab118d8ecb6370bdabae29b332142c4388897..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84630 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 YT!<(a@WyCeNk#o@yh079Q(9*IKb!DUMF0Q* diff --git a/Me_Lua/h10/mime/core.so b/Me_Lua/h10/mime/core.so deleted file mode 100644 index 022ab118d8ecb6370bdabae29b332142c4388897..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84630 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 YT!<(a@WyCeNk#o@yh079Q(9*IKb!DUMF0Q* diff --git a/Me_Lua/h10/posix.so b/Me_Lua/h10/posix.so deleted file mode 100644 index 21d530bcd9435ad2ed4e8eff88410cd75ea65c61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34716 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

nJ-Wi9Cwp|cN00UBQ64?gqlbBPiANWB^szsC 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 Gmj4fjVCtd( diff --git a/Me_Lua/h10/socket/core.so b/Me_Lua/h10/socket/core.so deleted file mode 100644 index c1aa8a232ac97944aa4165e70d756c74e4ac4b29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 289771 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 Gmj4fjVCtd( diff --git a/Me_Lua/h10/socket/ftp.lua b/Me_Lua/h10/socket/ftp.lua deleted file mode 100644 index ea1145b..0000000 --- a/Me_Lua/h10/socket/ftp.lua +++ /dev/null @@ -1,285 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h10/socket/headers.lua b/Me_Lua/h10/socket/headers.lua deleted file mode 100644 index 1eb8223..0000000 --- a/Me_Lua/h10/socket/headers.lua +++ /dev/null @@ -1,104 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h10/socket/http.lua b/Me_Lua/h10/socket/http.lua deleted file mode 100644 index 4f8c1c8..0000000 --- a/Me_Lua/h10/socket/http.lua +++ /dev/null @@ -1,356 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h10/socket/smtp.lua b/Me_Lua/h10/socket/smtp.lua deleted file mode 100644 index b113d00..0000000 --- a/Me_Lua/h10/socket/smtp.lua +++ /dev/null @@ -1,256 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h10/socket/tp.lua b/Me_Lua/h10/socket/tp.lua deleted file mode 100644 index cbeff56..0000000 --- a/Me_Lua/h10/socket/tp.lua +++ /dev/null @@ -1,126 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h10/socket/url.lua b/Me_Lua/h10/socket/url.lua deleted file mode 100644 index 92ba7fd..0000000 --- a/Me_Lua/h10/socket/url.lua +++ /dev/null @@ -1,307 +0,0 @@ ------------------------------------------------------------------------------ --- 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 --- ::= :///;?# --- ::= @: --- ::= [:] --- :: = {/} --- 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 {/} is considered part of ------------------------------------------------------------------------------ -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 diff --git a/Me_Lua/h10/ssl.lua b/Me_Lua/h10/ssl.lua deleted file mode 100644 index 1cf2e39..0000000 --- a/Me_Lua/h10/ssl.lua +++ /dev/null @@ -1,168 +0,0 @@ ------------------------------------------------------------------------------- --- 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) - diff --git a/Me_Lua/h10/ssl.so b/Me_Lua/h10/ssl.so deleted file mode 100644 index 81e80a26598bee721290dbeb3a610871e622067c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53826 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 G=>31L$sQ5_ diff --git a/Me_Lua/h10/ssl/https.lua b/Me_Lua/h10/ssl/https.lua deleted file mode 100644 index d010669..0000000 --- a/Me_Lua/h10/ssl/https.lua +++ /dev/null @@ -1,138 +0,0 @@ ----------------------------------------------------------------------------- --- 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 diff --git a/Me_Lua/h13/MZLog.lua b/Me_Lua/h13/MZLog.lua deleted file mode 100644 index c4a1177..0000000 --- a/Me_Lua/h13/MZLog.lua +++ /dev/null @@ -1,14 +0,0 @@ -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 diff --git a/Me_Lua/h13/Posix.lua b/Me_Lua/h13/Posix.lua deleted file mode 100644 index 7536a2a..0000000 --- a/Me_Lua/h13/Posix.lua +++ /dev/null @@ -1,113 +0,0 @@ -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 diff --git a/Me_Lua/h13/cjson.so b/Me_Lua/h13/cjson.so deleted file mode 100644 index b3e433db2fde5dea2d0608dd9ed78da428656cfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37404 zcmeHw3wT`Bb?(;8$QB@yu`P@MLC)ACd2D1cHUeZL!dMSK64_R45uBoAB+WxoENceM z$k-`uCbmg@Q+*mGaT1b}Fp+I=Ze7VXc1n6lP-Li3es!4p z|NAjII+je5rnl++a_p^r)_$zL*4k^W{WyEh`Dk;?`l6yDVJ^2Q5rkS73Q>#rm0uTP zzE>n`g(c>RfVfs%&7#RS@W+I5+%tG|n8t<#TopT2D3(x>#4nNnk|>E#I}hz4;6JV+ z;lkfiWSQ_9V21e!Y~y`DNJkM}aGCrIGHeN~kL#3*rvFa9q3Am2CIz4c1xpdXut12* z5l=)^+bAZ;N6V#(-g{9Fw_+pW%Mg1JfI>{Aiv+5QKx@Y+qDjfH|mT#5MQV7DaQ>6ixFxN*dI#~-tM{$ z1=b@3b-@P2l?ba5EQDnU??bo?;R=Ln5vV_P2v7}iE5f@F?nIzI*{_uVuGa~*h?gT! zmsTJso4^e&>Xo^u>zfUr<28uigK(3EZ%2HKzF&*@y$B!B@OH$?9);MV)0%Z`qOIm; zj(8i=cg&IZ^Cr{Yc)6j4S3+>Dup?exXbE+VcFJp!_~-m}$TzST@J0ye9Ed7Ik%iEV zwTOw2IiW1NlK4{9e?zZ19_ay*Bs}z`_RK z?S_x)LK-g8`y;?pHaLs&FF=8wlKGd4oyecG<-dgXCv5OND1X8R--Yt#qS|~4A!p0~ zGU|`m;2`SX3j=INI_3K~;EXN*Eu<%Ha0qaR4W=J6mxY^SXus8#A8|o`Hu%RV6STqK zM!sc(U8wK1!P}89Y;XfWb6L1q3VP0VsuapIf$~!}I70c^;J-uugbn_75#(oszmNP5 zIIMF>r#wE3IA_cM81hGK@V@|m#s(Loe9{I#Pkc7`PUN@R;CaXo+2AL@L(m5QDPYS6 zKM2@sgO{TI4h&oyixj$XyD6Uz3CjFMz&Bxo-+}xS zHuze=IUC%rs>;7h@b?DfSHs@##XaS>0qu=+$ZU!KEbwP+@OP1w`;ZXNB4+uIBTm}# zYf*m)gJVwTA3^;NTmJt9+-ifb0UWZy2T?z0gYQDVWrH6Tkf#lP(v1Wg{1Je!gP#e+ zq^}G3&V~UP(i+txL-G>1jFI~k7lrjjBY z@9pmu;Z1Fu!_nA4th+arjt#VJZtP3+$J#o(`eG_?_MC8JPbU#{_Vs=wCi(_D!|B9e zDmD=9Om~V@dZ24C9*z&hR91H^olYcKswLbx&>b5XNDRn2$-z|5?#{kJRjjuk2+}Ge z(%ILiD$Fe1-`gkR$w;DqcNo;G!jXYkXF8UaB$JZ<*gXYO2(y()q%V;g98e9VV(EBq ztS>5?0@;;WLlSvkZ+B1nf+qWbthc{gR)7Si zTTJgwDmqA*tq{T9{&WlivbCB>rh60p5(^7-B@%tHP6@Y!C0VvA=me7=4)>*_@zt_k zI?+G4s|#4e;oekle_Y1>K%ynt9ggoxn_e4;r3zgNLi;;+K@lKRA`6FOcdNKt!|}dE zXFAmzCC+ZyU>It#CmK)n>ZXktv}ik%z!?o|wozTHLVs+J>dk@9dmt@U+a`8Y=#T75 zlFI%_XDY^fO+J#+iKsw-MUs1EtH7bVF05`9I?7K=Lh7PK@1PILLlg;68IF87r6fNM zg;SmJ7>Izy42a$FBzia<2O)#$h=}chLhgd%CL%_dpaOad1>F_vFG!enfu1rlfcDy} zXaTWDcBlGv17MLBHJuk8h@}VivYANFfQa8S(3_5l&aMRQr?;y+5(%ejQi+;Xgd)5P z!rs%AaX2n*6mCF-W9l~Cl}dq{PE-!ZagU7tsMyfh7`_qpc)|4`T zUX2hkc{5`Jsq(Ut?azg&DusWi^AwJ0m=tpj>D8E8tM+0l?-C)*t4FwG98!e zxI)L4j{Q0g=(t+PK^@oXxK79QIu7Z$Nyi&?+@j-F9k=OthmPBI+@a&Bj(c?6r{koK z(>mUx<9l_S(eVKtAJp-Xj_=p;w{)DjTgjtzK*e6nlcjugT(08^9a}o~>o}m}Y8?l4 zT&v?c9oOqPq~j(XbDhEV+H|}_$L%`q&~a49Jv#2waZ<-=9q-Zcy*ke5_<)WN>Uc=U zBRW2$k0DV5*795zW=~7-_#e}Q~7T!^NPpDE5zgD z<%qE}A+?cZo|9!BbO$nD$ev!bW?7HUL;0+|+;LmEWO&W8&5INcmIK~wiI{R*;v36| zGo#zB$Q;O)XZB^M(g*x*(coX|Z4&cELv^tTmEDi_+`?K!nh&Fs(mGoQ|uBqRQ%BaN>8BMU`E zW+a=>Z>#d%-yxcIyN9p$4uGGKw@5_%fX6cBZgJ_ek>6B!g!tFI@Ddm0-nwwjvXglw zPwamAL%WxZg0?JZ%YwEnXoHMTNErvUj4L!xtbYjgPXQlg_!{^VVtI=q%R zTI&MdQkgf6w-WLvUbi@q@yfh?g?jTKOG_L;n@m$}zLF1lzY4fS9Lbi7!&$Kus(7_q z_{#T#fg@ScAbcLcQK=6;ERY_Qw5a;uL4DFoTE2>OCq3WGU&!Yl$~L?F&ubY`zh3;C zY1`O={zYG){~sS`{}hR0Kl_ILPdT~z&JWq}Rcn0Z&?ke_m&ssc za7(-;qS5QKge#Ewcs7InV|&EyjXopu+149KXBnpd!wZTY!tFL%44q8hh;+h5VxGk1 z!zKcGxC%VD(C&1b_d%B)&%O@)pfBr>9z~udZTBqF(6r=}I9Z>uz0J4s#gc#4bwO8+ z42Y9y)L)ZEIj3Kmw!I{Dvo+n|zZW)FE*@Ey7AMCkci+K`7=r8%im#0y5NF0S;`I0) z*kqFSSl;1k6-|Du`i4AW!%&G>KU6B3VTTP!>pAWb-N#Er{CKH|9sk#SQ<)d`MmzP0 zhM|CzRrEMz=n-AVB|kyzMM~LPQno&9bSgeA*AW~4p<*L*%O%UBoDX%0%a;ii>I5?P zWnVrr+l?@?P@CY`c#36K9Zx7%+Od&YvOdnw?$V%JzL z!aI=fM|z;xJywqpL|R3$7=uF{6UCk?Nt@xPocoXS{KDh%`vPv42XgsIz6)Eh4;`l- zzER{Jqh4Gt7Wyv(-b0|L4{4W(E8wfCFN^(`iZXv1Y4;Z`96N&GM|c#W4q+1EpjbF| z9N{#=1j17Y&mw#aVG`jvgclHAM3_Q&1wnW`RVTz1W3P$DW0?JnWrS}N^i+#%UpP(%B zN`x0%LkowQ|9U>et!43wt*+@`)@egs=FjLWq#IpfS>`3RFJK+&*m>aF16yTYv7u#_ zdYM`39n|$oE>iCh>cIxHu)!>BFbf;Z!cMcW!z}DH3tKGM_J|&X?*HG)wkKfM0gRJD z*mEHBDLJO)q7D9I(N$ITuxrR=ybd;B3!AQnO}8&zv#cCtD==PIA~*iyw-$KlAEkWZ zZ;VaVUG20f<|&&pa@rVEKC?oc0u7&$vTeE|RTW|%1ud5k_$V{euY_g4209%5YUzFz zE`!@6wpE?azfbn-kMb6_lU#oAlLaqX@IrpG;75+jAuW>w-&Ha>2$^sk;Cw3zp3{&+ z5;Ew640^!3?0@hKKNUck?0k&Hr0t7vAJ9G7&xDyLa1j?{Sx={9P8Fcfej~5yavU>d zIA*Z!QTTt(XC|dSDp}ALn73NDSy8-XnDtzuvHEt5*}Sj794CX3VG97}5AuT!K9Ys}vXEaEGR6E+ zjWv59dpkZg4!R|eAJSuOMdlOPHqgR6pZ4Pu=~v-z8>=acC-WU%$YJbRl<@^ZGvw@~ z*YL@C1=tj6)&Wm;8Tdv*g1VajsH;AoZ>ViS-&h#)I7jkX9j*}QI0W65^2At88kUOC zJmRs6SC5^}exrr~>A$5_o zeNxw-EuZ*DbbgBsx6!#c@+fE8IOibbm%R1Fj>@+0&~0<>Q1|@LW=k%IErno9>?uk2f^s}G`wp8vz+1YHV{vx*Y4z0U^pHg?}OE^!W?%Mm<$mwV4<03I%%C1y| zt|sjP^ubHI59aFQZ)!Qu)`zVB?Lz(8`^nU2KaD*1->;wQe+l}j{y*4HtpBt0(`$e6 zAL}PPlmCU<(``S6Jq3Tk{X{>^dGuVqn6?CeUG)yEkLfQwq!Bh1gsi`(ZDKZ?Vg7dt zHZ!|lJ)>=IF5mYJoll#p|8vz>FX(v$=TO|A@M9jqy$b2mFn^%Wuttyj@c|%hp~lp{EZ%)Ii8a?GX~7n?reUN_&5%;KF2cpW`oDH z_XP6U=4^dxug^a1`Lq8%eOi5yK0WdOpifU=Zf0a${a?_hZ1bn-(?frHVV`o}N7?Bq z*zDZ4+VKmv)w>+FT3ft&nEFb+r7l|9UTbah{gprEe4q7Az4>CBw24aEda=K1=Kh$! zO4-<{EO?)>Cv-9Uu6!H&<~*G=dCY-5Xp+j`RtnVJ`i6P}il+r~gFh2iM52!G~Z>!CLqX*21U9gIEt%V?7vvj`*Q7 zzWZ}HC-?ZcFEAy1BNM`xn^HU+%ZTdY_%O#K?mb;ECa_1{Axgog&kAWiJLDQ-v+m>i z88Wcs+;_e9%_X9F80*eq^0n04j5Bx*fe-3DA)1DR#a+YaK&x7-+{b+{CFeTJg?&U> zk88pb(J-dg!)LG_K8^M8BUlfg!oKy%Echv`i|OAtiznnbN}7#4eE~%?_Q~ZqG8@g$ zX+Q3yxfnEK%#(U}5VU%P-Yc*|l2?`wU=1t4XEGWY@_|pcXgr1!kB@?G$pd8I|1`uHI5`T~|~MA9!@=sTq!dW}h1Fh+aG zgIxzMamce|7MhGa&&8rrp66l_>=ia0!`|W$^ybm|kgvxkU&z&ekCw09M?hz#JRj0L z+UdB|LB}Pt(s4lc>+7+POFCYU@%hqvw7nm6tVjPI7@4M}DQEf{Jo>k5dQ6{C4(t=q z5SVAvC%3I#mZctT5pL{-G>cB`$wH5EMWQJOzf{1_XI!^x{IvZ&f2eH#QP@893I1!m zUi=>H{xt0V5!n5y@g~@NNPH7M;cM^-XW$1;j$8Bvxg5^mlaDPVii4eJ7wNC>&Ap`7Hd)r~3A>InEWx3}-e`xl>{F>L=;(g!^XGV*ZEh)X9 zS(bI3dQV@>^ttr@K>Srdc*}yfEO^GA+1KDB&cH{UhL3mzKH?O7#K|mpm40F)=6=pT zxtNW!eU>*mc`+O3yqz}AIUMk&Z_=obPE*#nf2AnGwT|w#;d^^&br5^nQ zo~JQS*-$fRX@U)m0&W_k4cPI%p3jsKrz%Uj8$oyDn9sWpbi4h(F6Gjg3qa?J#G6$s zymyK>AbaYO(ZhGTlpaoxtsSnixb~01DM>r&IXieZ=wQSGz2Pu_&OQ@wnCwI0u@HmEfbd^Yj_n)b~(8+{yKByVWCp~LTL30?;YZ4?K}KBpJ`9% zvrEy17oXVV|A_NPzgaf}q#Y%=w0-)dxP-Oz3rEYgP=<-3QN!Q;~_^Bj}lZ{KdryN*8itQzY$<~heY z_L~})URrj&^^|*|9P1|BzH&FlH8a*lgBgsyKFg1^`y69k6XrzgVe9w7E}o+Pj{Qi= zW53p`3&%E&g|q3o({~tot%banNSvd&x%BFbTCZlqi*ZQ$Q>Xo?`N3$8;|z7BefbBJ zZDWpd*ZBpWw=h33_$VjNefb>GKKJEZMD`u#=`2fIqh50#&)_Hh@P%3)-1}?r|D(3E zA@o1X69=DJv7PyEg`_`TV6!z};IJAa(T=jU#^EP_qI|QVk$6ZWbr1W+v-12Kpd~8n zjpk+>UtZTZDd*YRjA%K})eq0xXtvuwX}s-i>bmF1XWfs?k*8$QJbZADeAcx;fARjW z>2(I@`ue;O)*2_Vt~jCB7^l>p@xcrPjD1qt5Nxg5K98|@PC}1KaxAjs^LG1ww>hJP z^C(g$-UU23Pq9oCFRUuTIg|ip3_Ly@=z#wcJ65h)_89cej3t;?4)ZJn&hf~-DV8NJ z(p0Sb*V%_^9dQclh?Agu`Wyn+3_&@63F&n@2mQygFKM|=&mk?D&u5Ix=bkO~ifgpz zzOH0<0&BDYWaSYfL$z3&1+g}(hWt=|yaj8tjaZ{KVeJ;eI;|e-v^uQe@GG@Xmx|8} zWiZ=RbLNI2-$)LaM~`0yz2~{6%S3b8WmqrLAA3Y_jCI(yy$<0w^G%?s0r`F@*QJ=J z!%vQtqV9)9lb7d!iV0+N{(2EH|S(&+ecX_FWI1y9)ZY5^)Z5AIwdKDFMQ z0(~#&_T8GkOJw`g`7b*1uSR{g_bt>dmhECa1%BwG%EeKhkIj~1twR6o5le>4c{UN( zgPI=hRbZtyhPBwfJ)p}HO|`G*_d|XSQhtAjIWx;Eo*G~W`(*w5;|>1Lqb~6p-Z6fa zk!SMGI;+7WWAcBSzIXD!;BEN#y*>X@-WTJaG*SlO6a1_7!;tpBnpLAK``ddwRG42gtpmVH3r@M4Jllf+x zeLXDC(azUfbEPBrk+?dm%l%(*t}%E-^ps_A5?gp0gGtTbJmHpY^of+j zJ72>+Vo<^*8lKF@(biL-;Q(mJXd2?6;Yp+`Uhk5;;+#yOP7HZRWSx1aW63kkQKTIJ z%?GNt!n1xgAA?OQ8Yc71`-J3k9{6;YZ^<9SK&J zcM0fNJ>^%5IX}kR`W5AkA_YG8`*0%jMwiIs-TvFb&+X8UDa@lQfxFV$FDg;)YH|25 z{MF&B#F4}Fed?^{EyI2}j=wToBECQD3t+Bm?E~G1<(Tgm$Hq&)n^fke^+n^%fni#-EJKWw&LIXdOEXTaM~E9&H%*G1dWCjcd9d_?ua;ag09T{kq=8 z@E=3D7G2Kx0L*WP;3u$862v|dbWVgY=TvQ(Jb`f%=Yhv=lXV-%7DATuAY1sb!#ub7 zd(yAa-_Fh3Q)qjoZkxV{e9;$)lEy$l_ss=lLsxKNOXi`?g?P_ ztNO#+h;@@1S4xpinS%c@p=sWQ@`{EEOq0}{Mu;bd?#H|aYcHNVqC ze-`+&z@G(v%u`Nbo^lfN6g3~|!F&Y20~o@yrlI=c2>f@0e+6`?1il1m$DL~lK11PH zNW0`bu|#;}Jd!Z;JYqifgzv-H%Q@w|;ny+VbB%K3`v3$MG!(3IZLxKti zo)yZoq(00K&aX{X`JU}?rMcF|c{~f_BIn3#YmuHC1Tu%R+~=vtd=ByF5x$(AY&=x8 zvHMJwH~oASwAOpD`^_q!7cUpUexDyWNEdlk&)7I$&dIq*y89XI5vx5h&XWV;DCTev zWz~8NcxkY?%(@%{+&3$@4l_O$r0-)h>c)$MVwoAUHM zn{h?)n-$1TKO3`L?VuM7N?CG0&D5cZmb)0ufABUm%e5|P(lQ+B zUSDW?o^G4GQx3E#jDymDU#!hT`NlH&d__E*{S0i2eEqa~YR-rLSLo>;Tq+mPp_8*#elKwGEH8++fV{n4Y{&-foP^ucEl2hN}Q$B^cg zzl(S{yIAuUfG&pgeF^yBvnZD5I=1w8l+Vw=-*Zh5+Ti0)jo%AjzX!fP4PT#xukVAe z?}4w6!q>NBJlKKpK>C&u_4_39gz*Bh56!yvXFl6h&lE#aC(K#%MMY{)p$zS_KF>?E z;+YrmH=&(Y`TMTN@VlY?)pa-ry%A^sFM*%0$34cf4Ds&7Sj!ml$}sNMbM6Y@Bure4 z>oIIE_4j)L^LZB60mR8Yk2-O38J=Y>Bj0@fKH0ctS%tKNY5&M_ z#C?A4nq^b}u6!rwW0z|GeGTlC`P8`(=rFw6{rCU4h`w=LG5R)hdnLc#3 z16|2NSMYm}-^)T*aMu1z7P^v!u3$Vrh4K6(#`Ed@mkh>kw#T-}H|d>#UK2n2`qNrJ z$HZZ;@Z3_xJ%@HNiZ$b?Tr+<_u4!lAb0Ch-q3?b00c?YN681d@=1(~C?RyT)_dp-j zo`ahA)uOzbo6g*GSZ4Md4yru|A7souhh>sJOSbRab0B`T=P;db-*aGoIqI{$Z-I91 zIgpnY>@`qM=u_+?9l@OFC~Xzv{OEXH(S6=(=-^JstzH}*FA_@%dkz0++iUodZLfiN z?0XIEs7qY*73z5_-Y2BbdtD29?E4P4fKTo@G$N+n`85B_HUDbQVVXbto(pM)e9%AB z`A+^VE$_McKMMZ&n@`361LBC}|9Z*)5%4urx6E$@Ue*56E+6||#LGAXLw+cGyL>oj zF4OYinw@JH<`?0fGP_*1dxG#jp2fxQpRrG&Y<%V(#A5tzPIy~j^C6-3iRRjWpr0Zw z1`oXTKEi`~|DhK$B7EWg!}ncSUuBqAD&8;44C}IH|AD^8>_138;ZI+LY?Mz@`%jaL zKIHd3JK_GfvkN>f;i;mmkKq}!56^_TeitveYCA<&Sw@Vm5T4Q1UxALWO~^;m`6Z$D zMPNq~{(^Xa8S(u9_%QdD_znS|INyZzuDkYAVn5cqhgZurFMiisd8`qM5?PF#oT_UPC3yK|c;}#@c8L)>vx2 z>-C4=m(+Uq2-dr!SnpcW_i)Wim^}Ktt#XV2Jm$+>=lY87Thr&C)^fr)r2KtgbcVk8 zVSm(@gD6McD3sIdVxw1n^a0nczp2ZGfRFuS)~4(Wvu+qRVma;~iCVAC9kl*8zWDSb=#D z_wHYUo>Jm~(J$&ZH|9MBFMLJS`;Y#9@oBW-%VaPa<9t`h@#00$Qg^jEw*qHT$ou8} z{UYT=c~0b%T=?4q%xT8&#k&oBbQJnWurH|e(7k0=Lx>NoUPid;Em%;#@74I#z>T@?l$-jH zcYFMQ4;{_Bi?L2RkTr8PZ`+z>zmIk9YrO{~eMcUgmJMkjjg%2(LHgKsh31iM`>c=% zq8!&oimp-0D2wvYM?Ob50UV9TNe9nIJKO$kTiXHMHqW5od1$p;`)bxL755!Cb*1b; zH)*3Cd=fa$Y5HIJ@-+SBVjtHq1^PK(ArI_h{K30AGIHDr+4_m;^sk5@U$tK0b2}gO zo;;Bs!wX^7RcV&w?_N9?DHET-8jStXB-cmS#~z+QIj=Z8UIzUs|8T)>OlPkTIT|IKe5`s?T6=est3+Pjh!eaM+M`5mmSHh%cP z1-ANUNH?~6?zg9Py#%_BIpR=&YH*f)ax4et{u%kxF*85Q}({TTe$K4gghgENqUN{nUGwTTy-(M)BCVQ}-$3GU#vOcGsVCdJw zV9(e&o1=C2>ORSB)_Qo zf#a<6w-1~@k&k+<_w+v-(M}6#&E@zU81N~)m*xt{nYO!Nn0zfgxWpx-U!@*m&l-IB zf*Car#JRN<2j3@YTp+B)FK$ZnzwIOLN=AT9H|3iO;U67da^#j$_2hzAX|5upjtXb{%c>U`TMDO}SE6 zRo{oC-uQC0u2!kbnNgEhqtE)dq)#Bm?YXB=#^l#w?aTcY;$Lcg3cqn_a$PHO@Wl(q zI8I)IX%goV&q$d!_*vJ`#h7K74|!of;tcj9PGdjf5j@dYX|e!0FvU9&_k*MdIv!p5!>`@Ch+Cr}P*pUwi_$@Kbt#q0~n zhcdv~!%^(h!43{U|Mq9VuK2fnyo~D{_Br$a4ZfTCpdEd23Vm@B&wA8cU(!hqe3^3!RVpPKO^|hi~2N~Zp=CL z;YIikqYo>g4`#e{>I2*0MSeOytN7vkx&k`DcZcyez4QkhmqgNAmCrALtgjj_7ONI< zETQe4&wH!>9r9zk`R%M3R}^-18ufb5l$+(-MY-P&-{pXR%>nOlz;`;}_dDP_9B`Wh z-tK_6Ip9_Yyu|@;cEIm(z?&TKMhCpX0k3z!%?=n(b7#n_!2z#xz##{Gy90i=1HR1x z*E`@_9q?KQyv70F;(%{JEFO)B=gJXM=u}C@=wN_bpaq^&i zi|ppuuEfAzOTIL=lkWz$ek+61k_V2X@ zlk%O*DWvre_VqDOz3Enn@RoI(n*pz`Srv`#j>)|6`fD3(N+;7jtf$J)Ow)DM3wguIfmj4DC&v4Bb^6X&EE&d2 zZ{v7xu}SOg2j#udu&M(FG~Nr+`4-=JVz57I6}UF?Bio|kjty(AJNo&`Xq2$xv2>(I zOAqgsj`wyC4oK0mY@rYIiu!v zB8XjsskFtMu9&r@bBmQ2ur>ib-dw#`tSsCKVY?OS0lW_zSG=z*29rs=P&fwuw16S2ow0tD8N}s3+FGUCTBX}srQ2Gi+ghdDTBX}srQ2G?wphPT$7^)l zsbjXwe0UxiLq;;z?XP0{OAu~AXjgf+AgwLDwc$PChUN{Mw&?rjElrS9TX@~JZH08+ zoAm8%+cs_4fFdZf<&Mn_&D+#{!`7`W&Fi-4^p+OpH*Rf#8)LkA^E$)^$DJEDwKZ>V zUDw#G>NaoNwsjlw@7VI*EnDv-4s$)W=B<3i+PCs$hu{!7Iz*%8@Aj(I(~Hv?;-#oA-tb0mXzX3{>{*S#Ig~ zh10=AtF69Re|Ne^-Sfrmyu%4{`ZpUsRMsU?{q8|&N~C2bUQ^$??cEZ~1%8t6-N!5X zwc9XsD-y_0JTb7VGfgv9mPD)U$E)H+B|J+rU;Dq-x~CU*Ua;1bHcc3XdewPgISjVD zhQt-FsoM*;zq~gf!~X80AUE>5W)ipM-Yx9oJM#I;VFb~Av}lhBEl;O=6c45X_asyn6z3^J9pg+9bpY#4Xq09`XJ72;&QgLl(X>h4?iep5$PDUcU_OA?~R} zdx#G$MSFp1?`K{)tQ$rU zG6+e84un>O5JC{aLhvF8gtJ&{Od;^wb(4rE5KbWQ${`*>;CJRSh?58%2)tSmhY*4Y z7J?T+FyK1d37iO%2one=5cqAj9O4m#3__A=2(1Vqgdl>2;6>nf(FEeN9l(Pyi7

RSSeupfHc&H6H5w{|Q5P}F6f)_y`@Oxlq@r^Hj_iGY?^4rkZxYi16 z*mB2m>&BWJYgX%ot@wh`odf9`TJVvsfrN!pR&7n)%GJSDwKc(7Yp{Q3f8w707yhOzm|rw!zS6&s z&d49J;jfc#dwA!J{E#i5dXKN5&dA?m%cnhDEI(vjJfHS+vHG+loPn6pegG*(zO=WC z<&v^IMy^X3%dT!PMusM4j>t+48-x9jE@-+GcJyXc1e{=Saoj!g`)mh(;pWjNon10Z|IrHuPCw-bj z|45RNAAK0E8S=5yzwVvL?d~5GMe}jvaf_PN-d)&~M2ru($(UcmlXv{+V1GOzYNC7b z0lMCZsOjlU^+*tvRGc0VH9%K`9SON_YzM-~8;JF>x~P#~^Q(~`KdafisdYQr8|+Gn z8u|Uhnt_D;2wF|72Olit$L?w(>BIoCqdLNdqr^2pa`<_}n(jmzM5}v#F0F=Jg8aZ+ zO){#9!Y;@_FLoYd$lVod#R$Aut^|SR&oqe-<=#Lz2!Q##7&CA%xD0{i_&sfgNmMj-S;mWSD}oz=<@o(= zhK+pNt z3_Yl1@)?s~>MrY1HvH}|!yeq5%ard&f+@%E4>M#on^KBbLTOt$j=cOz7 zAID4v@@6hm?&C;cIr8g`s!&4H&=+OQYZ$?lE8mGeM=&^;Z|?8ccIt2aoHXKo*{mE(8YS|O+rq?yaBZ@!LLx9jEnZwlpF znV>J0BhGIkm~x!o1b0uj#iFL&r*Y4ICLbY`t3^4}7Lp40e~f$L3o;QG%QdT8`ImVN zf2m`ch(GtDT!(24u(^E!_dkZ7nsP6GWV$V;5f`u55X^lm=zAUI?3c-dT1p;F9?Si! z0T7#VjHxT;>dSy9*jxn?HX@Kd@=x24I)Iqh1D_NkW78{xPvy@1OFzTQty`r(QLt*6 zK10E(1^NaBs~h?N1=DJktt*&TsBBuniXhsqg4vUWIVjpE7s?hH<7;h<3g5SNOAn=N zi|KBhUgt$S;^o#~b*HT;7*2;5?E;rusD`Qk3Rap!Jy$S$1?@vmdAS9g0xq>~A*?35 z)K6Y+Q6^*Rp@QXPR^BUkap7LUS2|#NaC1SzAV2EJAsfu$e#!>l4Vd(k1Dx*@8N^M1*|UV{hfXWDB|axTUqrsgM$f~5 zjr@zmJH#2lNjh&_q(@0g!Q}5x)UEtW_^)usH3bgz$nq}(<{F|EG3&pHm}>?c2$k?V z5pxb(uiSj+v?$lUEl^#;O@KM)Kc>rn2yw`ohWR~f&gqXMX8A85<{aFD zDG)vbm~-~$bpCe`bB=G|9|Pu^QI18>uK-|vSCX1Y_$I)d z)1TM%Hv;Ayz6TZ9{s#a{eMJZ1Y=MXY<{bSw&F>&!&dJ|^DY87rdN1(TOZ*GOmjIiK z@_vZnN`}6|CTELTUkUD|Z|2f|XSac9l z_}TB?4hhQk-VfNa!QFs^HaHD9WP|So+-igG1KeSQe+#f_-;4I~BkCF75C3hzNn81c z0NcMmehP5Lmj89YBR2St0CSDP{^9q)p95^JCAfJRaIQn8P@X>qe8L8MpeGYHxD@cD z4PFFz$_872&)VP>fVro^i}=?9wtxS917Plb@M8WQfVm&Si*P4kuHnkiMWjCsn0qF? znEz40AsdVX;xoQi|9QY2wtW1cX~y^NPXo@_@_!#N=X@L=7h*h_06b#L|2E*94gM>@ zTmzjeQuO@*@CjS~j{#5E;PZedZLkM+Hf4ja0DRU4R{=Jcg_{syuGyZ#J>{{D`CSOO zD31tWxhJLJ1YqOOy(qsMF!!x^vHWiW=3W*r!Z@rb_qPm;L#lGm%fP<_m}}BWS^iS- z2Y}6G;pTgQYxQ_Uef~SZ9X9-D0Vi#65r%lKG0&kc`MC;k#+Hwl8p?gR_9B&kGvEvT1u;I1H%C2H`8|Sjgkt&OkW5D;&X@8mxzB zNeYLfiEwvcqN}qnESKHk&cQuAXp`)V;WR-8Q!DtrcN|*7E<|E)SRDjYY5GVV z)68~*EUVAM>3Z_0le~|_yYUTm!ZXjtIWwmZ$rW-gI4W1jnd`uuvw;2NoHI`!z$%=e zE9B2{lCB`BFptztL#fVqOeS?D5`E!BlIIXpH8hb=u0-KljI%> z4}+{$C%;sA94TN-3Qi(8*u0;D{lIPxj9Oz2R+jL?O z_mXZ(BRQDr>Fe$8Nf%O~JUDHGy`)%7gyXVcxH}n+_NI~|)vpe@NK8r4)(0YRJ|@08 z6v765_{N%`%<7K8&|-a2S=7e$hL zS-B+~>4`;lrqZ2}ou(!`G#rlX=?ufDacc1+l2=`_4{Y!}py5&X9qHj&K1dU?mANTH z>+YG{Q7{^b>W^@DIKE2>ky2BgS-{`hM{Ef^v{05AriLlf`KZq#2taFN#S^)=lg&DljFMI&|B#X zdJBZ?ilwnLh|{DZys2$-*tj_87kyrv%mFGYhSq$FA{>t0eF3(C&U=8c7rG;NEG2uI zHS}0P&B9@*LT5VF8;wuvjy@V@dYC#0I|>5_`%;oN?UH8@7Y<`169qdVE~pJC0Cjyc zdA)!E@R`Q(HHz{=^}^vyty0oRGz}=*f^)*%s!yqTy`UCEL8$@liN;gC)BMQN616^i zi{2VcM+|>jlp1yXo`K%9@dVTkbh|l07mg`I+|aVMVO>jj>-zQEo7=)|>l#{`F=p`u zW^7Nd(oM)8rqoNWrnOP>sCou;_FrJJ+G>>RBYBaY0a+)VFq%XuQQ@S!3dgx`yxXXi VbQUZCdOOq5C2A63Dzjnz{{lk&Gp_&u diff --git a/Me_Lua/h13/lfs.so b/Me_Lua/h13/lfs.so deleted file mode 100644 index 0a5c165e535fea259afae448a6e25fc154a1b972..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20493 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 diff --git a/Me_Lua/h13/lsqlite3.so b/Me_Lua/h13/lsqlite3.so deleted file mode 100644 index fa267c0f42d3419e1581739f4fc5fda64abe8760..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53091 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 diff --git a/Me_Lua/h13/ltn12.lua b/Me_Lua/h13/ltn12.lua deleted file mode 100644 index 1014de2..0000000 --- a/Me_Lua/h13/ltn12.lua +++ /dev/null @@ -1,305 +0,0 @@ ------------------------------------------------------------------------------ --- 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 diff --git a/Me_Lua/h13/luci/controller/admin/network.lua b/Me_Lua/h13/luci/controller/admin/network.lua deleted file mode 100644 index f86b91c..0000000 --- a/Me_Lua/h13/luci/controller/admin/network.lua +++ /dev/null @@ -1,611 +0,0 @@ ---[[ -LuCI - Lua Configuration Interface - -Copyright 2008 Steven Barth -Copyright 2011 Jo-Philipp Wich - -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 - diff --git a/Me_Lua/h13/luci/controller/api/index.lua b/Me_Lua/h13/luci/controller/api/index.lua deleted file mode 100644 index f1f4d96..0000000 --- a/Me_Lua/h13/luci/controller/api/index.lua +++ /dev/null @@ -1,243 +0,0 @@ -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 ---rh_Jameson -smart_wifi_shutdown = nwfs.smart_wifi_shutdown - -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 - --rh_Jameson - page = entry({"api", "smart_wifi_shutdown"}, call("smart_wifi_shutdown"), 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 diff --git a/Me_Lua/h13/luci/controller/bs/index.lua b/Me_Lua/h13/luci/controller/bs/index.lua deleted file mode 100644 index 4f0a114..0000000 --- a/Me_Lua/h13/luci/controller/bs/index.lua +++ /dev/null @@ -1,105 +0,0 @@ -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 diff --git a/Me_Lua/h13/luci/dispatcher.lua b/Me_Lua/h13/luci/dispatcher.lua deleted file mode 100644 index a8b7fd1..0000000 --- a/Me_Lua/h13/luci/dispatcher.lua +++ /dev/null @@ -1,965 +0,0 @@ ---[[ -LuCI - Dispatcher - -Description: -The request dispatcher and module dispatcher generators - -FileId: -$Id$ - -License: -Copyright 2008 Steven Barth - -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 diff --git a/Me_Lua/h13/luci/model/network.lua b/Me_Lua/h13/luci/model/network.lua deleted file mode 100644 index 41b0e99..0000000 --- a/Me_Lua/h13/luci/model/network.lua +++ /dev/null @@ -1,1632 +0,0 @@ ---[[ -LuCI - Network model - -Copyright 2009-2010 Jo-Philipp Wich - -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 type, next, pairs, ipairs, loadfile, table - = type, next, pairs, ipairs, loadfile, table - -local tonumber, tostring, math = tonumber, tostring, math - -local require = require - -local bus = require "ubus" -local nxo = require "nixio" -local nfs = require "nixio.fs" -local ipc = require "luci.ip" -local sys = require "luci.sys" -local utl = require "luci.util" -local dsp = require "luci.dispatcher" -local uci = require "luci.model.uci" -local lng = require "luci.i18n" - -module "luci.model.network" - - -IFACE_PATTERNS_VIRTUAL = { } -IFACE_PATTERNS_IGNORE = { "^wmaster%d", "^wifi%d", "^hwsim%d", "^imq%d", "^ifb%d", "^mon%.wlan%d", "^sit%d", "^gre%d", "^lo$" } -IFACE_PATTERNS_WIRELESS = { "^wlan%d", "^wl%d", "^ath%d", "^%w+%.network%d" } - - -protocol = utl.class() - -local _protocols = { } - -local _interfaces, _bridge, _switch, _tunnel -local _ubus, _ubusnetcache, _ubusdevcache, _ubuswificache -local _uci_real, _uci_state - -function _filter(c, s, o, r) - local val = _uci_real:get(c, s, o) - if val then - local l = { } - if type(val) == "string" then - for val in val:gmatch("%S+") do - if val ~= r then - l[#l+1] = val - end - end - if #l > 0 then - _uci_real:set(c, s, o, table.concat(l, " ")) - else - _uci_real:delete(c, s, o) - end - elseif type(val) == "table" then - for _, val in ipairs(val) do - if val ~= r then - l[#l+1] = val - end - end - if #l > 0 then - _uci_real:set(c, s, o, l) - else - _uci_real:delete(c, s, o) - end - end - end -end - -function _append(c, s, o, a) - local val = _uci_real:get(c, s, o) or "" - if type(val) == "string" then - local l = { } - for val in val:gmatch("%S+") do - if val ~= a then - l[#l+1] = val - end - end - l[#l+1] = a - _uci_real:set(c, s, o, table.concat(l, " ")) - elseif type(val) == "table" then - local l = { } - for _, val in ipairs(val) do - if val ~= a then - l[#l+1] = val - end - end - l[#l+1] = a - _uci_real:set(c, s, o, l) - end -end - -function _stror(s1, s2) - if not s1 or #s1 == 0 then - return s2 and #s2 > 0 and s2 - else - return s1 - end -end - -function _get(c, s, o) - return _uci_real:get(c, s, o) -end - -function _set(c, s, o, v) - if v ~= nil then - if type(v) == "boolean" then v = v and "1" or "0" end - return _uci_real:set(c, s, o, v) - else - return _uci_real:delete(c, s, o) - end -end - -function _wifi_iface(x) - local _, p - for _, p in ipairs(IFACE_PATTERNS_WIRELESS) do - if x:match(p) then - return true - end - end - return false -end - -function _wifi_state(key, val, field) - if not next(_ubuswificache) then - _ubuswificache = _ubus:call("network.wireless", "status", {}) or {} - end - - local radio, radiostate - for radio, radiostate in pairs(_ubuswificache) do - local ifc, ifcstate - for ifc, ifcstate in pairs(radiostate.interfaces) do - if ifcstate[key] == val then - return ifcstate[field] - end - end - end -end - -function _wifi_lookup(ifn) - -- got a radio#.network# pseudo iface, locate the corresponding section - local radio, ifnidx = ifn:match("^(%w+)%.network(%d+)$") - if radio and ifnidx then - local sid = nil - local num = 0 - - ifnidx = tonumber(ifnidx) - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device == radio then - num = num + 1 - if num == ifnidx then - sid = s['.name'] - return false - end - end - end) - - return sid - - -- looks like wifi, try to locate the section via state vars - elseif _wifi_iface(ifn) then - local sid = _wifi_state("ifname", ifn, "section") - if not sid then - _uci_state:foreach("wireless", "wifi-iface", - function(s) - if s.ifname == ifn then - sid = s['.name'] - return false - end - end) - end - - return sid - end -end - -function _iface_virtual(x) - local _, p - for _, p in ipairs(IFACE_PATTERNS_VIRTUAL) do - if x:match(p) then - return true - end - end - return false -end - -function _iface_ignore(x) - local _, p - for _, p in ipairs(IFACE_PATTERNS_IGNORE) do - if x:match(p) then - return true - end - end - return _iface_virtual(x) -end - - -function init(cursor) - _uci_real = cursor or _uci_real or uci.cursor() - _uci_state = _uci_real:substate() - - _interfaces = { } - _bridge = { } - _switch = { } - _tunnel = { } - - _ubus = bus.connect() - _ubusnetcache = { } - _ubusdevcache = { } - _ubuswificache = { } - - -- read interface information - local n, i - for n, i in ipairs(nxo.getifaddrs()) do - local name = i.name:match("[^:]+") - local prnt = name:match("^([^%.]+)%.") - - if _iface_virtual(name) then - _tunnel[name] = true - end - - if _tunnel[name] or not _iface_ignore(name) then - _interfaces[name] = _interfaces[name] or { - idx = i.ifindex or n, - name = name, - rawname = i.name, - flags = { }, - ipaddrs = { }, - ip6addrs = { } - } - - if prnt then - _switch[name] = true - _switch[prnt] = true - end - - if i.family == "packet" then - _interfaces[name].flags = i.flags - _interfaces[name].stats = i.data - _interfaces[name].macaddr = i.addr - elseif i.family == "inet" then - _interfaces[name].ipaddrs[#_interfaces[name].ipaddrs+1] = ipc.IPv4(i.addr, i.netmask) - elseif i.family == "inet6" then - _interfaces[name].ip6addrs[#_interfaces[name].ip6addrs+1] = ipc.IPv6(i.addr, i.netmask) - end - end - end - - -- read bridge informaton - local b, l - for l in utl.execi("brctl show") do - if not l:match("STP") then - local r = utl.split(l, "%s+", nil, true) - if #r == 4 then - b = { - name = r[1], - id = r[2], - stp = r[3] == "yes", - ifnames = { _interfaces[r[4]] } - } - if b.ifnames[1] then - b.ifnames[1].bridge = b - end - _bridge[r[1]] = b - elseif b then - b.ifnames[#b.ifnames+1] = _interfaces[r[2]] - b.ifnames[#b.ifnames].bridge = b - end - end - end - - return _M -end - -function save(self, ...) - _uci_real:save(...) - _uci_real:load(...) -end - -function commit(self, ...) - _uci_real:commit(...) - _uci_real:load(...) -end - -function ifnameof(self, x) - if utl.instanceof(x, interface) then - return x:name() - elseif utl.instanceof(x, protocol) then - return x:ifname() - elseif type(x) == "string" then - return x:match("^[^:]+") - end -end - -function get_protocol(self, protoname, netname) - local v = _protocols[protoname] - if v then - return v(netname or "__dummy__") - end -end - -function get_protocols(self) - local p = { } - local _, v - for _, v in ipairs(_protocols) do - p[#p+1] = v("__dummy__") - end - return p -end - -function register_protocol(self, protoname) - local proto = utl.class(protocol) - - function proto.__init__(self, name) - self.sid = name - end - - function proto.proto(self) - return protoname - end - - _protocols[#_protocols+1] = proto - _protocols[protoname] = proto - - return proto -end - -function register_pattern_virtual(self, pat) - IFACE_PATTERNS_VIRTUAL[#IFACE_PATTERNS_VIRTUAL+1] = pat -end - - -function has_ipv6(self) - return nfs.access("/proc/net/ipv6_route") -end - -function add_network(self, n, options) - local oldnet = self:get_network(n) - if n and #n > 0 and n:match("^[a-zA-Z0-9_]+$") and not oldnet then - if _uci_real:section("network", "interface", n, options) then - return network(n) - end - elseif oldnet and oldnet:is_empty() then - if options then - local k, v - for k, v in pairs(options) do - oldnet:set(k, v) - end - end - return oldnet - end -end - -function get_network(self, n) - if n and _uci_real:get("network", n) == "interface" then - return network(n) - end -end - -function get_networks(self) - local nets = { } - local nls = { } - - _uci_real:foreach("network", "interface", - function(s) - nls[s['.name']] = network(s['.name']) - end) - - local n - for n in utl.kspairs(nls) do - nets[#nets+1] = nls[n] - end - - return nets -end - -function del_network(self, n) - local r = _uci_real:delete("network", n) - if r then - _uci_real:delete_all("network", "alias", - function(s) return (s.interface == n) end) - - _uci_real:delete_all("network", "route", - function(s) return (s.interface == n) end) - - _uci_real:delete_all("network", "route6", - function(s) return (s.interface == n) end) - - _uci_real:foreach("wireless", "wifi-iface", - function(s) - local net - local rest = { } - for net in utl.imatch(s.network) do - if net ~= n then - rest[#rest+1] = net - end - end - if #rest > 0 then - _uci_real:set("wireless", s['.name'], "network", - table.concat(rest, " ")) - else - _uci_real:delete("wireless", s['.name'], "network") - end - end) - end - return r -end - -function rename_network(self, old, new) - local r - if new and #new > 0 and new:match("^[a-zA-Z0-9_]+$") and not self:get_network(new) then - r = _uci_real:section("network", "interface", new, _uci_real:get_all("network", old)) - - if r then - _uci_real:foreach("network", "alias", - function(s) - if s.interface == old then - _uci_real:set("network", s['.name'], "interface", new) - end - end) - - _uci_real:foreach("network", "route", - function(s) - if s.interface == old then - _uci_real:set("network", s['.name'], "interface", new) - end - end) - - _uci_real:foreach("network", "route6", - function(s) - if s.interface == old then - _uci_real:set("network", s['.name'], "interface", new) - end - end) - - _uci_real:foreach("wireless", "wifi-iface", - function(s) - local net - local list = { } - for net in utl.imatch(s.network) do - if net == old then - list[#list+1] = new - else - list[#list+1] = net - end - end - if #list > 0 then - _uci_real:set("wireless", s['.name'], "network", - table.concat(list, " ")) - end - end) - - _uci_real:delete("network", old) - end - end - return r or false -end - -function get_interface(self, i) - if _interfaces[i] or _wifi_iface(i) then - return interface(i) - else - local ifc - local num = { } - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - if s['.name'] == i then - ifc = interface( - "%s.network%d" %{s.device, num[s.device] }) - return false - end - end - end) - return ifc - end -end - -function get_interfaces(self) - local iface - local ifaces = { } - local seen = { } - local nfs = { } - local baseof = { } - - -- find normal interfaces - _uci_real:foreach("network", "interface", - function(s) - for iface in utl.imatch(s.ifname) do - if not _iface_ignore(iface) and not _wifi_iface(iface) then - seen[iface] = true - nfs[iface] = interface(iface) - end - end - end) - - for iface in utl.kspairs(_interfaces) do - if not (seen[iface] or _iface_ignore(iface) or _wifi_iface(iface)) then - nfs[iface] = interface(iface) - end - end - - -- find vlan interfaces - _uci_real:foreach("network", "switch_vlan", - function(s) - if not s.device then - return - end - - local base = baseof[s.device] - if not base then - if not s.device:match("^eth%d") then - local l - for l in utl.execi("swconfig dev %q help 2>/dev/null" % s.device) do - if not base then - base = l:match("^%w+: (%w+)") - end - end - if not base or not base:match("^eth%d") then - base = "eth0" - end - else - base = s.device - end - baseof[s.device] = base - end - - local vid = tonumber(s.vid or s.vlan) - if vid ~= nil and vid >= 0 and vid <= 4095 then - local iface = "%s.%d" %{ base, vid } - if not seen[iface] then - seen[iface] = true - nfs[iface] = interface(iface) - end - end - end) - - for iface in utl.kspairs(nfs) do - ifaces[#ifaces+1] = nfs[iface] - end - - -- find wifi interfaces - local num = { } - local wfs = { } - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - local i = "%s.network%d" %{ s.device, num[s.device] } - wfs[i] = interface(i) - end - end) - - for iface in utl.kspairs(wfs) do - ifaces[#ifaces+1] = wfs[iface] - end - - return ifaces -end - -function ignore_interface(self, x) - return _iface_ignore(x) -end - -function get_wifidev(self, dev) - if _uci_real:get("wireless", dev) == "wifi-device" then - return wifidev(dev) - end -end - -function get_wifidevs(self) - local devs = { } - local wfd = { } - - _uci_real:foreach("wireless", "wifi-device", - function(s) wfd[#wfd+1] = s['.name'] end) - - local dev - for _, dev in utl.vspairs(wfd) do - devs[#devs+1] = wifidev(dev) - end - - return devs -end - -function get_wifinet(self, net) - local wnet = _wifi_lookup(net) - if wnet then - return wifinet(wnet) - end -end - -function add_wifinet(self, net, options) - if type(options) == "table" and options.device and - _uci_real:get("wireless", options.device) == "wifi-device" - then - local wnet = _uci_real:section("wireless", "wifi-iface", nil, options) - return wifinet(wnet) - end -end - -function del_wifinet(self, net) - local wnet = _wifi_lookup(net) - if wnet then - _uci_real:delete("wireless", wnet) - return true - end - return false -end - -function get_status_by_route(self, addr, mask) - local _, object - for _, object in ipairs(_ubus:objects()) do - local net = object:match("^network%.interface%.(.+)") - if net then - local s = _ubus:call(object, "status", {}) - if s and s.route then - local rt - for _, rt in ipairs(s.route) do - if not rt.table and rt.target == addr and rt.mask == mask then - return net, s - end - end - end - end - end -end - -function get_status_by_address(self, addr) - local _, object - for _, object in ipairs(_ubus:objects()) do - local net = object:match("^network%.interface%.(.+)") - if net then - local s = _ubus:call(object, "status", {}) - if s and s['ipv4-address'] then - local a - for _, a in ipairs(s['ipv4-address']) do - if a.address == addr then - return net, s - end - end - end - if s and s['ipv6-address'] then - local a - for _, a in ipairs(s['ipv6-address']) do - if a.address == addr then - return net, s - end - end - end - end - end -end - -function get_wannet(self) - local net = self:get_status_by_route("0.0.0.0", 0) - return net and network(net) -end - -function get_wandev(self) - local _, stat = self:get_status_by_route("0.0.0.0", 0) - return stat and interface(stat.l3_device or stat.device) -end - -function get_wan6net(self) - local net = self:get_status_by_route("::", 0) - return net and network(net) -end - -function get_wan6dev(self) - local _, stat = self:get_status_by_route("::", 0) - return stat and interface(stat.l3_device or stat.device) -end - - -function network(name, proto) - if name then - local p = proto or _uci_real:get("network", name, "proto") - local c = p and _protocols[p] or protocol - return c(name) - end -end - -function protocol.__init__(self, name) - self.sid = name -end - -function protocol._get(self, opt) - local v = _uci_real:get("network", self.sid, opt) - if type(v) == "table" then - return table.concat(v, " ") - end - return v or "" -end - -function protocol._ubus(self, field) - if not _ubusnetcache[self.sid] then - _ubusnetcache[self.sid] = _ubus:call("network.interface.%s" % self.sid, - "status", { }) - end - if _ubusnetcache[self.sid] and field then - return _ubusnetcache[self.sid][field] - end - return _ubusnetcache[self.sid] -end - -function protocol.get(self, opt) - return _get("network", self.sid, opt) -end - -function protocol.set(self, opt, val) - return _set("network", self.sid, opt, val) -end - -function protocol.ifname(self) - local ifname - if self:is_floating() then - ifname = self:_ubus("l3_device") - else - ifname = self:_ubus("device") - end - if not ifname then - local num = { } - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] - and num[s.device] + 1 or 1 - - local net - for net in utl.imatch(s.network) do - if net == self.sid then - ifname = "%s.network%d" %{ s.device, num[s.device] } - return false - end - end - end - end) - end - return ifname -end - -function protocol.proto(self) - return "none" -end - -function protocol.get_i18n(self) - local p = self:proto() - if p == "none" then - return lng.translate("Unmanaged") - elseif p == "static" then - return lng.translate("Static address") - elseif p == "dhcp" then - return lng.translate("DHCP client") - else - return lng.translate("Unknown") - end -end - -function protocol.type(self) - return self:_get("type") -end - -function protocol.name(self) - return self.sid -end - -function protocol.uptime(self) - return self:_ubus("uptime") or 0 -end - -function protocol.expires(self) - local a = tonumber(_uci_state:get("network", self.sid, "lease_acquired")) - local l = tonumber(_uci_state:get("network", self.sid, "lease_lifetime")) - if a and l then - l = l - (nxo.sysinfo().uptime - a) - return l > 0 and l or 0 - end - return -1 -end - -function protocol.metric(self) - return tonumber(_uci_state:get("network", self.sid, "metric")) or 0 -end - -function protocol.ipaddr(self) - local addrs = self:_ubus("ipv4-address") - return addrs and #addrs > 0 and addrs[1].address -end - -function protocol.netmask(self) - local addrs = self:_ubus("ipv4-address") - return addrs and #addrs > 0 and - ipc.IPv4("0.0.0.0/%d" % addrs[1].mask):mask():string() -end - -function protocol.gwaddr(self) - local _, route - for _, route in ipairs(self:_ubus("route") or { }) do - if route.target == "0.0.0.0" and route.mask == 0 then - return route.nexthop - end - end -end - -function protocol.dnsaddrs(self) - local dns = { } - local _, addr - for _, addr in ipairs(self:_ubus("dns-server") or { }) do - if not addr:match(":") then - dns[#dns+1] = addr - end - end - return dns -end - -function protocol.ip6addr(self) - local addrs = self:_ubus("ipv6-address") - if addrs and #addrs > 0 then - return "%s/%d" %{ addrs[1].address, addrs[1].mask } - else - addrs = self:_ubus("ipv6-prefix-assignment") - if addrs and #addrs > 0 then - return "%s/%d" %{ addrs[1].address, addrs[1].mask } - end - end -end - -function protocol.gw6addr(self) - local _, route - for _, route in ipairs(self:_ubus("route") or { }) do - if route.target == "::" and route.mask == 0 then - return ipc.IPv6(route.nexthop):string() - end - end -end - -function protocol.dns6addrs(self) - local dns = { } - local _, addr - for _, addr in ipairs(self:_ubus("dns-server") or { }) do - if addr:match(":") then - dns[#dns+1] = addr - end - end - return dns -end - -function protocol.is_bridge(self) - return (not self:is_virtual() and self:type() == "bridge") -end - -function protocol.opkg_package(self) - return nil -end - -function protocol.is_installed(self) - return true -end - -function protocol.is_virtual(self) - return false -end - -function protocol.is_floating(self) - return false -end - -function protocol.is_empty(self) - if self:is_floating() then - return false - else - local rv = true - - if (self:_get("ifname") or ""):match("%S+") then - rv = false - end - - _uci_real:foreach("wireless", "wifi-iface", - function(s) - local n - for n in utl.imatch(s.network) do - if n == self.sid then - rv = false - return false - end - end - end) - - return rv - end -end - -function protocol.add_interface(self, ifname) - ifname = _M:ifnameof(ifname) - if ifname and not self:is_floating() then - -- if its a wifi interface, change its network option - local wif = _wifi_lookup(ifname) - if wif then - _append("wireless", wif, "network", self.sid) - - -- add iface to our iface list - else - _append("network", self.sid, "ifname", ifname) - end - end -end - -function protocol.del_interface(self, ifname) - ifname = _M:ifnameof(ifname) - if ifname and not self:is_floating() then - -- if its a wireless interface, clear its network option - local wif = _wifi_lookup(ifname) - if wif then _filter("wireless", wif, "network", self.sid) end - - -- remove the interface - _filter("network", self.sid, "ifname", ifname) - end -end - -function protocol.get_interface(self) - if self:is_virtual() then - _tunnel[self:proto() .. "-" .. self.sid] = true - return interface(self:proto() .. "-" .. self.sid, self) - elseif self:is_bridge() then - _bridge["br-" .. self.sid] = true - return interface("br-" .. self.sid, self) - else - local ifn = nil - local num = { } - for ifn in utl.imatch(_uci_real:get("network", self.sid, "ifname")) do - ifn = ifn:match("^[^:/]+") - return ifn and interface(ifn, self) - end - ifn = nil - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - - local net - for net in utl.imatch(s.network) do - if net == self.sid then - ifn = "%s.network%d" %{ s.device, num[s.device] } - return false - end - end - end - end) - return ifn and interface(ifn, self) - end -end - -function protocol.get_interfaces(self) - if self:is_bridge() or (self:is_virtual() and not self:is_floating()) then - local ifaces = { } - - local ifn - local nfs = { } - for ifn in utl.imatch(self:get("ifname")) do - ifn = ifn:match("^[^:/]+") - nfs[ifn] = interface(ifn, self) - end - - for ifn in utl.kspairs(nfs) do - ifaces[#ifaces+1] = nfs[ifn] - end - - local num = { } - local wfs = { } - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - - local net - for net in utl.imatch(s.network) do - if net == self.sid then - ifn = "%s.network%d" %{ s.device, num[s.device] } - wfs[ifn] = interface(ifn, self) - end - end - end - end) - - for ifn in utl.kspairs(wfs) do - ifaces[#ifaces+1] = wfs[ifn] - end - - return ifaces - end -end - -function protocol.contains_interface(self, ifname) - ifname = _M:ifnameof(ifname) - if not ifname then - return false - elseif self:is_virtual() and self:proto() .. "-" .. self.sid == ifname then - return true - elseif self:is_bridge() and "br-" .. self.sid == ifname then - return true - else - local ifn - for ifn in utl.imatch(self:get("ifname")) do - ifn = ifn:match("[^:]+") - if ifn == ifname then - return true - end - end - - local wif = _wifi_lookup(ifname) - if wif then - local n - for n in utl.imatch(_uci_real:get("wireless", wif, "network")) do - if n == self.sid then - return true - end - end - end - end - - return false -end - -function protocol.adminlink(self) - return dsp.build_url("admin", "network", "network", self.sid) -end - -function protocol.get_option_value(self,name) - return self:_get(name) -end - -function protocol.status(self) - local iface = uci.cursor_state():get_all("network", self.sid) - local proto = iface["proto"] - local ifname = iface["ifname"] - local device = iface["device"] - local up = tonumber(iface["up"]) - if proto == "pppoe" then - if device == nil then - return "down" - end - if up == nil then - return "connection" - end - if up == 1 then - return "up" - end - elseif proto == "3g" then - if device ~= ifname and up==nil then - return "down" - end - if device == ifname and up == nil then - return "connection" - end - if up == 1 then - return "up" - end - elseif proto == "static" then - if up == nil then - return "down" - end - if up == 1 then - return "up" - end - elseif proto == "dhcp" then - if up == nil then - return "down" - end - if up == 1 then - return "up" - end - end - return "unkown" -end - -interface = utl.class() - -function interface.__init__(self, ifname, network) - local wif = _wifi_lookup(ifname) - if wif then - self.wif = wifinet(wif) - self.ifname = _wifi_state("section", wif, "ifname") - end - - self.ifname = self.ifname or ifname - self.dev = _interfaces[self.ifname] - self.network = network -end - -function interface._ubus(self, field) - if not _ubusdevcache[self.ifname] then - _ubusdevcache[self.ifname] = _ubus:call("network.device", "status", - { name = self.ifname }) - end - if _ubusdevcache[self.ifname] and field then - return _ubusdevcache[self.ifname][field] - end - return _ubusdevcache[self.ifname] -end - -function interface.name(self) - return self.wif and self.wif:ifname() or self.ifname -end - -function interface.mac(self) - return (self:_ubus("macaddr") or "00:00:00:00:00:00"):upper() -end - -function interface.ipaddrs(self) - return self.dev and self.dev.ipaddrs or { } -end - -function interface.ip6addrs(self) - return self.dev and self.dev.ip6addrs or { } -end - -function interface.type(self) - if self.wif or _wifi_iface(self.ifname) then - return "wifi" - elseif _bridge[self.ifname] then - return "bridge" - elseif _tunnel[self.ifname] then - return "tunnel" - elseif self.ifname:match("%.") then - return "vlan" - elseif _switch[self.ifname] then - return "switch" - else - return "ethernet" - end -end - -function interface.shortname(self) - if self.wif then - return "%s %q" %{ - self.wif:active_mode(), - self.wif:active_ssid() or self.wif:active_bssid() - } - else - return self.ifname - end -end - -function interface.get_i18n(self) - if self.wif then - return "%s: %s %q" %{ - lng.translate("Wireless Network"), - self.wif:active_mode(), - self.wif:active_ssid() or self.wif:active_bssid() - } - else - return "%s: %q" %{ self:get_type_i18n(), self:name() } - end -end - -function interface.get_type_i18n(self) - local x = self:type() - if x == "wifi" then - return lng.translate("Wireless Adapter") - elseif x == "bridge" then - return lng.translate("Bridge") - elseif x == "switch" then - return lng.translate("Ethernet Switch") - elseif x == "vlan" then - return lng.translate("VLAN Interface") - elseif x == "tunnel" then - return lng.translate("Tunnel Interface") - else - return lng.translate("Ethernet Adapter") - end -end - -function interface.adminlink(self) - if self.wif then - return self.wif:adminlink() - end -end - -function interface.ports(self) - local members = self:_ubus("bridge-members") - if members then - local _, iface - local ifaces = { } - for _, iface in ipairs(members) do - ifaces[#ifaces+1] = interface(iface) - end - end -end - -function interface.bridge_id(self) - if self.br then - return self.br.id - else - return nil - end -end - -function interface.bridge_stp(self) - if self.br then - return self.br.stp - else - return false - end -end - -function interface.is_up(self) - return self:_ubus("up") or false -end - -function interface.is_bridge(self) - return (self:type() == "bridge") -end - -function interface.is_bridgeport(self) - return self.dev and self.dev.bridge and true or false -end - -function interface.tx_bytes(self) - local stat = self:_ubus("statistics") - return stat and stat.tx_bytes or 0 -end - -function interface.rx_bytes(self) - local stat = self:_ubus("statistics") - return stat and stat.rx_bytes or 0 -end - -function interface.tx_packets(self) - local stat = self:_ubus("statistics") - return stat and stat.tx_packets or 0 -end - -function interface.rx_packets(self) - local stat = self:_ubus("statistics") - return stat and stat.rx_packets or 0 -end - -function interface.get_network(self) - return self:get_networks()[1] -end - -function interface.get_networks(self) - if not self.networks then - local nets = { } - local _, net - for _, net in ipairs(_M:get_networks()) do - if net:contains_interface(self.ifname) or - net:ifname() == self.ifname - then - nets[#nets+1] = net - end - end - table.sort(nets, function(a, b) return a.sid < b.sid end) - self.networks = nets - return nets - else - return self.networks - end -end - -function interface.get_wifinet(self) - return self.wif -end - - -wifidev = utl.class() - -function wifidev.__init__(self, dev) - self.sid = dev - self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { } -end - -function wifidev.get(self, opt) - return _get("wireless", self.sid, opt) -end - -function wifidev.set(self, opt, val) - return _set("wireless", self.sid, opt, val) -end - -function wifidev.name(self) - return self.sid -end - -function wifidev.hwmodes(self) - local l = self.iwinfo.hwmodelist - if l and next(l) then - return l - else - return { b = true, g = true } - end -end - -function wifidev.get_i18n(self) - local t = "Generic" - if self.iwinfo.type == "wl" then - t = "Broadcom" - elseif self.iwinfo.type == "madwifi" then - t = "Atheros" - end - - local m = "" - local l = self:hwmodes() - if l.a then m = m .. "a" end - if l.b then m = m .. "b" end - if l.g then m = m .. "g" end - if l.n then m = m .. "n" end - if l.ac then m = "ac" end - - return "%s 802.11%s Wireless Controller (%s)" %{ t, m, self:name() } -end - -function wifidev.is_up(self) - if _ubuswificache[self.sid] then - return (_ubuswificache[self.sid].up == true) - end - - local up = false - _uci_state:foreach("wireless", "wifi-iface", - function(s) - if s.device == self.sid then - if s.up == "1" then - up = true - return false - end - end - end) - - return up -end - -function wifidev.get_wifinet(self, net) - if _uci_real:get("wireless", net) == "wifi-iface" then - return wifinet(net) - else - local wnet = _wifi_lookup(net) - if wnet then - return wifinet(wnet) - end - end -end - -function wifidev.get_wifinets(self) - local nets = { } - - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device == self.sid then - nets[#nets+1] = wifinet(s['.name']) - end - end) - - return nets -end - -function wifidev.add_wifinet(self, options) - options = options or { } - options.device = self.sid - - local wnet = _uci_real:section("wireless", "wifi-iface", nil, options) - if wnet then - return wifinet(wnet, options) - end -end - -function wifidev.del_wifinet(self, net) - if utl.instanceof(net, wifinet) then - net = net.sid - elseif _uci_real:get("wireless", net) ~= "wifi-iface" then - net = _wifi_lookup(net) - end - - if net and _uci_real:get("wireless", net, "device") == self.sid then - _uci_real:delete("wireless", net) - return true - end - - return false -end - - -wifinet = utl.class() - -function wifinet.__init__(self, net, data) - self.sid = net - - local num = { } - local netid - _uci_real:foreach("wireless", "wifi-iface", - function(s) - if s.device then - num[s.device] = num[s.device] and num[s.device] + 1 or 1 - if s['.name'] == self.sid then - netid = "%s.network%d" %{ s.device, num[s.device] } - return false - end - end - end) - - local dev = _wifi_state("section", self.sid, "ifname") or netid - - self.netid = netid - self.wdev = dev - self.iwinfo = dev and sys.wifi.getiwinfo(dev) or { } - self.iwdata = data or _uci_state:get_all("wireless", self.sid) or - _uci_real:get_all("wireless", self.sid) or { } -end - -function wifinet.get(self, opt) - return _get("wireless", self.sid, opt) -end - -function wifinet.set(self, opt, val) - return _set("wireless", self.sid, opt, val) -end - -function wifinet.mode(self) - return _uci_state:get("wireless", self.sid, "mode") or "ap" -end - -function wifinet.ssid(self) - return _uci_state:get("wireless", self.sid, "ssid") -end - -function wifinet.bssid(self) - return _uci_state:get("wireless", self.sid, "bssid") -end - -function wifinet.network(self) - return _uci_state:get("wifinet", self.sid, "network") -end - -function wifinet.id(self) - return self.netid -end - -function wifinet.name(self) - return self.sid -end - -function wifinet.ifname(self) - local ifname = self.iwinfo.ifname - if not ifname or ifname:match("^wifi%d") or ifname:match("^radio%d") then - ifname = self.wdev - end - return ifname -end - -function wifinet.get_device(self) - if self.iwdata.device then - return wifidev(self.iwdata.device) - end -end - -function wifinet.is_up(self) - local ifc = self:get_interface() - return (ifc and ifc:is_up() or false) -end - -function wifinet.active_mode(self) - local m = _stror(self.iwinfo.mode, self.iwdata.mode) or "ap" - - if m == "ap" then m = "Master" - elseif m == "sta" then m = "Client" - elseif m == "adhoc" then m = "Ad-Hoc" - elseif m == "mesh" then m = "Mesh" - elseif m == "monitor" then m = "Monitor" - end - - return m -end - -function wifinet.active_mode_i18n(self) - return lng.translate(self:active_mode()) -end - -function wifinet.active_ssid(self) - return _stror(self.iwinfo.ssid, self.iwdata.ssid) -end - -function wifinet.active_bssid(self) - return _stror(self.iwinfo.bssid, self.iwdata.bssid) or "00:00:00:00:00:00" -end - -function wifinet.active_encryption(self) - local enc = self.iwinfo and self.iwinfo.encryption - return enc and enc.description or "-" -end - -function wifinet.assoclist(self) - return self.iwinfo.assoclist or { } -end - -function wifinet.frequency(self) - local freq = self.iwinfo.frequency - if freq and freq > 0 then - return "%.03f" % (freq / 1000) - end -end - -function wifinet.bitrate(self) - local rate = self.iwinfo.bitrate - if rate and rate > 0 then - return (rate / 1000) - end -end - -function wifinet.channel(self) - return self.iwinfo.channel or - tonumber(_uci_state:get("wireless", self.iwdata.device, "channel")) -end - -function wifinet.signal(self) - return self.iwinfo.signal or 0 -end - -function wifinet.noise(self) - return self.iwinfo.noise or 0 -end - -function wifinet.country(self) - return self.iwinfo.country or "00" -end - -function wifinet.txpower(self) - local pwr = (self.iwinfo.txpower or 0) - return pwr + self:txpower_offset() -end - -function wifinet.txpower_offset(self) - return self.iwinfo.txpower_offset or 0 -end - -function wifinet.signal_level(self, s, n) - if self:active_bssid() ~= "00:00:00:00:00:00" then - local signal = s or self:signal() - local noise = n or self:noise() - - if signal < 0 and noise < 0 then - local snr = -1 * (noise - signal) - return math.floor(snr / 5) - else - return 0 - end - else - return -1 - end -end - -function wifinet.signal_percent(self) - local qc = self.iwinfo.quality or 0 - local qm = self.iwinfo.quality_max or 0 - - if qc > 0 and qm > 0 then - return math.floor((100 / qm) * qc) - else - return 0 - end -end - -function wifinet.shortname(self) - return "%s %q" %{ - lng.translate(self:active_mode()), - self:active_ssid() or self:active_bssid() - } -end - -function wifinet.get_i18n(self) - return "%s: %s %q (%s)" %{ - lng.translate("Wireless Network"), - lng.translate(self:active_mode()), - self:active_ssid() or self:active_bssid(), - self:ifname() - } -end - -function wifinet.adminlink(self) - return dsp.build_url("admin", "network", "wireless", self.netid) -end - -function wifinet.get_network(self) - return self:get_networks()[1] -end - -function wifinet.get_networks(self) - local nets = { } - local net - for net in utl.imatch(tostring(self.iwdata.network)) do - if _uci_real:get("network", net) == "interface" then - nets[#nets+1] = network(net) - end - end - table.sort(nets, function(a, b) return a.sid < b.sid end) - return nets -end - -function wifinet.get_interface(self) - return interface(self:ifname()) -end - - --- setup base protocols -_M:register_protocol("static") -_M:register_protocol("dhcp") -_M:register_protocol("none") - --- load protocol extensions -local exts = nfs.dir(utl.libpath() .. "/model/network") -if exts then - local ext - for ext in exts do - if ext:match("%.lua$") then - require("luci.model.network." .. ext:gsub("%.lua$", "")) - end - end -end diff --git a/Me_Lua/h13/luci/sauth.lua b/Me_Lua/h13/luci/sauth.lua deleted file mode 100644 index ec02be8..0000000 --- a/Me_Lua/h13/luci/sauth.lua +++ /dev/null @@ -1,200 +0,0 @@ ---[[ - -Session authentication -(c) 2008 Steven Barth - -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 diff --git a/Me_Lua/h13/meizu/arpmon.lua b/Me_Lua/h13/meizu/arpmon.lua deleted file mode 100644 index ccecba8..0000000 --- a/Me_Lua/h13/meizu/arpmon.lua +++ /dev/null @@ -1,103 +0,0 @@ -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 - diff --git a/Me_Lua/h13/meizu/bfs.lua b/Me_Lua/h13/meizu/bfs.lua deleted file mode 100644 index 0906acb..0000000 --- a/Me_Lua/h13/meizu/bfs.lua +++ /dev/null @@ -1,370 +0,0 @@ -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 - diff --git a/Me_Lua/h13/meizu/build.sh b/Me_Lua/h13/meizu/build.sh deleted file mode 100644 index e3908c8..0000000 --- a/Me_Lua/h13/meizu/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/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 diff --git a/Me_Lua/h13/meizu/dbfs.lua b/Me_Lua/h13/meizu/dbfs.lua deleted file mode 100644 index e2f51cd..0000000 --- a/Me_Lua/h13/meizu/dbfs.lua +++ /dev/null @@ -1,410 +0,0 @@ -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 \ No newline at end of file diff --git a/Me_Lua/h13/meizu/nwfs.lua b/Me_Lua/h13/meizu/nwfs.lua deleted file mode 100644 index 238cccf..0000000 --- a/Me_Lua/h13/meizu/nwfs.lua +++ /dev/null @@ -1,2920 +0,0 @@ -module("meizu.nwfs", package.seeall) ---network functions - -local cjson = require "cjson" -local lfs = require "lfs" -local bfs = require "meizu.bfs" -local RC = require "meizu.r10config" -local dbfs = require "meizu.dbfs" -local posix = require "posix" - -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 b64dec = bfs.b64dec -local b64enc = bfs.b64enc - -local lue = require("luci.util").exec - -function wifi_network(wifi_device_name) - local network = require "luci.model.network".init() - local wifi_net = network:get_wifinet(wifi_device_name) - if wifi_net then - local dev = wifi_net:get_device() - if dev then - return { - id = wifi_device_name, - name = wifi_net:shortname(), - up = wifi_net:is_up(), - mode = wifi_net:active_mode(), - ssid = wifi_net:active_ssid(), - bssid = wifi_net:active_bssid(), - encryption = wifi_net:active_encryption(), - encryption_src = wifi_net:get("encryption"), - frequency = wifi_net:frequency(), - bitrate = wifi_net:bitrate(), - ifname = wifi_net:ifname(), - assoclist = wifi_net:assoclist(), - country = wifi_net:country(), - key = wifi_net:get("key"), - key1 = wifi_net:get("key1"), - hidden = wifi_net:get("hidden"), - device = { - up = dev:is_up(), - device = dev:name(), - name = dev:get_i18n() - } - } - end - end - return {} -end - -function wifi_networks() - 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 wifi_net - for _, wifi_net in ipairs(dev:get_wifinets()) do - rd.networks[#rd.networks+1] = { - name = wifi_net:shortname(), - up = wifi_net:is_up(), - mode = wifi_net:active_mode(), - ssid = wifi_net:active_ssid(), - bssid = wifi_net:active_bssid(), - encryption = wifi_net:active_encryption(), - frequency = wifi_net:frequency(), - channel = wifi_net:channel(), - signal = wifi_net:signal(), - quality = wifi_net:signal_percent(), - noise = wifi_net:noise(), - bitrate = wifi_net:bitrate(), - ifname = wifi_net:ifname(), - assoclist = wifi_net:assoclist(), - country = wifi_net:country(), - key = wifi_net:get("key"), - key1 = wifi_net:get("key1"), - encryption_src = wifi_net:get("encryption"), - hidden = wifi_net:get("hidden"), - } - end - result[#result+1] = rd - end - return result -end - -function nw_get_wifi_settings() - luci.http.prepare_content("application/json") - local app_version = luci.http.formvalue("appVer") - if app_version == nil then - app_version = 0 - end - local list = get_wifi_settings(app_version) - luci.http.write(list) -end - -function ww_get_wifi_settings(app_version) - local list = get_wifi_settings(app_version) - --return data_to_json(list) - return list -end - -function get_wifi_settings(app_version) - local network = require "luci.model.network".init() - local info_list = {} - local wifis = wifi_networks() - for i,wifi_net in ipairs(wifis) do - local item = {} - local index = 1 - - if wifi_net.device == "mt7628" then - local wifi_net_wl0 = network:get_wifinet('mt7628.network1') - item["ssid"] = wifi_net_wl0:get("ssid") - if wifi_net_wl0:get("disabled") == "1" then - item["status"] = "false" - else - item["status"] = "true" - end - end - - if wifi_net.device == "mt7610e" then - local wifi_net_wl1 = network:get_wifinet('mt7610e.network1') - item["ssid"] = wifi_net_wl1:get("ssid") - if wifi_net_wl1:get("disabled") == "1" then - item["status"] = "false" - else - item["status"] = "true" - end - end - - local encryption = wifi_net.networks[index].encryption_src - local key = wifi_net.networks[index].key - if encryption == "wep-open" then - key = wifi_net.networks[index].key1 - if key:len()>4 and key:sub(0,2)=="s:" then - key = key:sub(3) - end - end - local name = "wl0"; - if "rai0" == wifi_net.networks[index].ifname then - name = "wl1" - end - item["name"] = name - --item["ssid"] = wifi_net.networks[index].ssid - if key == nil then - key = "" - end - item["password"] = key - item["encryption"] = encryption - info_list[#wifis+1-i] = item - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, info_list) - if tonumber(app_version) >= 5 then - return b64enc(cjson.encode(info_list)) - else - return cjson.encode(info_list) - end -end - -function get_wifi_ssids() - local wifis = wifi_networks() - local ssid1 = "" - local ssid2 = "" - for i, wifi_net in ipairs(wifis) do - if i == 1 then - ssid1 = wifi_net.networks[1].ssid - end - if i == 2 then - ssid2 = wifi_net.networks[1].ssid - end - end - - return ssid1, ssid2 -end - -function nw_wifi_settings() - - luci.http.prepare_content("application/json") - local data = luci.http.formvalue("data") - local app_version = luci.http.formvalue("appVer") - if app_version == nil then - app_version = 0 - end - 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 - - if tonumber(app_version) >= 5 then - local data = b64dec(data) - data = cjson.decode(data) - - for k, v in pairs(data) do - if v.name == "wl0" then - switch_2g = v.on - ssid_2g = v.ssid - pwd_2g = v.pwd - encry_2g = v.encryption - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - elseif v.name == "wl1" then - switch_5g = v.on - ssid_5g = v.ssid - pwd_5g = v.pwd - encry_5g = v.encryption - end - end - else - switch_2g = luci.http.formvalue("on1") - ssid_2g = luci.http.formvalue("ssid1") - pwd_2g = luci.http.formvalue("pwd1") - encry_2g = luci.http.formvalue("encryption1") - - switch_5g = luci.http.formvalue("on2") - ssid_5g = luci.http.formvalue("ssid2") - pwd_5g = luci.http.formvalue("pwd2") - encry_5g = luci.http.formvalue("encryption2") - - end - - dbfs.init_ssid_table() - local dbssid = dbfs.fetch_ssid() - if nil == dbssid or #dbssid == 0 then - dbfs.add_ssid(ssid_2g, ssid_5g) - else - dbfs.update_ssid(ssid_2g, ssid_5g) - end - - local res = wifi_settings(switch_2g, ssid_2g, pwd_2g, encry_2g, switch_5g, ssid_5g, pwd_5g, encry_5g) - luci.http.write_json(res) -end - -function wifi_settings(on1, ssid1, pwd1, encry1, on2, ssid2, pwd2, encry2) - local result = {} - local res = {} - local code = 0 - local code1 = 0 - local code2 = 0 - local details = {} - local code1 = check_ssid(ssid1, 31) - local code2 = check_ssid(ssid2, 31) - local succeed1 = false - local succeed2 = false - if on1 == "false" then - require "MZLog".log(3, debug.getinfo(1).currentline) - succeed1 = set_wifi_basic_info(1, nil, nil, nil, on1) - else - if code1 == 1 then - succeed1 = set_wifi_basic_info(1, ssid1, pwd1, encry1, on1) - end - end - - if on2 == "false" then - succeed2 = set_wifi_basic_info(2, nil, nil, nil, on2) - else - if code2 == 1 then - succeed2 = set_wifi_basic_info(2, ssid2, pwd2, encry2, on2) - end - end - - if code == 0 and code1 ~= 0 and code2 ~= 0 and succeed1 ~= false and succeed2 ~= false then - res["result"] = true - fork_restart_network() - else - res["result"] = false - end - - return res -end - -function set_wifi_basic_info(wifi_index, ssid, password, encryption, on) - - local network = require "luci.model.network".init() - if wifi_index == 1 then - wifi_net = network:get_wifinet('mt7628.network1') - wifi_dev = network:get_wifidev('mt7628') - end - - if wifi_index == 2 then - wifi_net = network:get_wifinet('mt7610e.network1') - wifi_dev = network:get_wifidev('mt7610e') - end - - if wifi_net == nil then - return false - end - - if wifi_dev then - if on == "true" then - wifi_net:set("disabled", "0") - elseif on == "false" then - wifi_net:set("disabled", "1") - end - end - - if not is_str_nil(ssid) and check_ssid(ssid) then - wifi_net:set("ssid",ssid) - end - - local code = check_wifi_passwd(password,encryption) - if code == 0 then - wifi_net:set("encryption",encryption) - wifi_net:set("key",password) - if encryption == "none" then - wifi_net:set("key","") - elseif encryption == "wep-open" then - wifi_net:set("key1","s:"..password) - wifi_net:set("key",1) - end - elseif code > 1502 then - return false - end - - network:save("wireless") - network:commit("wireless") - return true -end - -function is_str_nil(str) - return (str == nil or str == "") -end - -function check_ssid(ssid) - if is_str_nil(ssid) then - return 0 - end - - return 1 -end - -function check_wifi_passwd(passwd,encryption) - if is_str_nil(encryption) or (encryption and encryption ~= "none" and is_str_nil(passwd)) then - return 1502 - end - if encryption == "psk" or encryption == "psk2" then - if passwd:len() < 8 then - return 1520 - end - elseif encryption == "mixed-psk" then - if passwd:len()<8 or passwd:len()>63 then - return 1521 - end - elseif encryption == "wep-open" then - if passwd:len()~=5 and passwd:len()~=13 then - return 1522 - end - end - return 0 -end -function fork_smart_wifi_shutdown(wnet, close_time, open_time) - local close_interval = close_time - os.time() - local open_interval = open_time - os.time() - - local cmd = string.format("/sbin/wifi down "..wnet.."; sleep 15; /sbin/wifi up "..wnet) - --local cmd = string.format("sleep %s; /sbin/wifi down; sleep %s; /sbin/wifi up;", tostring(close_interval), tostring(open_interval)) - --local cmd = "/sbin/wifi "..switch.." "..wnet - exec_cmd_in_sh(cmd) -end - --[[ - return coroutine.create(function() - --do close - while true do - if os.time() ~= close_time then - posix.sleep(1) - else - wifi_shutdown(wnet) - table["close"] = true - luci.http.write_json(table) - break - end - end - --do restart - while true do - if os.time() ~= restart_time then - posix.sleep(1) - else - wifi_reconnect(wnet) - table["restart"] = true - luci.http.write_json(table) - break - end - end - ) - --require "MZLog".log(3, debug.getinfo(1).currentline) - ]]-- - - -function fork_restart_wifi() - local cmd = "sleep 1; /sbin/wifi >/dev/null 2>/dev/null;" - exec_cmd_in_sh(cmd) -end - -function fork_restart_network() - local cmd = "/etc/init.d/network restart" - exec_cmd_in_sh(cmd) -end - -function get_lan_ip() - local uci = require("luci.model.uci").cursor() - local lan = uci:get_all("network", "lan") - return lan.ipaddr -end - ---[[ ---function: 定时wifi开关 ---author: rh_Jameson ---]]-- ---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: 定时wifi开关shell形式 ---author: rh_Jameson -function smart_wifi_shutdown() - local wnet = 'mt7628.network1' - local info = {} - - --get para - --close_time = luci.http.formvalue("close_time") - --open_time = luci.http.formvalue("open_time") - - --test normal - close_time = os.time() + 5 - restart_time = os.time() + 10 - - --test exception - --close_time = os.time() - 5 - --restart_time = os.time() - 10 - - --para err manage - if close_time < os.time() or restart_time < close_time then - info["SUCCESS"] = false - else - info["SUCCESS"] = true - end - fork_smart_wifi_shutdown(wnet, close_time, restart_time) - luci.http.write_json(info) -end - - ---[[ ---function: 定时wifi开关 ---author: rh_Jameson -function smart_wifi_shutdown() - local wnet = 'mt7628.network1' - local table = {} - - --get para - --local close_time = luci.http.formvalue("close_time") - --local open_time = luci.http.formvalue("open_time") - - --test normal - --local close_time = os.time() + 5 - --local restart_time = os.time() + 10 - - --test exception - local close_time = os.time() - 5 - local restart_time = os.time() - 10 - - --para err manage - if close_time < os.time() or restart_time < close_time then - table["err"] = true - luci.http.write_json(table) - return - end - --do close - while true do - if os.time() ~= close_time then - posix.sleep(1) - else - wifi_shutdown(wnet) - table["close"] = true - luci.http.write_json(table) - break - end - end - - --do restart - while true do - if os.time() ~= restart_time then - posix.sleep(1) - else - wifi_reconnect(wnet) - table["restart"] = true - luci.http.write_json(table) - break - end - end -end - ---]]-- - - - - -function macFormat(mac) - if mac then - return string.upper(string.gsub(mac, "-", ":")) - else - return "" - end -end - -function getAllWifiConnetDeviceDict() - local result = {} - for index = 1,2 do - local wifilist = getWifiConnectDeviceList(index) - for _, mactime in pairs(wifilist) do - local item = {} - item["wifiIndex"] = index - item["time"] = mactime["time"] - item["rx"] = mactime["rx"] - item["tx"] = mactime["tx"] - result[macFormat(mactime["mac"])] = item - end - end - return result -end - -function getWifiConnectDeviceList(wifiIndex) - local dlist = {} - local macfile = nil - local uci = require("luci.model.uci").cursor() - if tonumber(wifiIndex) == 1 then - local disable_2g = uci.get("wireless", "mt7628iface", "disabled") - if "1" ~= disable_2g then - local cmd = [[iwpriv ra0 get_mac_table]] - macfile = io.popen(cmd) - end - elseif tonumber(wifiIndex) == 2 then - local disable_5g = uci.get("wireless", "mt7610eiface", "disabled") - if "1" ~= disable_5g then - local cmd = [[iwpriv rai0 get_mac_table]] - macfile = io.popen(cmd) - end - end - local tmplinenumber = 0 - if nil ~= macfile then - for line in macfile:lines() do - if 0 ~= tmplinenumber and "" ~= line then - local item = {} - local mactime = strsplit(line, " ") - item["mac"] = macFormat(mactime[1]) - item["time"] = mactime[2] - item["rx"] = mactime[3] - item["tx"] = mactime[4] - table.insert(dlist,item) - end - tmplinenumber = tmplinenumber + 1 - end - end - return dlist -end - -function getDHCPLists() - local NixioFs = require("nixio.fs") - local LuciUci = require("luci.model.uci") - local uci = LuciUci.cursor() - local result = {} - local leasefile = "/var/dhcp.leases" - uci:foreach("dhcp", "dnsmasq", - function(s) - if s.leasefile and NixioFs.access(s.leasefile) then - leasefile = s.leasefile - return false - end - end) - local dhcp = io.open(leasefile, "r") - if dhcp then - for line in dhcp:lines() do - if line then - local ts, mac, ip, name = line:match("^(%d+) (%S+) (%S+) (%S+)") - if name == "*" then - name = "" - end - if ts and mac and ip and name then - result[#result+1] = { - mac = macFormat(mac), - ip = ip, - name = name, - sp = 0 - } - end - end - end - dhcp:close() - return result - else - return false - end -end - -function getDHCPDict() - local dhcpDict = {} - local dhcpList = getDHCPLists() - for _,value in ipairs(dhcpList) do - dhcpDict[value.mac] = value - end - return dhcpDict -end - -function getDHCPIpDicts() - local dhcpDict = {} - local dhcpList = getDHCPLists() - for _,value in ipairs(dhcpList) do - dhcpDict[value.ip] = value - end - return dhcpDict -end - -function getDeviceInfoFromDB() - local result = {} - local deviceList = dbfs.fetchAllDeviceInfo() - if #deviceList > 0 then - for _, device in ipairs(deviceList) do - result[device.mac] = device - end - end - return result -end - -function is_device_online(ip) - local lu = require("luci.util") - local cmd = "ping -W 2 -c 1 " .. ip .. " > /dev/null ;echo -n $?" - local pingresult = lu.exec(cmd) - - local res = nil - if pingresult == "0" then - res = true - else - res = false - - end - - return res -end - -function get_connect_device_list_router() - local devicelist = {} - dbfs.init_arp_table() - local dbarp = dbfs.fetch_all_arp() - - local deviceDBDict = getDeviceInfoFromDB() - local dhcpDeviceDict = getDHCPDict() - local blacklist0 = dbfs.fetch_all_deny_mac() - local wifiDeviceDict = getAllWifiConnetDeviceDict() - - local cmd = [[cat /proc/net/arp |grep br-lan|awk '{print $1","$4}']] - local ipmacs = {} - local devs = lue(cmd) - if devs ~= "" then - local ipmacstr = strsplit(devs, '\n') - ipmacstr[#ipmacstr] = nil - for k, v in pairs(ipmacstr) do - local ipmac = strsplit(v, ',') - ipmacs[string.upper(ipmac[2])] = ipmac - end - end - - for k, v in pairs(dbarp) do - local item = {} - local mac = string.upper(v["mac"]) - if "00:00:00:00:00:00" ~= mac then - local devflag = false - local im = ipmacs[mac] - local wf = v["wifi"] - if wf == 0 then - item["type"] = "wire" - elseif wf == 1 then - item["type"] = "2.4G" - elseif wf == 2 then - item["type"] = "5G" - end - if nil ~= im then - item["ip"] = im[1] - item["mac"] = string.upper(im[2]) - else - item["ip"] = v["ip"] - item["mac"] = mac - end - - local deviceDB = deviceDBDict[mac] - local dhcpinfo = dhcpDeviceDict[mac] - if deviceDB ~= nil then - item["devicename"] = deviceDB.orgname - if deviceDB.devicename ~= '' then - item["devicename"] = deviceDB.devicename - end - elseif dhcpinfo ~= nil then - item["devicename"] = dhcpinfo.name - dbfs.saveDeviceInfo(mac, dhcpinfo.name, "", dhcpinfo.ip) - else - item["devicename"] = "unknown" - end - - local isblack = false - if nil ~= blacklist0 then - for k, v in pairs(blacklist0) do - if v.mac == mac then - isblack = true - end - end - end - if isblack == false then - item["enable"] = true - else - item["enable"] = false - end - - local wifi = wifiDeviceDict[mac] - - item["online"] = false - if wf == 0 and nil ~= im then - item["online"] = true - end - if wifi ~= nil then - item["online"] = true - if wifi.wifiIndex == 1 then - item["type"] = "2.4G" - elseif wifi.wifiIndex == 2 then - item["type"] = "5G" - end - end - if nil == item["type"] or false == item["online"] then - item["type"] = "unknown" - end - table.insert(devicelist,item) - end - end - return devicelist -end - -function get_connect_device_list() - local LuciNetwork = require("luci.model.network").init() - local lanNetwork = LuciNetwork:get_network("lan") - local apc = lanNetwork:get_option_value("apclient") - local devicelist = {} - if nil == apc or "" == apc then - --mode router - devicelist = get_connect_device_list_router() - else - --mode apclient - if "mt7628" == apc then - - elseif "mt7610e" == apc then - - end - devicelist = get_connect_device_list_router() - end - return devicelist -end - -function ww_get_connect_device_list() - local result = get_connect_device_list() - return result -end - -function nw_get_connect_device_list() - luci.http.prepare_content("application/json") - local result = get_connect_device_list() - luci.http.write_json(result) -end - -function nw_set_device_name() - local mac = luci.http.formvalue("mac") - local devicename = luci.http.formvalue("devicename") - set_device_name(mac,devicename) -end - -function set_device_name(mac,devicename) - local code = 0 - local deviceList = {} - - if is_str_nil(mac) or is_str_nil(devicename) then - code = 1502 - else - code = save_device_name(mac,devicename) - end - return code -end - -function save_device_name(mac,name) - local code = 0 - local code = dbfs.updateDeviceNickname(macFormat(mac),name) - if code == 0 then - return true - else - return false - end -end - -function set_wan_switch(mac, mode, enable) - local result = {} - local code = false - if is_str_nil(mac) then - return - else - mac = macFormat(mac) - enable = tonumber(enable) - end - - local dbdenymac = dbfs.fetch_all_deny_mac() - local macstr = "" - local deny = false - if enable == 0 then - if nil == dbdenymac then - dbfs.add_deny_mac(mac) - macstr = mac - else - if #dbdenymac >= 60 then - return "black person reach max" - end - for _, macaddr in ipairs(dbdenymac) do - if mac == macaddr.mac then - return "same black" - else - macstr = macstr.." "..macaddr.mac - end - end - dbfs.add_deny_mac(mac) - macstr = macstr.." "..mac - end - else - if nil == dbdenymac then - return - end - for _, macaddr in ipairs(dbdenymac) do - if mac == macaddr.mac then - dbfs.delete_deny_mac(mac) - if #dbdenymac == 1 then - deny = true - end - else - macstr = macstr.." "..macaddr.mac - end - end - end - local cmd = [[wireless-ban.sh ]] - if deny == true then - cmd = cmd.."none" - else - cmd = cmd.."deny "..macstr - end - exec_cmd_in_sh(cmd) - code = true - result["result"] = code - - return result -end - -function nw_set_wan_switch() - local result = {} - local code = false - local mac = luci.http.formvalue("mac") - local mode = luci.http.formvalue("mode") - local enable = luci.http.formvalue("enable") - - code = set_wan_switch(mac,mode,enable) - result["result"] = code - luci.http.write_json(result) -end - -function getNetConnect(ip) - local sys = require "luci.sys" - local res = {} - res["bytes"] = 0 - local conn = sys.net.conntrack() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, conn) - for _, value in pairs(conn) do - if value.src == ip then - res["bytes"] = value.bytes + res["bytes"] - end - end - return res -end - -function get_net_device() - local ntm = require "luci.model.network".init() - local dev - local devices = { } - for _, dev in luci.util.vspairs(luci.sys.net.devices()) do - if dev ~= "lo" and not ntm:ignore_interface(dev) then - devices[#devices+1] = dev - end - end - local curdev = luci.dispatcher.context.requestpath - curdev = curdev[#curdev] ~= "bandwidth" and curdev[#curdev] or devices[1] - luci.http.write_json(devices) -end - -function nw_check_sys_password() - local password = luci.http.formvalue("password") - check_sys_password(password) -end - -function check_sys_password(password) - local result={} - if not is_str_nil(password) then - local check = check_sys_pwd(password) - if check then - code = true - else - code = false - end - end - result["result"] = code - luci.http.write_json(result) -end - -function get_wan_type() - local LuciNetwork = require("luci.model.network").init() - local lanNetwork = LuciNetwork:get_network("lan") - local wanNetwork = LuciNetwork:get_network("wan") - local wanDetails = {} - if wanNetwork and lanNetwork then - local apc = lanNetwork:get_option_value("apclient") - if nil ~= apc and "" ~= apc then - wanDetails["type"] = "apclient" - local uci = require("luci.model.uci").cursor() - local ssid = uci.get("wireless", apc, "apclissid") - wanDetails["ssid"] = ssid - else - local wanType = wanNetwork:proto() - - if wanType == "static" then - wanDetails["ipaddr"] = wanNetwork:get_option_value("ipaddr") - wanDetails["netmask"] = wanNetwork:get_option_value("netmask") - wanDetails["gateway"] = wanNetwork:get_option_value("gateway") - elseif wanType == "pppoe" then - wanDetails["type"] = "pppoe" - wanDetails["pppoeName"] = wanNetwork:get_option_value("username") - wanDetails["pppoePwd"] = wanNetwork:get_option_value("password") - elseif wanType == "dhcp" then - wanDetails["type"] = "dhcp" - wanDetails["pppoeName"] = "" - wanDetails["pppoePwd"] = "" - end - end - return wanDetails - else - return nil - end -end - -function ww_get_wan_type() - local result = get_wan_type() - return data_to_json(result) -end - -function nw_get_wan_type() - local result = get_wan_type() - luci.http.write_json(result) -end -function nw_set_wan_type() - local wan_type = luci.http.formvalue("type") - if "apclient" == wan_type then - local channel = luci.http.formvalue("channel") - local ssid = luci.http.formvalue("ssid") - local mac = luci.http.formvalue("mac") - local sec = luci.http.formvalue("sec") - local extch = luci.http.formvalue("extch") - local wl_type_val = luci.http.formvalue("aptype") - local key = luci.http.formvalue("key") - set_ap_client(channel, ssid, mac, sec, extch, wl_type_val, key) - else - local pppoe_name = luci.http.formvalue("pppoeName") - local pppoe_pwd = luci.http.formvalue("pppoePwd") - set_wan_type(wan_type, pppoe_name, pppoe_pwd) - end -end - -function set_wan_type(wan_type, pppoe_name, pppoe_pwd) - local result = {} - local code = true - local needRestartWifi = false - if not is_str_nil(wan_type) then - local succeed - if wan_type == "pppoe" and not is_str_nil(pppoe_name) and not is_str_nil(pppoe_pwd) then - succeed = setWanPPPoE(pppoe_name, pppoe_pwd) - elseif wan_type == "dhcp" then - succeed = setWanDHCP() - end - if not succeed then - code = false - else - cancelapclient() - needRestartWifi = true - end - end - result["result"] = code - local dbssid = dbfs.fetch_ssid() - if nil ~= dbssid then - for k, v in pairs(dbssid) do - result["ssid"] = v.ssid24 - end - end - local macaddrcmd = "eth_mac r wl0" - local macaddr = lue(macaddrcmd) - if macaddr ~= "" then - local ipmacstr = strsplit(macaddr, '\n') - ipmacstr[#ipmacstr] = nil - for k, v in pairs(ipmacstr) do - result["mac"] = v - end - end - luci.http.write_json(result) - - if needRestartWifi then - cmd = [[sleep 1;apcli_connect.sh restart &]] - exec_cmd_in_sh(cmd) - --fork_restart_network() - end - luci.http.close() -end - -function set_ap_client(channel, ssid, mac, sec, extch, wl_type_val, key) - local sec_alg = "TKIP" - if string.find(sec, "AES") then - sec_alg = "AES" - end - if string.find(sec, "WPA2") then - sec = "WPA2PSK" - else - if string.find(sec, "WPA") then - sec = "WPA1PSK" - else - sec = "WEP" - end - end - local wl_type = "ra0" - if wl_type_val == "5G" then - wl_type = "rai0" - end - local cmd = [[apcli_connect.sh ]]..wl_type.." "..channel.." "..ssid.." " - cmd = cmd..sec.." "..sec_alg.." "..key - lue(cmd) - require "MZLog".log(3, cmd) - local ret = {} - ret["result"] = true - local ssid5,ssid2 = get_wifi_ssids() - local macaddrcmd = "" - if wl_type_val == "2.4G" then - ret["ssid"] = ssid2 - macaddrcmd = "eth_mac r wl0" - else - ret["ssid"] = ssid5 - macaddrcmd = "eth_mac r wl1" - end - local macaddr = lue(macaddrcmd) - if macaddr ~= "" then - local ipmacstr = strsplit(macaddr, '\n') - ipmacstr[#ipmacstr] = nil - for k, v in pairs(ipmacstr) do - ret["mac"] = v - end - end - luci.http.prepare_content("application/json") - luci.http.write_json(ret) - local cmd = [[sleep 1;apcli_connect.sh restart &]] - exec_cmd_in_sh(cmd) - luci.http.close() -end - -function cancelapclient() - local LuciNetwork = require("luci.model.network").init() - local lanNetwork = LuciNetwork:get_network("lan") - local apc = lanNetwork:get_option_value("apclient") - if nil ~= apc then - local dbssid = dbfs.fetch_ssid() - local ssid_2g = "" - local ssid_5g = "" - if nil ~= dbssid then - for k, v in pairs(dbssid) do - ssid_2g = v.ssid24 - ssid_5g = v.ssid5 - end - end - local cmd = [[apcli_connect.sh disable]] - if "" ~= ssid_2g and "" ~= ssid_5g then - cmd = cmd.." "..ssid_2g.." "..ssid_5g - end - lue(cmd) - end -end - -function setWanPPPoE(name, password) - local LuciNetwork = require("luci.model.network").init() - local uci = require("luci.model.uci").cursor() - local iface = "wan" - local ifname = getWanEth() - local oldconf = uci:get_all("network", "wan") or {} - local wanrestart = true - if oldconf.username == name and oldconf.password == password then - wanrestart = false - end - local wanNet = LuciNetwork:del_network(iface) - local mtuvalue = 1480 - wanNet = LuciNetwork:add_network( - iface, { - proto ="pppoe", - ifname = ifname, - username = name, - password = password, - mtu = mtuvalue - }) - if wanNet then - LuciNetwork:save("network") - LuciNetwork:commit("network") - if wanrestart then - wanRestart() - end - return true - else - return false - end -end - -function setWanDHCP() - local LuciNetwork = require("luci.model.network").init() - local uci = require("luci.model.uci").cursor() - local oldconf = uci:get_all("network", "wan") or {} - local iface = "wan" - local ifname = getWanEth() - local wanrestart = true - - local wanNet = LuciNetwork:del_network(iface) - if oldconf.proto == "dhcp" then - wanrestart = false - end - local network = { - proto = "dhcp", - ifname = ifname - } - wanNet = LuciNetwork:add_network(iface, network) - if wanNet then - LuciNetwork:save("network") - LuciNetwork:commit("network") - if wanrestart then - wanRestart() - end - return true - else - return false - end -end - -function check_sys_pwd(oldPassword) - local LuciSys = require("luci.sys") - return LuciSys.user.checkpasswd("root", oldPassword) -end - -function getWanEth() - local LuciNetwork = require("luci.model.network").init() - local wanNetwork = LuciNetwork:get_network("wan") - return wanNetwork:get_option_value("ifname") -end - -function wanRestart() - local LuciUtil = require("luci.util") - LuciUtil.exec("env -i /sbin/ifup wan") -end - -function netspeed_channel(cmd) - local speed_table = {} - local speed_file = io.popen(cmd) - for line in speed_file:lines() do - table.insert(speed_table, line) - end - speed_file:close() - - local rx = 0 - local tx = 0 - local speed, tb, rxb, txb - local n = 0 - for k, v in ipairs(speed_table) do - speed = strsplit(v, ',') - if (k == 1) then - tb = tonumber(speed[1]) - rxb = tonumber(speed[3]) - txb = tonumber(speed[2]) - else - n = n + 1 - local tmp - local td - tmp = tonumber(speed[1]) - td = tmp - tb - tb = tmp - - tmp = tonumber(speed[3]) - rx = rx + (tmp - rxb) / td - rxb = tmp - - tmp = tonumber(speed[2]) - tx = tx + (tmp - txb) / td - txb = tmp - end - end - rx = string.format("%6.2f", rx/n) - tx = string.format("%6.2f", tx/n) - return rx, tx -end - -function real_time_net_speed() - local res = {} - --local cmd = [[luci-bwc -i eth0.2|tail -n 5|sed -e 's#.*\[\s*\(.*\)\s*\].*#\1#']] - local uci = require("luci.model.uci").cursor() - local apclient = uci.get("network", "lan", "apclient") - - local cmd = nil - local rx = 0 - local tx = 0 - if nil == apclient then - cmd = [[luci-bwc -i eth0.2 |tail -n 5 |sed -e 's#.*\[\s*\(.*\)\s*\].*#\1#']] - rx, tx = netspeed_channel(cmd) - else - cmd = [[luci-bwc -i eth0.1 |tail -n 5 |sed -e 's#.*\[\s*\(.*\)\s*\].*#\1#']] - rx, tx = netspeed_channel(cmd) - cmd = [[luci-bwc -i ra0 |tail -n 5 |sed -e 's#.*\[\s*\(.*\)\s*\].*#\1#']] - local tmprx, tmptx = netspeed_channel(cmd) - rx = rx + tmprx - tx = tx + tmptx - cmd = [[luci-bwc -i rai0 |tail -n 5 |sed -e 's#.*\[\s*\(.*\)\s*\].*#\1#']] - tmprx, tmptx = netspeed_channel(cmd) - rx = rx + tmprx - tx = tx + tmptx - end - - res["rx"] = rx - res["tx"] = tx - - return res -end - -function get_device_details(mac) - dbfs.change_maclist_table() - local item = {} - mac = string.upper(mac) - local deviceDBDict = getDeviceInfoFromDB() - local dhcpDeviceDict = getDHCPDict() - local blacklist0 = dbfs.fetch_all_deny_mac() - local wifiDeviceDict = getAllWifiConnetDeviceDict() - - local cmd = [[cat /proc/net/arp |grep br-lan|awk '{print $1","$4}']] - local ipmacs = {} - local devs = lue(cmd) - if devs ~= "" then - local ipmacstr = strsplit(devs, '\n') - ipmacstr[#ipmacstr] = nil - for k, v in pairs(ipmacstr) do - local ipmac = strsplit(v, ',') - ipmacs[string.upper(ipmac[2])] = ipmac - end - end - - item["diskaccess"] = false - item["speed"] = 0 - item["upload"] = 0 - item["download"] = 0 - item["time"] = 0 - - local isblack = false - if nil ~= blacklist0 then - for k, v in pairs(blacklist0) do - if v.mac == mac then - isblack = true - end - end - end - if isblack == false then - item["enable"] = true - else - item["enable"] = false - end - - local dbarp = dbfs.fetch_arp(mac) - if nil ~= dbarp then - for k, v in pairs(dbarp) do - local im = ipmacs[mac] - local wf = v["wifi"] - if wf == 0 then - item["type"] = "wire" - elseif wf == 1 then - item["type"] = "2.4G" - elseif wf == 2 then - item["type"] = "5G" - end - if nil ~= im then - item["ip"] = im[1] - item["mac"] = string.upper(im[2]) - else - item["ip"] = v["ip"] - item["mac"] = mac - end - - local deviceDB = deviceDBDict[mac] - local dhcpinfo = dhcpDeviceDict[mac] - if deviceDB ~= nil then - item["devicename"] = deviceDB.orgname - if deviceDB.devicename ~= '' then - item["devicename"] = deviceDB.devicename - end - else - item["devicename"] = dhcpinfo.name - dbfs.saveDeviceInfo(mac, dhcpinfo.name, "", dhcpinfo.ip) - end - - local wifi = wifiDeviceDict[mac] - - item["online"] = false - if wf == 0 and nil ~= im then - item["online"] = true - end - if wifi ~= nil then - item["online"] = true - local time = wifi.time - item["time"] = time - local rx = wifi.rx - local tx = wifi.tx - item["upload"] = tx - item["download"] = rx - if wifi.wifiIndex == 1 then - item["type"] = "2.4G" - elseif wifi.wifiIndex == 2 then - item["type"] = "5G" - end - end - if nil == item["type"] or false == item["online"] then - item["type"] = "unknown" - end - end - end - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, item) - require "MZLog".log(3, debug.getinfo(1).currentline) - - return item -end - -function nw_get_device_details() - local mac = luci.http.formvalue("mac") - local res = get_device_details(mac) - luci.http.write_json(res) -end - -function ww_get_device_details(mac) - local res = get_device_details(mac) - return res -end - -function get_wireless_channel() - local uci = require("luci.model.uci").cursor() - local channel = uci.get("wireless", "mt7628", "channel") - local bw = uci.get("wireless", "mt7628", "bw") - local ret = {} - ret["channel"] = channel - ret["extch"] = bw - return ret -end - -function nw_get_wireless_channel() - local ret = get_wireless_channel() - luci.http.write_json(ret) -end - -function ww_get_wireless_channel() - local ret = get_wireless_channel() - return cjson.encode(ret) -end - -function set_wireless_channel(channel, extch) - local res = false - local uci = require("luci.model.uci").cursor() - local c = tonumber(channel) - - if c >= 0 and c <= 13 then - res = uci.set("wireless", "mt7628", "channel", c) - if extch == "1" or extch == "0" then - res = uci.set("wireless", "mt7628", "bw", extch) - end - end - uci.commit("wireless") - fork_restart_wifi() - return res -end - -function nw_set_wireless_channel(channel, extch) - local channel = luci.http.formvalue("channel") - local extch = luci.http.formvalue("extch") - local res = set_wireless_channel(channel, extch) - local ret = {} - ret["result"] = res - luci.http.write_json(ret) -end - -function ww_set_wireless_channel(channel, extch) - local res = set_wireless_channel(channel, extch) - local ret = {} - ret["result"] = res - return ret -end - -function is_wan_connected() - local lu = require("luci.util") - local cmd = "ping -W 2 -c 1 www.baidu.com > /dev/null ;echo -n $?" - local pingresult = lu.exec(cmd) - - local res = {} - if pingresult == "0" then - res["result"] = true - else - res["result"] = false - - end - - return res -end - -function set_bluetooth(id, status) - require "MZLog".log(3, debug.getinfo(1).currentline) - local res = {} - - if status == "open" then - local cmd = "/root/spi_open" .. id - lue(cmd) - res["result"] = "open" - elseif status == "close" then - local cmd = "/root/spi_close" .. id - lue(cmd) - res["result"] = "close" - end - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return res -end - -function get_bluetooth_info() - --local value = luci.http.formvalue("data") - local value = "010101010101" - local ret = {} - require "MZLog".log(3, debug.getinfo(1).currentline) - local types = string.format("%d", "0x" .. string.sub(value, 1, 2)) - --[[ - if types == "00" then - end - ]] - local id = string.format("%d", "0x" .. string.sub(value, 3, 4)) - local status = string.format("%d", "0x" .. string.sub(value, 5, 6)) - local temp = string.format("%d", "0x" .. string.sub(value, 7, 8)) - local rh = string.format("%d", "0x" .. string.sub(value, 9, 10)) - local light = string.format("%d", "0x" .. string.sub(value, 11, 12)) - - ret["type"] = types - ret["id"] = id - ret["status"] = status - ret["temp"] = temp - ret["rh"] = rh - ret["light"] = light - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, ret) - return ret -end - -function nw_set_bluetooth() - require "MZLog".log(3, debug.getinfo(1).currentline) - local id = luci.http.formvalue("id") - local status = luci.http.formvalue("status") - local res = set_bluetooth(id, status) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function nw_get_bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - local res = get_bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_set_bluetooth() - require "MZLog".log(3, debug.getinfo(1).currentline) - local res = set_bluetooth() - require "MZLog".log(3, debug.getinfo(1).currentline) - return res -end - -function ww_get_bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - local res = get_bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - return res -end - ------------------------- bluetooth -------------------- - ------------------------ receive data -------------------- -function bluetooth_info() - dbfs.initBluetoothTable() - local value = luci.http.formvalue("data") - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, value) - local ret = {} - local types = string.sub(value, 1, 2) - - if types == "00" then - local id = string.sub(value, 3, 4) - local status = string.format("%d", "0x" .. string.sub(value, 5, 6)) - local temp1 = string.sub(value, 7, 8) - local temp2 = string.sub(value, 9, 10) - local temp = temp2..temp1 - temp = string.format("%d", "0x" .. temp) - local rh1 = string.sub(value, 11, 12) - local rh2 = string.sub(value, 13, 14) - local rh = rh2..rh1 - rh = string.format("%d", "0x" .. rh) - local light1 = string.sub(value, 15, 16) - local light2 = string.sub(value, 17, 18) - local light = light2..light1 - light = string.format("%d", "0x" .. light) - local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/"..mac.."0" - - ret["mac"] = mac - ret["id"] = id - if status == "1" then - ret["onoff"] = "on" - else - ret["onoff"] = "off" - end - local timer_id = "" - local flag = "" - local start = "" - local ends = "" - local fd = io.open(TMP, "r") - - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - timer_id = res.timerId - flag = res.flag - start = res.start - ends = res.ends - end - - ret["timerId"] = timer_id - ret["flag"] = flag - ret["start"] = start - ret["ends"] = ends - ret["temp"] = temp - ret["hemi"] = rh - ret["light"] = light - ret["time"] = os.time() - - local result = data_to_json(ret) - --[[ - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, id) - require "MZLog".log(3, result) - require "MZLog".log(3, ret) - ]] - local fd = assert(io.open(TMP, "w")) - fd:write(result) - fd:close() - - elseif types == "01" then - local id = string.sub(value, 3, 4) - local voltage1 = string.sub(value, 5, 6) - local voltage2 = string.sub(value, 7, 8) - local voltage = voltage2..voltage1 - voltage = string.format("%d", "0x" .. voltage) - local electricity1 = string.format("%d", "0x" .. string.sub(value, 9, 10)) - local electricity2 = string.format("%d", "0x" .. string.sub(value, 11, 12)) - local electricity = electricity2..electricity1 - electricity = string.format("%d", "0x" .. electricity) - local power1 = string.sub(value, 13, 14) - local power2 = string.sub(value, 15, 16) - local power = power2..power1 - power = string.format("%d", "0x" .. power) - local electric1 = string.sub(value, 17, 18) - local electric2 = string.sub(value, 19, 20) - local electric = electric2..electric1 - electric = string.format("%d", "0x" .. electric) - local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/"..mac.."1" - local timer_id = "" - local fd = io.open(TMP, "r") - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - timer_id = res.timerId - end - - ret["timerId"] = timer_id - ret["mac"] = mac - ret["id"] = id - ret["voltage"] = voltage - ret["current"] = electricity - ret["power"] = power - ret["energy"] = electric - - local result = data_to_json(ret) - local fd = assert(io.open(TMP, "w")) - fd:write(result) - fd:close() - - elseif types == "02" then - require "MZLog".log(3, debug.getinfo(1).currentline) - local id = string.sub(value, 3, 4) - local TYPE = string.sub(value, 5, 6) - local mac1 = string.sub(value, 7, 8) - local mac2 = string.sub(value, 9, 10) - local mac3 = string.sub(value, 11, 12) - local mac4 = string.sub(value, 13, 14) - local mac5 = string.sub(value, 15, 16) - local mac6 = string.sub(value, 17, 18) - local mac = mac6..mac5..mac4..mac3..mac2..mac1 - - mac = string.upper(mac) - local ID = "" - local res = dbfs.fetchBluetoothDevice(mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, #res) - require "MZLog".log(3, res) - if #res > 0 then - for k, v in pairs(res) do - ID = v.id - end - end - if id ~= ID then - dbfs.updateBluetoothDevice(id, "", "", "", mac) - end - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - res["time"] = os.time() - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - require "MZLog".log(3, id) - require "MZLog".log(3, mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - - elseif types == "09" then - local deviceType = string.sub(value, 3, 4) - local mac1 = string.sub(value, 5, 6) - local mac2 = string.sub(value, 7, 8) - local mac3 = string.sub(value, 9, 10) - local mac4 = string.sub(value, 11, 12) - local mac5 = string.sub(value, 13, 14) - local mac6 = string.sub(value, 15, 16) - local mac = mac6..mac5..mac4..mac3..mac2..mac1 - mac = string.upper(mac) - - local res = dbfs.fetchBluetoothDevice(mac) - local ret = nil - local id = nil - if #res > 0 then - for k, v in pairs(res) do - ret = v.mac - id = v.id - end - end - if id then - dbfs.updateBluetoothDevice("", "", "", "", mac) - end - if ret == nil then - dbfs.addBluetoothDevice("", mac, "", "", deviceType, "") - local TMP = "/tmp/"..mac - local fd = io.open(TMP, "w") - fd:write(os.time()) - fd:close() - else - local TMP = "/tmp/"..mac - local fd = io.open(TMP, "w") - fd:write(os.time()) - fd:close() - end - - elseif types == "04" then - local data = string.format("%d", "0x" .. string.sub(value, 3, 4)) - ret["data"] = data - - elseif types == "03" then - require "MZLog".log(3, debug.getinfo(1).currentline) - local id = string.sub(value, 3, 4) - local flag = string.sub(value, 5, 6) - local timer_id = string.sub(value, 7, 8) - local start = string.sub(value, 9, 16) - local ends = string.sub(value, 17, 24) - local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/"..mac.."1" - local fd = io.open(TMP, "r") - - if fd then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, timer_id) - require "MZLog".log(3, flag) - local res = fd:read() - res = cjson.decode(res) - if timer_id == res["timerId"] then - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - local res = fd:read() - res = cjson.decode(res) - res["flag"] = flag - res["timerId"] = timer_id - res["start"] = start - res["ends"] = ends - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - end - - elseif types == "06" then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - local id = string.sub(value, 3, 4) - local mac = dbfs.getBluetoothDevice(id) - local len = tonumber(dbfs.getBleDeviceNameLength(id)) - local str = string.sub(value, 5, len + 4) - --local res = {} - --[[ - for i = 1, #str, 2 do - res[#res + 1] = (tonumber(string.format("%d", "0x"..string.sub(str, i, i+1)))) - end - ]] - local device_name = str - --[[ - if #res == 1 then - device_name = string.char(res[1]) - elseif #res == 2 then - device_name = string.char(res[1], res[2]) - elseif #res == 3 then - device_name = string.char(res[1], res[2], res[3]) - elseif #res == 4 then - device_name = string.char(res[1], res[2], res[3], res[4]) - elseif #res == 5 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5]) - elseif #res == 6 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6]) - elseif #res == 7 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6], res[7]) - elseif #res == 8 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6], res[7], res[8]) - elseif #res == 9 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6], res[7], res[8], res[9]) - elseif #res == 10 then - device_name = string.char(res[1], res[2], res[3], res[4], res[5], res[6], res[7], res[8], res[9], res[10]) - end - ]] - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, str) - require "MZLog".log(3, device_name) - dbfs.updateBluetoothDevice(id, "", device_name, len, mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - - elseif types == "07" then - local data = string.format("%d", "0x" .. string.sub(value, 3, 4)) - ret["data"] = data - - elseif types == "0b" then - local key_ack = string.sub(value, 3, 4) - local TMP = "/tmp/0b0b" - local fd = io.open(TMP, "w") - fd:write(key_ack) - fd:close() - - elseif types == "0c" then - local id = string.sub(value, 3, 4) - local status = string.sub(value, 5, 6) - local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - local res = nil - require "MZLog".log(3, debug.getinfo(1).currentline) - - if fd then - res = fd:read() - fd:close() - res = cjson.decode(res) - if status == "01" then - res["onoff"] = "on" - else - res["onoff"] = "off" - end - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - require "MZLog".log(3, res) - - elseif types == "0d" then - local id = string.sub(value, 3, 4) - local led_light = string.sub(value, 5, 6) - local temp1 = string.sub(value, 7, 8) - local temp2 = string.sub(value, 9, 10) - led_light = string.format("%d", "0x" .. led_light) - local led_temp = temp2..temp1 - temp = string.format("%d", "0x" .. temp) - - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - local res = nil - require "MZLog".log(3, debug.getinfo(1).currentline) - - if fd then - res = fd:read() - fd:close() - res = cjson.decode(res) - res["led_light"] = led_light - res["led_temp"] = led_temp - - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - - elseif types == "0e" then - local id = string.sub(value, 3, 4) - local wait_time = string.format("%d", "0x" .. string.sub(value, 5, 6)) - --local mac = dbfs.getBluetoothDevice(id) - local TMP = "/tmp/0e0e" - local fd = io.open(TMP, "w") - fd:write(wait_time) - fd:close() - - elseif types == "10" then - local mac1 = string.sub(value, 3, 4) - local mac2 = string.sub(value, 5, 6) - local mac3 = string.sub(value, 7, 8) - local mac4 = string.sub(value, 9, 10) - local mac5 = string.sub(value, 11, 12) - local mac6 = string.sub(value, 13, 14) - local mac = mac6..mac5..mac4..mac3..mac2..mac1 - mac = string.upper(mac) - - local res = dbfs.fetchBluetoothDevice(mac) - if #res == 0 then - dbfs.addBluetoothDevice("", mac, "0123", "", "", "") - end - --[[ - if ret == nil then - dbfs.addBluetoothDevice("", mac, "", "", deviceType, "") - local TMP = "/tmp/"..mac - local fd = io.open(TMP, "w") - fd:write(os.time()) - fd:close() - else - local TMP = "/tmp/"..mac - local fd = io.open(TMP, "w") - ]] - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, ret) - return ret -end - -function nw_get_bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - local res = bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_get_bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - local res = bluetooth_info() - require "MZLog".log(3, debug.getinfo(1).currentline) - return res -end - ------------------------ scan_ble_device -------------------- -function scan_ble_switch(status) - local res = {} - if status == "on" then - local cmd = "bt_daemon -s ".."16".." 255" - lue(cmd) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, cmd) - posix.sleep(1) - res["result"] = true - elseif status == "off" then - local cmd = "bt_daemon -s ".."18".." 255" - lue(cmd) - posix.sleep(1) - res["result"] = false - end - return res -end - -function nw_scan_ble_switch() - local status = luci.http.formvalue("status") - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, status) - local res = scan_ble_switch(status) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_scan_ble_switch(status) - local res = scan_ble_switch(status) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ get_ble_device_list -------------------- -function get_ble_device_list() - local res = dbfs.fetchAllBluetoothDevice() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, res) - local result = {} - if #res > 0 then - for k, v in pairs(res) do - local TMP = "/tmp/"..v.mac - local fd = io.open(TMP, "r") - if fd then - local time = fd:read() - fd:close() - if tonumber(os.time()) - tonumber(time) < 5 then - table.insert(result, v) - end - end - end - end - return result -end - -function nw_get_ble_device_list() - local res = get_ble_device_list() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if #res == 0 then - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write("[]") - else - luci.http.write_json(res) - end -end - -function ww_get_ble_device_list() - local res = get_ble_device_list() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if #res == 0 then - return "[]" - else - return cjson.encode(res) - end -end - ------------------------ add_ble_mesh_device -------------------- -function is_receive_id(mac) - local id = "" - local ret = dbfs.fetchBluetoothDevice(mac) - for k, v in pairs(ret) do - id = v.id - end - return id -end - -function add_ble_mesh_device(mac) - local res = {} - local id = "" - local mac1 = string.format("%d", "0x" .. string.sub(mac, 1, 2)) - local mac2 = string.format("%d", "0x" .. string.sub(mac, 3, 4)) - local mac3 = string.format("%d", "0x" .. string.sub(mac, 5, 6)) - local mac4 = string.format("%d", "0x" .. string.sub(mac, 7, 8)) - local mac5 = string.format("%d", "0x" .. string.sub(mac, 9, 10)) - local mac6 = string.format("%d", "0x" .. string.sub(mac, 11, 12)) - local macs = mac6.." "..mac5.." "..mac4.." "..mac3.." "..mac2.." "..mac1 - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, mac) - local cmd = "bt_daemon -s ".."17 "..macs - lue(cmd) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, cmd) - - for i = 1, 20 do - posix.sleep(1) - id = is_receive_id(mac) - if id ~= "" then - break - end - end - if id ~= "" then - res["result"] = true - res["id"] = id - res["mac"] = mac - else - res["result"] = false - res["mac"] = mac - end - return res -end - -function nw_add_ble_mesh_device() - local mac = luci.http.formvalue("mac") - local res = add_ble_mesh_device(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_add_ble_mesh_device(mac) - local res = add_ble_mesh_device(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ get_ble_device_detail -------------------- -function get_ble_device_status(mac) - local TMP1 = "/tmp/"..mac.."0" - local TMP2 = "/tmp/"..mac.."1" - local fd1 = io.open(TMP1, "r") - local fd2 = io.open(TMP2, "r") - if fd1 and fd2 then - local res1 = fd1:read() - local res2 = fd2:read() - fd1:close() - fd2:close() - --require "MZLog".log(3, res1) - --require "MZLog".log(3, res2) - if res1 ~= nil and res2 ~= nil then - res1 = cjson.decode(res1) - res2 = cjson.decode(res2) - res1["voltage"] = res2.voltage - res1["current"] = res2.current - res1["power"] = res2.power - res1["energy"] = res2.energy - - local ret = dbfs.fetchBluetoothDevice(mac) - local deviceType = nil - local name = nil - for k, v in pairs(ret) do - deviceType = v.deviceType - name = v.name - end - - res1["name"] = name - res1["type"] = deviceType - res1["time"] = nil - --require "MZLog".log(3, res1) - require "MZLog".log(3, debug.getinfo(1).currentline) - end - return res1 - else - return "{}" - end -end - -function nw_get_ble_device_status() - local mac = luci.http.formvalue("mac") - local res = get_ble_device_status(mac) - --require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if res == "{}" then - luci.http.write(res) - else - luci.http.write_json(res) - end -end - -function ww_get_ble_device_status(mac) - local res = get_ble_device_status(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if res == "{}" then - return res - else - return cjson.encode(res) - end -end - ------------------------ remove_ble_from_mesh -------------------- -function is_remove_ble_from_mesh() - local res = nil - local TMP = "/tmp/0e0e" - local fd = io.open(TMP, "r") - if fd then - local ret = fd:read() - fd:close() - if ret ~= "" and ret ~= nil then - require "MZLog".log(3, debug.getinfo(1).currentline) - return ret - else - return nil - end - else - return nil - end -end - -function remove_ble_from_mesh(mac) - local res = {} - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - for k, v in pairs(ret) do - id = v.id - end - if id ~= nil and id ~= "" then - local cmd = "bt_daemon -s ".."3 "..string.format("%d", "0x"..id) - lue(cmd) - local wait_time = nil - for i = 1, 20 do - posix.sleep(1) - wait_time = is_remove_ble_from_mesh(mac) - if wait_time ~= nil then - break - end - end - if wait_time then - res["result"] = true - res["waitTime"] = wait_time - res["mac"] = mac - res["id"] =id - else - res["result"] = false - res["mac"] = mac - res["id"] = id - end - else - res["result"] = false - res["mac"] = mac - end - return res -end - -function nw_remove_ble_from_mesh() - local mac = luci.http.formvalue("mac") - local res = remove_ble_from_mesh(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_remove_ble_from_mesh(mac) - local res = remove_ble_from_mesh(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ get_mesh_device_list -------------------- -function is_file_exist(TMP) - local fd = io.open(TMP, "r") - if fd then - return fd - else - return false - end -end - -function get_mesh_device_list() - local result = {} - dbfs.initBluetoothTable() - local ret = dbfs.fetchAllBleMeshDevice() - if #ret > 0 then - for k, v in pairs(ret) do - local res = {} - local TMP = "/tmp/" .. v.mac .."0" - local fd = nil - for i = 1, 10 do - fd = is_file_exist(TMP) - if fd then - break - else - posix.sleep(1) - end - end - if fd then - local value = fd:read() - if value ~= nil then - value = cjson.decode(value) - end - res["mac"] = v.mac - --res["online"] = true - res["name"] = v.name - res["type"] = v.deviceType - if value["onoff"] == "on" then - res["onoff"] = "on" - else - res["onoff"] = "off" - end - - if tonumber(os.time()) - tonumber(value.time) > 60 then - res["online"] = false - else - res["online"] = true - end - - if res["online"] == false then - res = nil - end - table.insert(result, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - else - res["mac"] = v.mac - res["name"] = v.name - res["type"] = v.deviceType - res["onoff"] = "off" - res["online"] = false - table.insert(result, res) - require "MZLog".log (3, debug.getinfo(1).currentline) - end - end - end - return result -end - -function nw_get_mesh_device_list() - local res = get_mesh_device_list() - --require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if #res == 0 then - luci.http.write("[]") - else - luci.http.write_json(res) - end -end - -function ww_get_mesh_device_list() - local res = get_mesh_device_list() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - if #res == 0 then - return "[]" - else - return cjson.encode(res) - end -end - ------------------------ dismiss_mesh -------------------- -function dismiss_mesh() - local res = {} - local cmd = "bt_daemon -s ".."3 ".." 255" - lue(cmd) - res["result"] = true -end -function nw_dismiss_mesh() - local res = dismiss_mesh() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - ------------------------ set_mesh_device_attr -------------------- -function is_switch_on(mac) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - if res["onoff"] == "on" then - return true - else - return nil - end - end -end - -function is_switch_off(mac) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - if fd then - local res = fd:read() - fd:close() - res = cjson.decode(res) - if res["onoff"] == "off" then - return true - else - return nil - end - end -end - -function is_set_name_ok(mac) - local name = "" - local ret = dbfs.fetchBluetoothDevice(mac) - for k, v in pairs(ret) do - name = v.name - end - return name -end - -function set_mesh_device_attr(mac, key, value) - local res = {} - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, mac) - require "MZLog".log(3, key) - require "MZLog".log(3, value) - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - if #ret > 0 then - for k, v in pairs(ret) do - id = v.id - end - end - - if id ~= nil then - if key == "8" and value == "true" then - local cmd = "bt_daemon -s ".."1 "..string.format("%d", "0x"..id).." 1" - lue(cmd) - local flag = nil - for i = 1, 10 do - flag = is_switch_on(mac) - if flag then - break - else - posix.sleep(1) - end - end - if flag then - res["result"] = true - res["mac"] = mac - res["key"] = key - res["onoff"] = " on" - else - res["result"] = false - res["mac"] = mac - res["key"] = key - res["onoff"] = "off" - end - - elseif key == "8" and value == "false" then - local cmd = "bt_daemon -s ".."1 "..string.format("%d", "0x"..id).." 0" - lue(cmd) - local flag = nil - for i = 1, 10 do - flag = is_switch_off(mac) - if flag then - break - else - posix.sleep(1) - end - end - if flag then - res["result"] = true - res["mac"] = mac - res["key"] = key - res[ "onoff"] = "off" - else - res[ "result"] = false - res["mac"] = mac - res["key"] = key - res["onoff"] = "on" - end - - elseif key == "0" then - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, value) - if #value > 20 then - value = string.sub(value, 1, 20) - end - require "MZLog".log(3, debug.getinfo(1).currentline) - local name = "" - for i = 1, #value, 2 do - name = name.." "..string.format("%d", "0x"..string.sub(value, i, i+1)) - end - - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, name) - local len = #value - if len > 20 then - len = 20 - end - require "MZLog".log(3, len) - dbfs.updateBluetoothDevice(id, "", "", len, mac) - require "MZLog".log(3, debug.getinfo(1).currentline) - local cmd = "bt_daemon -s ".."13 "..string.format("%d", "0x"..id).." "..name - lue(cmd) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, cmd) - - local name = "" - for i = 1, 10 do - posix.sleep(1) - name = is_set_name_ok(mac) - if name ~= "" then - break - end - end - - if name ~= "" and name ~= nil then - res ["result"] = true - res["mac"] = mac - res["key"] = key - else - res[ "result"] = false - res["mac"] = mac - res["key"] = key - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - end - else - res["result"] = false - res["mac"] = mac - res["key"] = key - end - return res -end - -function nw_set_mesh_device_attr() - local mac = luci.http.formvalue("mac") - local key = luci.http.formvalue("key") - local value = luci.http.formvalue("value") - local res = set_mesh_device_attr(mac, key, value) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_set_mesh_device_attr(mac, key, value) - local res = set_mesh_device_attr(mac, key, value) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ reboot_mesh_device -------------------- -function reboot_mesh_device(mac) - local res = {} - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - for k, v in pairs(ret) do - id = v.id - end - - local cmd = "bt_daemon -s ".."4 "..string.format("%d", "0x"..id) - lue(cmd) - posix.sleep(2) - res["result"] = true -end - -function nw_reboot_mesh_device() - local mac = luci.http.formvalue("mac") - local res = reboot_mesh_device(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_reboot_mesh_device(mac) - local res = reboot_mesh_device(mac) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ unmesh_all_device -------------------- -function unmesh_all_device() - local res = {} - local cmd = "bt_daemon -s ".."3 ".."255" - lue(cmd) - require "MZLog".log(3, debug.getinfo(1).currentline) - local wait_time = nil - for i = 1, 20 do - wait_time = is_remove_ble_from_mesh() - require "MZLog".log(3, debug.getinfo(1).currentline) - if wait_time ~= nil then - break - else - posix.sleep(1) - end - end - if wait_time then - require "MZLog".log(3, debug.getinfo(1).currentline) - posix.sleep(5) - posix.sleep(5) - posix.sleep(5) - --posix.sleep(tonumber(wait_time)) - require "MZLog".log(3, debug.getinfo(1).currentline) - res["result"] = true - else - res["result"] = false - end - require "MZLog".log(3, debug.getinfo(1).currentline) - return res -end - -function nw_unmesh_all_device() - local res = unmesh_all_device() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_unmesh_all_device() - local res = unmesh_all_device() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ set_mesh_device_timer -------------------- -function is_set_timer_ok(mac, timer_id) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, "r") - if fd then - local ret = fd:read() - ret = cjson.decode(ret) - fd:close() - if ret["timerId"] == timer_id then - return true - else - return nil - end - else - return nil - end -end -function set_mesh_device_timer(mac, timer_id, flag, start_time, end_time) - local res = {} - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - for k ,v in pairs(ret) do - id = v.id - end - local ret = dbfs.getBleTimerId(id, timer_id) - if ret == "" then - dbfs.addBleTimer(id, timer_id, flag, start_time, end_time) - end - --[[ - local start = start - local ends = ends - if string.len(start) == 6 then - start = "00"..start - elseif string.len(start) == 5 then - start = "000"..start - elseif string.len(start) == 4 then - start = "0000"..start - end - - if string.len(ends) == 6 then - ends = "00"..ends - elseif string.len(ends) == 5 then - ends = "000"..ends - elseif string.len(ends) == 4 then - ends = "0000"..ends - end - require "MZLog".log(3, mac) - require "MZLog".log(3, timer_id) - require "MZLog".log(3, flag) - require "MZLog".log(3, start) - require "MZLog".log(3, ends) - - local TMP = "/tmp/"..mac.."1" - local fd = io.open(TMP, "r") - if fd then - local res = fd:read() - res = cjson.decode(res) - res["timerId"] = timer_id - res = cjson.encode(res) - local fd = io.open(TMP, "w") - fd:write(res) - fd:close() - end - - local start1 = string.sub(start, 1, 2) - local start2 = string.sub(start, 3, 4) - local start3 = string.sub(start, 5, 6) - local start4 = string.sub(start, 7, 8) - local end1 = string.sub(ends, 1, 2) - local end2 = string.sub(ends, 3, 4) - local end3 = string.sub(ends, 5, 6) - local end4 = string.sub(ends, 7, 8) - if id then - local start = string.format("%d", "0x"..start1).." ".. - string.format("%d", "0x"..start2).." ".. - string.format("%d", "0x"..start3).." ".. - string.format("%d", "0x"..start4) - local ends = string.format("%d", "0x"..end1).." ".. - string.format("%d", "0x"..end2).." ".. - string.format("%d", "0x"..end3).." ".. - string.format("%d", "0x"..end4) - - local cmd = "/root/spi_send ".."6 "..string.format("%d", "0x"..id).. - " "..string.format("%d", "0x"..flag).." ".. - string.format("%d", "0x"..timer_id).." "..start.." "..ends - require "MZLog".log(3, cmd) - lue(cmd) - - local times = tonumber(os.time()) - 1420041600 - local res = string.format("%x", times) - local time = "" - for i = 1, #res, 2 do - time = time.." "..string.format("%d", "0x"..string.sub(res, i, i+1)) - end - local cmd = "/root/spi_send ".."7 "..string.format("%d", "0x"..id).." "..time - lue(cmd) - end - - local flag = nil - for i = 1, 10 do - posix.sleep(1) - flag = is_set_timer_ok(mac, timer_id) - if flag then - break - end - end - if flag then - res["result"] = true - res["mac"] = mac - res["timerId"] = timer_id - else - res["result"] = false - res["mac"] = mac - res["timerId"] = timer_id - end - return res - ]] -end - -function nw_set_mesh_device_timer() - local mac = luci.http.formvalue("mac") - local timer_id = luci.http.formvalue("timerId") - local flag = luci.http.formvalue("flag") - local start_time = luci.http.formvalue("start") - local end_time = luci.http.formvalue("ends") - local timer = luci.http.formvalue("timer") - local res = set_mesh_device_timer(mac, timer_id, flag, start_time, end_time) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_set_mesh_device_timer(mac, timer_id, flag, start, ends) - local res = set_mesh_device_timer(mac, timer_id, flag, start, ends) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ del_mesh_device_timer -------------------- -function is_del_timer_ok(mac, timer_id) - local TMP = "/tmp/"..mac.."0" - local fd = io.open(TMP, r) - if fd then - local ret = fd:read() - ret = cjson.decode(ret) - fd:close() - if ret["timerId"] ~= timer_id then - return true - else - return nil - end - else - return nil - end -end - -function del_mesh_device_timer(mac, timer_id) - local res = {} - local ret = dbfs.fetchBluetoothDevice(mac) - local id = nil - for k ,v in pairs(ret) do - id = v.id - end - local ret = dbfs.getBleTimerId(id, timer_id) - if ret ~= "" then - dbfs.deleteBleTimer(id, timer_id) - end - - --[[ - local cmd = "/root/spi_send ".."10 "..string.format("%d", "0x"..id).. - " "..string.format("%d", "0x"..timer_id) - lue(cmd) - local flag = nil - for i = 1, 10 do - posix.sleep(1) - flag = is_del_timer_ok(mac, timer_id) - if flag then - break - end - end - if flag then - res["result"] = true - res["mac"] = mac - res["timerId"] = timer_id - else - res["result"] = false - res["mac"] = mac - res["timerId"] = timer_id - end - return res - ]] -end - -function nw_del_mesh_device_timer() - local mac = luci.http.formvalue("mac") - local timer_id = luci.http.formvalue("timerId") - local res = del_mesh_device_timer(mac, timer_id) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_del_mesh_device_timer(mac, timer_id) - local res = del_mesh_device_timer(mac, timer_id) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - ------------------------ set_encry_info -------------------- -function is_set_key_ok() - local TMP = "/tmp/0b0b" - local fd = io.open(TMP, "r") - require "MZLog".log(3, debug.getinfo(1).currentline) - if fd then - local file = fd:read() - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, file) - fd:close() - if file == "00" then - return true - elseif file == "01" then - require "MZLog".log(3, debug.getinfo(1).currentline) - return false - end - end -end - -function get_ble_device_key() - local ret = dbfs.fetchBluetoothDeviceKey() - if #ret > 0 then - return ret - else - return nil - end -end - -function set_mesh_network_pwd(old_key, new_key) - --local TMP = "/tmp/"..new_key - --local fd = io.open(TMP, "w") - --fd:write(new_key) - --fd:close() - require "MZLog".log(3, debug.getinfo(1).currentline) - --"0123" - --"8888" - require "MZLog".log(3, old_key) - local key = new_key - require "MZLog".log(3, new_key) - local cmd = "bt_daemon -s 21" - lue(cmd) - local ret = nil - for i = 1, 10 do - ret = get_ble_device_key() - if ret then - break - else - posix.sleep(1) - end - end - - if #ret > 0 then - for k, v in pairs(ret) do - if v.key ~= old_key then - old_key = v.key - end - end - end - - local res = {} - require "MZLog".log(3, old_key) - require "MZLog".log(3, new_key) - local old_key1 = string.sub(old_key, 1, 1) - local old_key2 = string.sub(old_key, 2, 2) - local old_key3 = string.sub(old_key, 3, 3) - local old_key4 = string.sub(old_key, 4, 4) - local new_key1 = string.sub(new_key, 1, 1) - local new_key2 = string.sub(new_key, 2, 2) - local new_key3 = string.sub(new_key, 3, 3) - local new_key4 = string.sub(new_key, 4, 4) - require "MZLog".log(3, old_key1) - require "MZLog".log(3, old_key2) - require "MZLog".log(3, old_key3) - require "MZLog".log(3, old_key4) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, debug.getinfo(1).currentline) - - --bt_daemon -s 21 - - local old_key = old_key1.." "..old_key2.." "..old_key3.." "..old_key4 - local new_key = new_key1.." "..new_key2.." "..new_key3.." "..new_key4 - local cmd = "bt_daemon -s ".."9 "..old_key.." "..new_key - lue(cmd) - require "MZLog".log(3, cmd) - local flag = nil - for i = 1, 10 do - flag = is_set_key_ok() - if flag ~= nil then - break - else - posix.sleep(1) - end - end - require "MZLog".log(3, debug.getinfo(1).currentline) - require "MZLog".log(3, ret) - if #ret > 0 then - for k, v in pairs(ret) do - local mac = v.mac - dbfs.updateBluetoothDevice("", key, "", "", mac) - end - end - - if flag then - res["result"] = true - res["newKey"] = key - else - res["result"] = false - res["newKey"] = key - end - return res -end - -function nw_set_mesh_network_pwd() - local old_key = luci.http.formvalue("oldKey") - local new_key = luci.http.formvalue("newKey") - local res = set_mesh_network_pwd(old_key, new_key) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_set_mesh_network_pwd (old_key, new_key) - local res = set_mesh_network_pwd(old_key, new_key) - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - return cjson.encode(res) -end - -function set_lamp_brightness() - -end - -function nw_set_lamp_brightness() - local res = set_lamp_brightness() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - -function ww_set_lamp_brightness() - local res = set_lamp_brightness() - require "MZLog".log(3, res) - require "MZLog".log(3, debug.getinfo(1).currentline) - luci.http.write_json(res) -end - ------------------------- bluetooth -------------------- diff --git a/Me_Lua/h13/meizu/r10config.lua b/Me_Lua/h13/meizu/r10config.lua deleted file mode 100644 index e3fdb3c..0000000 --- a/Me_Lua/h13/meizu/r10config.lua +++ /dev/null @@ -1,3 +0,0 @@ -upgradeFlagFile = "/tmp/upgradeFlagFile" -upgradeLOCK = "/bin/touch "..upgradeFlagFile -upgradeUNLOCK = "/bin/rm "..upgradeFlagFile diff --git a/Me_Lua/h13/meizu/sipfs.lua b/Me_Lua/h13/meizu/sipfs.lua deleted file mode 100644 index 27ab6c5..0000000 --- a/Me_Lua/h13/meizu/sipfs.lua +++ /dev/null @@ -1,690 +0,0 @@ -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 - diff --git a/Me_Lua/h13/meizu/upgdfs.lua b/Me_Lua/h13/meizu/upgdfs.lua deleted file mode 100644 index caedc9f..0000000 --- a/Me_Lua/h13/meizu/upgdfs.lua +++ /dev/null @@ -1,231 +0,0 @@ -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() diff --git a/Me_Lua/h13/mime.lua b/Me_Lua/h13/mime.lua deleted file mode 100644 index f559150..0000000 --- a/Me_Lua/h13/mime.lua +++ /dev/null @@ -1,90 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h13/mime.so.1.0.3 b/Me_Lua/h13/mime.so.1.0.3 deleted file mode 100644 index c8ebf1b6d9604bcd02dfc604546091c84f12c67e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10200 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 h0xgjUvOf;p{{SeD3~&Gd diff --git a/Me_Lua/h13/mime/core.so b/Me_Lua/h13/mime/core.so deleted file mode 100644 index 723cc1f2c0481f21c24129c26ec7106213d75263..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86651 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 diff --git a/Me_Lua/h13/posix.so b/Me_Lua/h13/posix.so deleted file mode 100644 index 648e6d800767c5db9793184fe22315b0dd8d203f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45066 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 afj2iy07H6$YBT&@^q}W`CrkiCy#E8?M3BD# diff --git a/Me_Lua/h13/socket/core.so b/Me_Lua/h13/socket/core.so deleted file mode 100644 index fc4064a74d7e33611e03324cf08c75115ba26b34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 306460 zcmeEv4SbwMwfF31lZH0HHVq{}pwG73B$QA?8z9vvOPfN(r~v|0t!DGFX(HPsCYutp z=vs>O-W#()d$rt~dvAmyRcn*B=?73S0&3Oj&AnFNs;KdT*Q%&ds#dM${r~49JNsml z*01;D_q$I!JI~CSIdkTmGiT1sGtZOvt*ySviMMs%% zM3yKPg<=VdcAUbG3Hi8Z@ad4mh74R4PpgnAQyz(5j3P0Lk_f$7LJT6{KQ52(;x`8% z6HX${Fb9Ec-1>u96QXICflmWi8LW?MpNf*dV{5#Ut`#7X^oJ1VAU<=65a%N<9Z_wc z0+9U}2axoJk(i6P7x6sAeuNB!@#j2ZKJym{k&Czkg>eh+O8gyc164ZMSAaSY5l=@5 zG3s^nAV$3oavSwJE<_PZ zAymsd^}}XgjljP0szta6;XH&Z5qObibCH+#AT%Qs>CCGUuS6hUN)b8{z;3Y=!M?6V zVv)|cNyjCK$?rmhn{}QY4uZLE!wqE%RTpazA_$ZjuL2c`)rjv# zxDa7I!ZirIu2PZIRedW~;D$PQvCe2gybR%02$v%)MCd}e1K}2g%Mi}xszRX}gkpps z!W9U-Rw1mFcd0+rM~+8c??AW?p$y@T2;~TGMtBRtYY}*b5#GQXT+0z|Kv>5Ft_>=Z zdV3e{D|Pxt#IMu$*CW>BN>u1P=(M~-I(`%4jr#ueh+FkNqfOTRt@^&n$}_jr+qdgP z1LE5e>U5gXod_IA?_>g36roYxsh>9Mezx0g05LZIW*2P=uMCWqThUN>)Fab=jCkq^ zZ4s{p;un+a05@qr(tXI^4do1?N-iu0b&dF_uerc?3(C`W^YR1Uh;;Ag4gOzDa=g%% zsq#5uy$jBgv|YUBqrGmx2d(<;uJZR~pdH}jMVqjKieRO0LRTjC6RP0<1o*g>-j4K` zl@0>msFl73>0v9KLwc;V2le}{bP(;ut@Kf}+hL`@fUbqDbS=^~R(b;Mg{<^x;48J# z`A9of`lIZ>m41o+x6-!&KCzFzSN(q#+8ejhw5wxQ`bDHit#mH%4O{60Xn)X3zXbgK zR{9$#AGgw7Xs^RcKL>c&N2Nq^237Pi*$#T{wd0Y zt@LHUUt^`q(EpH?PN06Nm3{-#j+Jf%y?!fw3Hf2AUx)G&!^p!$e$cj?%fU@H%8y&{ z-;qC7`Ub#9t@IGm!&Z6__y?`@w}G?YO1}VnaV!0IDBoeFmm(du(kIdX8Y^9Z`XMXb zPyMjc8&Th}(oX~Kx6)StF0AxC;F}mi9xn3Z%P2o?rQgr~Tj@vHe=B{2{kPIF;2*To zcLHC(mEM4K+)57se}|R+BJhQ+^izP>Sn0W_AF|R9BVB5xZ)5+h^jnbjTj>Mrzm-0Y z_9phQ_p1MKz{jn02jF8?dM)S~wbGwJde}-gC{*%yF@8Hi-=GD*A9?*&`nO2Ot@O81 zzQal%2mY{?{xSJsrGE>0Lst3@&|7MyuLRt&(odm1zm*P?A6B{r>4{Gx4;S^J5bcdy z=>*baR{GqK2^TWd_zZRn_L zYVGO}boy)9B(-w=%`Sb9iZV^2L1)JI$29TCy) z`s%vImPq5>t!=T$hDaxK>NZ4TvGxw$ws%C@>blw+?~cUk8rwT%g}RRJu9mJ?XKULA zSvu0$*)Ho<*RgoCwLxZg*5A_=0o8TUSX1)~#2a+n+}hLB+=UL*HAma)V_mIH&A9LC zZfI&=iJOhxQQjmeYwOzkT*LxNj3M%tU3>hG0}lSExl zB5Lo5xsuUj531|xJJEIaLetdUCaEGXTDy`J>tgN6gyx%tM>3|ZHA*b4J;0&6xgkOZ zNIDw2n<>1QN`ZQ-dbO1;xa zqN@X{5Nnpr#M-S6$wr&4O2FIP8i_VdQPj}h9*xwuDQ-wL?3O4=F$heh3JL`Tsu|GK zR=-iv6>B$WP=&e*VN)Z_ZEG8pw*#UR@~)nDAgXbr)NrRan@tFQykeo8p7y^EUG(H@P8uGS40pHk8`Mavdt*K5CQr?c9%54(2rZw|x{Z;I zkQ|6<*wENm*R{N>efc#^HS(?$HZm6Jf%Sn!fQrI&in@rpt!wD&0{`mKYF#t#0YIm2 zUbCjIZ21b*F3_=~Nu|BtvcSO<6a#P>UgJ)ck6gq$0IsEqT^8=Kd$pP4Astuh zxJJjdI$o#a^*RpgxJkz?I*#hNL&q^4$923_$J=z=tK)thZ`bh-9S`VuP{%uUJgnmp z9Us>55gm`}_<0>4)$uVMkLmchj!)?L1s#v;_$3{m)bYzYp3w0r9iP_m86Asfm0Wx} z&em~`j{Q2$({a9z3v}%0IH==d9hd01RL5mHF4u8|jzc=G)Nz%Lt94wX<60fB)A4#8 zhjrYf;|?9ibljuk%{tzu<6a&2>v+44cj$OP$AdcFspDNb-mT+d9gpbvu#S)D_^6JL z>3B@X$8~%{$1mu3T*oiz_@s_s*71anPwDuyj?d^=VE>5r!>8kH9p~uSuj4!&=j*sY z$BvGJIxg06iH=KkT&Cl49areMO2^eYuF-L=j@RjUy^g~=Zqjj!j-xv6&~Z%1Jv!d3 zUf)udv)BenIzFP~Q5`?8@hyq* z=eA-SaCLBrzf#N*t4lIPC~xHb4<|B&vw(H7g+uZYkIR_-$VtKRfW)z+c&E6(I8!`( zai$0quN7->pD70Y<7dG&TC8|d09wX0U;014roRNdDHi*Of@0s0BldzTN?0fwFL@@rLMD}Q7a7q6f@BRI`q9ER%n4G+=Ft8&m zwtqgO?<#*M`V;bdL}L)?J@NbuG52WWdleobemyDt#6=mzFI`o%cT({dK1Q(r^NSw= zZ3)np0Bs4-27V7qewTvZ1Rs!y!{JnHWQKJt*TF%6>*lmbp2KwCoxa#b6YT>zzx z{8(qesuKo3Jt8y6I!b?rhe&rI9!Dcb5&=heH-jf^PvwWi5`PVzW33K?XHw7DM!u$* zI%3l9c7wXz6QH#Ww6aagA_$r(k9ULSz&6$H70{c2<9JKr4nJto-O=^XC}RUg#C6hlt=!f?G&CDlm7Sz5^Q$>{SJ?QJ{Z7* z7uJvKw$stIZ5G&e3s!E?{D(=&_r%vMd5S_M>!aY2gZ9azGVrGad@2TyN}<1`MavBG z35gxR87K~m0Nixa8iUMbIF#W(OffAW3a z3dpt05syG7gOp7Xo{9M(+oF8&h~z0@1^PaS`y9|{_!}q|QU<5MTk;rmCqQokv_rp@ zPM3qf4sfHa_#yfo6psxxN&1zHNGIjUevMkZ3iOAj^fAshL3f~3_p@B}lRPMa9U4Tv zngbu`tv&Fd>LYMToPe_}(kAV_+{bEaRp18l)wrS--B}dwzU9x{dC>un5AC_a3 zG~|n&wA~m#I}>()Nh9+MbiP}rrmwrei*@MhdUs#J$Mv$^R6Z$Nvlq4|)y8aFlB5^y zLf1y1bDsgN`=JN>AoIPLTZV^xqQ6&&hkB*X4aQ-cg_rUVK=&k1p?{?N_0&1!Ws48> z<%kdW$?{If3%cc4q@J?eGHpZ3VGr2nVQm`;gARC=ti#h}?H3>DWB>BRgMHK$rORQ7 zlWFRC%9w!ufbKrf-zUq$cC(E<=snw!2=A+}{PfH4a zgys+0a*c&QnLn5ZWxMgP_}rxG_cur*XrgQOueCgkp`nTi&OaWKYHWVn{WM5`2%WP{omJ{{6$J{=(kXY#`geyLqnid z`5)drc_L#E{R#LIUfai@?j65E;h;Z39P}etAGUPpU#f}dAq_Jhc95prltwwcRYhW59?Rz`W!E``ytq%Fy`7O%(bLT*?*T0 zx?>RIC{y9>j~n}ix%vZ%(&n0ew;93$PCO;`T)ipJ?0oglPif-zVO+CmZ)a#eEL$ ziIYAH{S)J>&~Kp}^D#FTh^@VWZG++}f0GFGkD{NMeR(3Q??U*^tV>^UN&fw~TeBx$ zWb`r5fj=FHXL$KkY9?Poh@If=$A_}T6TQO83OXXQkbQN;wIYxQ0^mbH0dUZhv5R9_IXP+~*)0rSKp}H0+rP7st!&xEl8C1|Lk@K3#sH)#$m>pGSs5@Xsp1^Ky*0GWcet(AgUC%uuyB zG*l%H4poW+LtINqd4l)Y7eJpKZwGLY-$C*5qGI^(gwxkI@Di+dDW8@D&9Dm_ddW|T zV=$y}q>+)kZWwi&P?x-wb-^=LCY0)b0~ho2Am0k@|MhTu!B=BG))xt!Q_J#*HNopd zC`;-#j{F6Nd5&^n;j;YOFpk5@exS}We~lOA{7d?4;IHA#9s0^Tk_KlX<`3||=sNUI z%9RO3H5RP8@7RN>z{6xgB1Nx!mDCH}{Y%=|lnIg?``;Dlv=Oa1IG zb+&R!XTJ@kFoWTU^;#y;f#9+9SgsV+$!u!VDeE z?*J{5hgdraQ5j!`xt?u4EbjM5ac|~()?;~=jahU4$rL##x`-)N@57Sb+458MKI|>^ zKal{x6X0zEyiI_&3Gg-n-Y3BO1bCkSpA+Ce^!_bU@56rhM``-axv4_(FNAfM9;2GK z0odAYh`v1C~&&v_3 z;hTiu?}YZ$inyflg-Iuuv`&}RYB>&b#9J`NDpU4uxOb5{#*_^Ii2bE%i^t>*`$YWd zWKMXsr6Xtb{?z???0MjGvhKC;FYBRijgxEgq@4v{r}J~rOMbpv@^dtU?FJ#2V(`(7 z1M-f1lrn_f$rr2pSSClT1^+7h0`O+9aw@^+NA=iR4Zg*}w>49I`vLex`TcRyi*dSm zA?aH?DUWN5J(G@1->B&~$d68DO$Nv2<@Q8F$-fU;4HZbO<+93X6tSgwoehsgs-s-FwtK4?HIA za-bBvlD16El>w|J$=7sscAGlI*t@XCAj`52_lnD1`8es`N7y_um{%uqvHnxCWH~cG zbI;q9TY%>$2W8ANhzj_zmGE&x@M#sFVMx^a$bSr9g0;S8V+&<1~QZvu2q?H^RZhjZhYlIJXR z)wt*)y)WpwY8WuKM;@5H{(S7mvz@4x?+ECWJc3Va`kIe=?4!yz`X;1~1_3*aI>~(y z#|ytx@_=Jt>-kD190LLWpxBD?6DPP#Bm884Ao*yR1Mv!f*!$ME4{Q07@AU8J2cZ8F*C{h@F?aS* zE@uC>H10hYyySb1?vI=A?2q9&We|v4e1|P!AH2eoMcz(M`U_D8d~@W!GwNa74JTd# zO@!NHZ(v?h&K!HHo#YV+7sFljtiDC{V{b+d9xR9o;@0SvukcrXF^zOvd`2N>W{g2^q58XDK6X|EL3o9_l{FK(R~z zg>{i%{n^Q}PyzqrWt4X`j{=S!1Eu45_wI4<;|TaiTd4L;h>B~|9Q`aJ{XP$PD|ISSF5ziCgjm5{5wC*xW>sI2@B|P&AP|94~TKiI^?q98_SUP5cozI z)3)Eox+dT4UopR0&tLSDSl9NI2#3um+78%U;S16ZN6_4<2UPG)7OE6pO@`_U;BOrZpLSahJS7bc(sP_(Qtbo$Fz+#v)soqedbs% zMSs}u=PaMopOLg-e*kaQ`i5EbgK0nbZQuOhCGq_B>kBq ziQE4IeM+a>*QcQ)fOQ<(Oz!cAKi?N z$kNBSICpy+C?Az)dN?+1yBj8d^c)A@K<>?qqTfM0k0ig@f5{Knx2U#5QZMjKVkUch za#GPX2z%UtIy3pNf%u@{dWU;lfgSMQwfqC{Y0W;s9PAfxuj+gOH&0%feT>f2`vbOa zaL%GH_-n|BdkLqp&hX((9n0t7Os858skIQsxLos`%Q{M}p&V(;vk&S066~{a4Q2M{ z0$4+_E&1#gFwTeLfBYXlkPj#Rp!mSKV{$U9>%lv`htqX794L<_p;15 ze1acaWwu*o431X7g;(K-S#TT2H?1-?R+%h}1Jbb$aF3>=)PfTS%aD$vR+${DjG^OZ zz_T@um(L{oYSVGZDs$8-V{lvtxL@Pgl?J{Xa7V+pS#XZ$c*UwB(qQVhSa8x%vu0J% zE7&{rqb&JdWx-AT>rp>f<1e=0rv8hlpR4Odz!6%OZPkwJf!>`*5P_EfVqbD*7zzo^IB?rI{NztK7n() zYTlaJ$4uvU;VgI_d1UA?_(B#P^qEY)p~F1;61e1ifccW`+v_3H%5_OL`fS!|)b}`K zOkeR9@R#Ru?KK70jAlJC_*iNylK4w1o3Z0a6W1m~m{aC`@`(u9%KgpXG&SOugXPVqAB8+PjKX4^^Fue}TvYm;M z&qMZJy?#ory`=p+og6Qui{trrjD>(63p+HNYiG`sOm$~ zkD~v?HIRhImCWc%aV=qdd#=-zZ?F7%wnuq=_xD_1&k4@vODW$`>8#odJCgX3^qE4_ ze5SD0G2`2l7rTF>c)>L!`)JmRLOjwtwf==X>7OY&vHph)9oPqs2lgw7^Hl7&U+;Bn zhm5BAGmvlU9x!;M*OrtM^^oh!)U~lK-_*1ITpOGEW?gL7rzd`$lrMEz5_#X-~OQN;}V?FdQuCK1jJ?1J9;K3-HK%VB@RhxZMzKkpNxc&<2#Gkv2t(>J<1AE5vt zP(0|3`W`PLo-!ZzR*obt=UNJ5IaOC3oU2j$5jAqnj&G2G#{uZQqz(H8Df$muski8B z0{u#$UkUU%fxacs?*#gnK;IMSqkLw$!-w$+n%PH=KiMzzF$y^GzX6}sxN7hs;lZ=M zYTrSe-#S!O2p>N5u{`1N%?XxBJ2nn~{oqg@)&Q)Z54&V&<{D%n`2$~?Fv>~NZPp>y znJAeLI#T*mJg)kQ{0ZP9G!qpI^jUkVRVmieq>^N?#NlW%+xwntnqA2I8rWIG17L$95Dc!xmg4)^1e zx*~e*PHN9NeCxdHT_eIS~ zBjBrg_k;bS{P>KD?}Qk++Rs3WCzSrhVF!)B0iA`7`^?aK*uQnKbF_^;zGq{ ztJNsOHa0=_lyymbd!i)%5rlt4_-LY7JcF~63xb1(wik*6-zdZo_75LAP&gO9FrMYh zeHQkQvX-<$E@9Y-Ow8H44*fu$3%6lLPOM{W7~!nrL!H2sz7A@;=bl4HGfX?_aIwBS zzd&5m$2!-^KGH@8q3=uklS9&t|`k4B=aG+*#v` zxO^C!Uhs_cv9CO%xCdvsxHeD6KRjdf4#Sp`C)5?zW4RhVS0YYOSGuLW4T3S zee~d2h6nGrd6LiDN4>rVZkK<7K zxM+`aPT9-JIcFH{I9O**^$&APP_C=hni?`vwh`+K-9PM!hP<_!jt4*oeSc+p_QB3@ ztf=uspLiY01;CpCo>km|vOIe|Q(4ls<0nblXpi)>Rjl**o;02jV{l1+>$#7%hHII8 z?AZ?7wW{a~c(z2}g0x~jkzE*(I?f9VQJ^=H3VU#k!uvzN1Rx%`So`43pC62P;Q#s^txn9X5b>9D)MU+1~PS^5k1NtvYUZ{W}DZ~u=}f9Z4ZohQd_ zzD~_MhL>)eV)FUk)Btqpi1p4iZI6LZw}tAxadTF~yhnBBq@t-H{-C6(6f}_@L(A^b zAIh^`$iuvFeKt{%;2J&)uE8|8oEdO6XKvA$&8LOt#%vw$88^g{@P?t2SptF`T)3)?O8 zVYB=w4@Rl+jd~mdgjI?y(odX=H0Om^BTc;2jq~-~a0I$R`q1A5`kz3b6XU&_SVpJ67&;4;)D-)lWm9OJk4}!AFvNG1Aa4JO&dvEYR+TYZPVGdZPQz_lK#v% z<|Ec&AL%F1p6o&&zkq!9llgLv1RsPxZ^wD?Ga62tQT^XaU(co&d4GalRQ&~d;Yc6B zZS#y?xbs7QGx?LRsF)g72**;pD%JOUMwETqm69R^KSw4k8^JU0?%4-?=gsA&R^V! zcFB9T%h>obpG3deKJd$Y+DV=raHmZ>e70fQVH-b!&a)lr{JIxapSgcp1HG2}r0~@O z&M3Yo&+|mn_fol!N_>Ihaltc|)Qx=XD;he@dgHLBllk-YT9xncvM*Ws%(uON!1<7K ze+Bx5vjgd$N5eL;KK3RS1{@)NuE)LEvskG3c&w5xl>0=uH-(vNPv_z#m`Rv=l-juhmRpM0dHWE%b zvL!4p1k{ zxQ@qs&;6Nvq0Xgcibv(Vb{KddZ~9IN%H8NYUW}1^p>In3gZ>Y!AXQRs(N?o3= zb04+n__5Zxf7d!ie!0h|p$l&(?%_BkEs*bw{K8*|=<|uWpyND@sq8*HhwbD0;`yMh z0Plw@ncTg{C*HXyTeR-U5iNWCV#A(1(Yz;LMD~0Sv=rdoK)xdwaM(j3sCR?kP1-G` zcl^!?&$LnB4nPO@!;Y$Rvedm7s5gUysQo6+-(9E96^N0?uMmTe2h2K2+xeRz zi+pha@>bu>@IP78oA>0cy%#{nKI~mcJ;nYSe5#xLsAca0XgtJ9ok*u zq%88jlbkolK-c*=b5{U4P%fm4G$K9qo(1Pj+7l1xVg2JTsQR2c$#2@ND)G!vCEkG! zVGq0l@}vzhwgvMXWUaoVwC=!d_-4-Sy@A89EyJ)ayGBJ|a9n`lkkb`G=x0$a>?WUu z2Apx&jZxT*LA6FNkIUzn>?7s3O5BL&p-KkKqx|^HWul>EXN6Z?Or<_!5f1~Q?H zC@cFtM+rmTC}6}yK5+c1e3ABDa|y%y2udHqDf(cyW$>|0gKr!9$aM+yY3hASK0hY> z8R!XRZocD4#W5B)ag<+oMC+eeE06 z{8W8O+D+0sq3z_kj-!u2&okg}%tQRjWCMJ_u%JBxjeU4eu8%U4?P%MBZyC|nc{jse z@J#J<@|<2A??x(q{ulQ6XuEcTM$*c?92*C|dj$^jdZf=htNFSfulz!v6g7eklJ?ua8jLi(7|Fj!9eD4zDHACDb`;?={B6-8oo535##F?r61@h#- z&`;(kW%LYe-67bzgRpf6VC&L<_lb7z6^lpZCz3p(&XvP1@fj0&MLroGk$>cq;Spxy z-Kl)qulO`EE;eHi+~}ku$g7LMtA)Wbt#bkWPEtVY1N%WXh0yb@Qnfe(5^QN9!S19b+FL=s8C~m# z{lghjqi3`mw*Nd`&q4+6d646aYZs15yq}sIz?n|Bo;|F2#j;5~3;tF0Y}fI>jh6x)zP1bmvUB|$$iBQV8G&)9pEfS*(Xv5}0*QhfWio2v985{P7v+CFrQlDWb^6`6dluZtZmPP=3lxw^v|_rBCU@3`d<1g+Oo?3oX#UN z4%6|-9*gohmo*NrnPnUvlQt~%XWa9>Et{)e~)_iF8NJf^X}a`-QJ(u7t@cp zxT(zUhtPO=CX95FPbKIBeOLHv=$Cqr^HciWF3O9vp91ZCo&>nu=P~^M(Vg?`N}bUhJE)ZzB>bbWN@Kf2G$5)A^yErT$dI ze*&8Rp#AYi$#r zDch}D#=f5`|A?|Ybxif^O5h3jIL&TJ6LB8q3*M64l zL#ghA*}vnry||Cb{^e;{NbhM=r*gy=*r_!olp%GhOoU}$%yZ81C-|JR0liZC5b&=@ z|3XOf8J5~}ItE&(Z_G3LM%eGrcI=7Oa?gn{dmO6rmAy94Xj@s2->NM^J>K&fK)=4{ z`MSgUo@;_Uea~lVCpDkA|F%=#e+&0jD8shQb3kMJNGHdMeVIJ+>g1P{E)?tM)a8)v zk$cs1YVwMG@nGB$H}{83zgc&;u1o$_pdNiI!(WbFHAdocj07<5{aSAnPFYs^@Px5_ zwmsgX&-s;_c?xG1G>qlMdlcNz#QDojSDr;zHE{kE-`W8E(q6ggBF!TfU6M{|`)59r z*pKp)lWTc?U+wehbs^3r$bAC4pL_?wd>7?Hx$iRl+b8Ml82P;!?XZ7Fmei9d@>0Jo z3ci9~p53?K*R}iMK8MEggxmdQeeR?4Ss7(Jb~I`G_-==hE%`@Y+OnM^?Xj}O#OtP; zGGIRIP!_U%@Qi$9egLwT_^dMx)F*+9`8<29_f}o=G$KCan3w z&Uf?1l(*?3&zMiV0~VeD+N1m^JIdA`Gd*8We4XiAxD&H{3zzNiqI^m<9{D~I#wquO z%$|qwf4NSjyyW{ugV=B5^PXK?dyb1LtbMDo9?lY@@N4lmYB}6+@jF+q5_$3&#_IWg zSWqwaY##9%yEq5mzQT8|x@}p8Wz9G*52Aol;i`Xww?_XNyo(=z4p6yT$Y)j_P zSl&r_2R(U~*GW15$F(!@9G}cvNSf61eoo1Qe3ZHcT?8)4vr_DtlwiF- z?HjD*p+5h?_diwNLMeaGf#)fie>uwy9nGmis;?R-eCm#zYeaz%HbY%Z6 zp4;?J@sWJ9#yf2==~dqun1T1Gvs>!2dIyU0i|OO;G`JQ^TOaa<(!kJHq4xj7@;zbh z=eT)|xk9cLnym4_{WIBSJS4~~@{IjuzohSsX9VVKw3-*jGw45`g5Ab_Y|YIrkj`hxt7ToX^Etj^BN%f&3)DhsULU;P2W5i*a_?gZ`X%eZ4k{j|zUODgYk=@H{9CQ((dhdgF1!cp3hFcWbA+$5n9mT1vsgU4fcdY2 zg(AMy^RLjh>RH&Tn|gi4U(Z-t{5h0ZyBpsO?4u5lX4t3oiw$+)yj|3@f2hT?Z)hvd+r>T4 z3~lxt8tU;J9Ey1k3^n1*a2RKZ%RP8zhp|U~4dQGa_ta{TSL?xhZT_&=@r>Y1UI>53 zV|DNklUo+@+qnV%IOJjS8Wsk$9Uy;*N7I1)PweSZKCr(^cS2Lo0ykSa!uoPA&nnM6 z)~N(7gc0|-)(M@h4scUP>Hn~eDqSAur2XIr{P>3xl^&kU;q%Op+>bpRUsY7V^>BH3 zst?3r=%hbGI%mQ`IC0FAIL6cBAU(wK9~>(f8}xsQai*VRGcbYor=ZTYPu?1&UKn0e zKMa4EZ|E`k9&w;BbzBcBUQZhnS_bH^ZGR0-#Oof{Z1+yk8hzh43%AJg$7=qe9uoHL zNpCLcjLR{q`hJ zEBZt3WyK}`%RM_2y{PYpFXRzh@%^4KeD-ngsozk?lh1dGp@SjM6Nz$+hr!J?!Aj5L zlF!O-djfUw_ZE%{@0+n_oQL_QN|$9h34=^0I(eVJ zknjZHlw%cOO#g#Ud$ERr9ZSHDC1A%Auwx0>u>|Z~0(LF|JC}e>OTeaKZ8e^;4d-e( ze#oQnfhv4s{q?;y=tC{&@{3(~mi39Dum2#)51UVm&w)>$wD@#T{|y-K&k+xOo=R&h zu7C2e;230T&dA#1f$z<8pF_b?Woqa(a{UD8O()l1L*8eT>w7JFzdnh-;{$uL4egR% z&MPBNntA1csk7}-(9Lxr*Bh8eQ`U#7pK9&e^W;svo1fHwBa8DtWE((SZjC*A9cIqH zbAIrDR=v|solCdAVmrJ@qhHh513#z({N*^`D(O2i6o>9@hELRkHB$^eeh2hAisyGN zcz)M}HB%UUn3{*MW|HF>&)SH`ydNvaD9$Jt*m2O$xs3HlpM(!;IMSTwSw@{n#CN#x zKDjJ&IEjO0`k{m4fbpC`?kUI$?>m|{o=5$4j+%#P^HqLG>?B_BXPu+>BjO5%=Vpc5 zp=NZpZlPQE(FYHFc@M`H^?xCBiDQ86s641b9Bze0!}7_vHu`2&A>f$t>h^!~o7M6{F6D zpgo9wk@f|gm-|D4=Lm^^_is7wgzOj7=hml?{EjSXp`92epP+|vjI}TPc)pMOPtRdo zlF!unfD52ntt9?MgAXVh7=sbF}1qWjv5etuB*lQ6a$)%=V}eunT2SNRW) zXvpQ?rs3bVaO=EJtSID}7WTD5>OS{HjzITI)9XIyrT$a*?|RAB{h-$UkasQZDAv9; z&dNP}XMr-{Hy&O_e`$AvIG4t}D>05Q1)te}bKZ=9|BHR0%vuf@TdMdv(z~jt7x1~L zM|f2l_*TGahX^m8f~&RjVep6g!L_sfypDcP7I;ay8=Fge!*_v7LGuo*JDkt{5ID7c zfjnfn;*dC^d48Ydxg%{h>8IU@!X~=+Be_;J>wfZpbF6vJ(=%fF`#^$cQ%Eo6TnTzP zZ-k(;70}ai*eBBbO~}ipd72G2bV6o?85=D16XTD4sBxCyOjii}=KDCx-jFVir69(# zIp5DS{~Y67PxAbH0nVO%5@UmByNE~b@1nibv74O3(v1!DD}g>G&?l_pl-;S)`~T^9 z$MYwojk2xYpX3$y*hj&uLGa3+XUU_>Ex8K#h@;jRrJST3(SNoV0G}jpus3JsP$MJr z%=h@db8C0fk`3E2w(ec0Y3mg4nLm@B%+!AE4DC}tOyAk>?^*2=R{(u`9z5dSNV&5% zIPp^QeGqYuIKSk=SpZu^yhkkgp>#7 zY$+%3Ep<;QEW`|FHRbqswQa_~n^$wJwhgb2=|1I)wZSKUknGR#;ne=jg!7jtlVj81 z9J6q?|928+{2Xz9Ck@Wy7S3xeI!n$G=g~AcPgpolT6%I~D7Eiq%(?j)a`Cgqxv7^j zeL>@e4H0kprPcp)#Jg+;yyF($eZNTJEj~xQc`m$0uV2!5<65uJ{3MC{*q-UUNT=6- zu=opQ6(@m{@mt{^=HqW$P_I2=ZAmuto%vGV!7J(v$Ew@@)LQNCvg}?h<_OH&__p{6 z-sRelGwJ(qCVemF3^iALThn3uh;(xWVVolf3(!{w9g?0w<$rLlD0f!iZ%|_o7X9Fy z5yU(Id*+?V7yQ_Z^L_OHh}-y(oLg#~rSK2q@Fl{SGxrTW_)Gc{svN%)Y5W}0z&ZOi z&`FQa}D@|Z|slYxz2uk&vqZqlJCXbqvo7-v&=bshrrA^Cw3=g z&OKy~{oSCgLi3*V(U+ueY5d6vt^@QssobdynmvTKfiK+mR(#oC^fGY4XYONv>F*x| zKk(jF((lB4o!Z}-eErZl`kju;?{uboOY)ok^RFcB+V{j7ifgH!yx3OF&A)pKsP@j1=A8b`gGz%@r0_G7Mm zXHl(J%sbA9L0dYzM*2+|z6YJI3~5@YY2x!pK7YjeZHV7#DZqPfr@%uzU&DG-J(D!@ zCB2Y);qYf~f}U+p1h_V_WX*c!cr!gfCy0qmi~0vGHwV8r`XE#*d={Zqbg zD&LRQYw|QYI-5;}-GkqL_O)#><`jd+=<4`W%Er6^ei%DQT{X7kIqr3UMze;!0BcyT z6_fih>Tld~O`DB<7Xd$zf0K3JIBf;r7hSMN{r#w!*PdJxbAB^xPk!^4G)VpbxY2(# zp8NlKRT2Llpjmq!O9LMO+^ju!Pr)CM`+)S7PNC1#N9ea4LzKg>WdGyRPEhXyu>ZzS z&xY@r^qEZpnrjNmTxi#Chv zLarmZHpI6>(Z^jwi+@2M=h6Qw>%)@AjQmphZ+K5RkpKT^@#wFyJ{;MZY}fc_lzY-Y ze%f;~?1itS){%s8JYA8S8+tbOpY_QJy6 zgR=~z!CqG${#lY=#V)+`0VzAT4W2UtUVB|xVBsAbJU3pw*TPFWQ`UI!r`d;eYrKv$ z_{k4j7L-l1g&)ImYLDr}D{}6Xa|-ik^8aRPf8yVg{p;7hGv}Eo<{5m~2G4@_<5|!? zJPX=8v|ih=gV+nEKJ&Xb0rb__uo`@~p&Db=*eV;IvLA^xr48fz76I4?Sr2{*Vd?Bz z2)HYyEm(uUF|KSxDQrOvY^2Yp>;?WF5T3c<@9VR_=XX_8=hF`+w`7xG?K~FX4B9F*3!y~z$3V%TI4*RL;aC-EbgFK?o z)$=b&y))};j@Jt5FD3s*i&3GgNX9wfk<1bCAGZxY~*-2dX5IXm!l%D2>Z zIs1xu4&j8ew`knq_td!8!81@{`p6Qm`JNiS6_dxdUUEJzzxl=XRlD(-?2XQMwnRt|H14FV6^Nk;l+2eJ}=)N>flRTYlfk1U5il|i3M zp-&}RpAKtXGI~6lE~zrpb&2`ecy>u$;uwDLyR>OIV+I`}%+{d+lyPt-kNU#BMvm>T zV(sfdXSgq8#_(m@PF^yDJtbbs$LP%~+@k|dMdS4S8t@>2{wL7?1p1#q|EF{&EPkfM*^|(;wrw^B-9)pJm2%9qv=|9nu1v<-%SMd;;~iAH}G@knfTT{9U3FF*Jd=o!yo`Fliu&`xi1rMq3}m@D1oN_V=_ z?{cL(TAPL&ce>K8u5^nl-Rw$7TxpydOyN(XE8XBq*SpeTSGvxX zeupdlc2|16EB!WC`mL_?TU_aNuJm25^qsEs9jQx zMpwGpm41UOeTysodRMy2mA=`PzR8td>q=L;(raAl8(nF5jw$+bgDd?ySNgTCbcHMZ z8dv(&uJkHby4;n%&XvB_l`eCoSGv+GTf%9UQ`N?++p z7rW9$u5_U*z0{Qsy3$Kr>BX*ez?F7f=|!&e6|VHfU$&~~6W>gJCxQDEoG*C>r>nj3?nq3Cx;xk2cKhq!{3fDtbwbn;l-yLzHtqq;^o%ga%*WIlhjO*&U+oJ9DO}ww~?rDv- z)_3wg($g5}Ks&M4jgj{5m}uy3ZjJ!b+Q!zA-`F9#n>s{SBpPW%P6P5<+cu${CP&wC zHnulKSaw4s#w^hljYMRl%oL-Olat@Ok#~`=d_~6bt;=OB#KdQqkNAdV(Ino^NModR zQ^e`0kHsRLZK5&S-W37m-EDWbwcpd`L^?a$Nqk*hYg<#K2k`o?E~J;D(WPClc9tSx zXl!qIC+G&ME}$TricIg9H@>>AF4o=^>uhb?ApMA?%U538NT*XYm6ryeX>+zR%Ye)9$wp?k+uhdH-OMPc8U=<%ts~RmXk&`eEf9iJ-`3=GMLIV*jrDD9;B`a9X=snNIBl)a z4D`7kiiHb`S5H|t*Kcf%Lc^)2*D+tQS~RtFiEgDPrids79Q=sXZxo_wLnkBXQWwMw z{ccy|12QCv*0$z$+lwl=MHq9f9|v9+s1vO5Q(7d+$QYxxI|70_o%+_g=4kx}FtV+^?P`p-_DzvaX-KHlGht#a$##bw zo6-xhF|x58MAS#4?Tz(PMKl(}2ee4hwl+p&&5q9YO|4ClrVueh>R#*Pm)x_C;ArCw6ZK6$CUggDDr4#FD($m;G_F1z|hFNrXX!-3W(u z`gz1-2rnRn5M<3zBGeYSCq~PPKE!Acp%cxt0Zoyv#?ID`7%X63rtw-W+m}rcpO{A+c0)5g02zak zHeGl1rt8|Na51FgB(WJa1HUNCV6TCyrR;FyzRZ`|nD>{DBQB%&cmVLX;yWLRd;Up?9K?CMu`h+V;P0lh;wbAC2r-5j z4@jq7WvF*1C`1L~vCF4{#n>SsP9X3aXN+>YbowOX@^zpQ@vhr}2XW0?K-*y<2C6ybinB6&g;uHvc2O5sKJ{xDxpA;pVbh_@rZ1n~gkv4?;QG20tKOgcuHM*cCx zyTB)NQD1!j0y>U>o&l4Kz9Jp0hHfD~d2_PgwMe%h-J;{oh)cjf^0UX{OF#0nSr2hB zV#EJkNLPTL#9#gf(1$o5G21zcaz_!LM!PRCANbf_m2QtQ+si?F6Nt+J_dSjNF-H58 zr@1JX@S{n&P!3F!{{k`jAODo%|IU9^eBbqm;(HBZ@;B#`7$U%b{;4voc-SC}GuE4oJ z;5!4n$KMLvccTpQd~MKe;HxM?TMeim##p%?`dBB#sq4@#+9+NHorAqOxd#2d675`# zHj2?U>TG>G@V*VQs6>B(uaY=okk?AsDAXSXo>6!M#Z&V%aE_px2ow8(4`B>p6k!-) z5TPF-j?jS+MyNpuA(SFG2z~^CFtHEy5ylWk5rz>45&9A02ptGvgc^hpLMeiS;71S$ z6MIn~VGLmuVHjZ$p&x-)9B~Ii7@-Csgiwm$Aovjk!o;vFD#j6yA&epnBMc(+Bg7Fp z5W)yG2qA=01P8&7AP^>oKnKDY!YBg2;5&%Wj}S-bKnNq$AcPP~5gY_RfQ?|Uc%+b3gS2A~UzF0m4d+;%4Nf~TTmLzq<4VDA_n-cR8}1;((8uwQFBPZM zx9RIIBz$K6Nk4@}T$jO5`!gH;v^8%2+4R#M%|;*XmJpMpw*IU`j%lAZ%?%Ixlkkxh zgipUrecIA=mx0s%rn?NB{$0Auz-dq2{I&Z}zr)R+D&&~@w8d_?U7xnztzTi}nEIR( zW~mTPvH{9-D=rx3=+6NncM#59=LkKlY`|%3a zpBY~8+UaoHevC_aYWp_*>t4tDspG2#Ii~&5&~!Mn47>(&v%7ybe$L&q@*nf}Y;gL` z=`Pbg{p56)fz#hhcNzHlv%u-Er@Ksj`se8`1E>F=?lN%t`{^zN&%QYwG|B(sv%u-M zrn?OOmb1XOodv$@EbyaefuB4Joc?yY%g|5%Kiy^EYJHVDe(dqVb(LFxZ8+Bl=`Mqx z>j?Mw2_eV8xsGw;x5o$98|f}npX-oxmw|H~lI}8au20fk2HtZPxV^5i@tFE*Jvy^} z;o2MXTgv>s!d*3xX zoNM^m_`|io+dnBrj-j9X0<+cUeu2AwDRQRj$7Y9fpTLdZZl8MwU`^>vMl|w*DPC3tYTs_WIlx#x-O6 zgA)F}6u3RVp1hCMQ^&szkG_xaRQqkq_i&u>RQ(Sj$ME<0Ez{xKEc>bUsZ-}K$EvUP zb5rqev*07W#6Por_gCHgsX~sa&;8xm!TG#kHaMRv%m(N4 z0(bxE5*YsTxq=%WvfzCF;MULVK(aocQ%tMxB;kC{F&lk+Ug)lG&;JFVCVcv3=q~`s zE5TS4@IuCzN8Rcq;NvKw;M{LLlI@273vv{k`-v4fZukug4V?RJz4ocn2~ z<`}3X2kn0b98>tYA5^=*4gUsqVHBL}rCzjVE`|T(9R^N+dFQnH0pzOs^cN0inA)cO z74T9u{>^x{b-o)u2`@y!Ip2-Vcfqi!ehkF(3a}!|2yVo!n0L+7xLy9ChHEX!vFq}?+>4}@h`vupt2!v8#o{534a-upXo z64g`5B$y-Shf(w0sFUlt!*flpr`8)6VnGiwai8&urxwq*-}-GJSkD@sM^N%2U|%mO zS$IVz^6n*s4}ft<_? zKS(%_ERdzXYD(d(G6n8g^^7bB zo#Xone&^nfpWh+O;}0^wgx^d#G%}Yg1qZS?H1LUbLbJ%J%%$JLtsWYgg#u+V9|S@9 zS##@I{&%mzYrONGljVnbpTqm?tiKE4{(Rp1h3`!jNL;`@8{ga;aeLuCxSiu8g3Q7{ zqWGNGQ=w%~=e$An^mXXzoa*<>#xqv}TXy!UFR)M^Fl4`m9T8c71P`+-c<&QA_>i{n ze1!=LZUALH0}T)}2f$ytP-68==;M=Ur9&Ui}sppPTYGq4kN z^I{vBM>1$W7U1JRzr^w-gXK1bMJ#-Z zEO?Nm_)u_ImbxSZ9o-~6+wMbC=&1iFKt5!$bETyHp%#%lj?CQC{KXca#D`g_EQp^P z{zUoHj~|gchQ@PG^GCinvG6`Jzmv`LiD@N@cm`rVO_t1minzvEIp;%U?Gsd1K0YO> zo`J_$7|QwtmGvc-4KBq`1%AXrK?V2_EAV-02(f42WnJMztdN-j6TTU+`5xHe`Lx6F zQM{v}rL5+Vg-y* zf$$$kV{b%VHnD<=v;~=Gkl7(K4HfwZRFRdYNLir}coP!!Kx2UmnqLd3E-5ahP5Kmy zUe=BVjqwhWVAVVEuW)pH;x}NHHr|_8E8}gvy!#j6RLUKwteumOL&v?}fQu%4%A9A= zQf91pBXXpllI2^C+brKZ@H?lG<&;g%_GS4>k<9ofw2-m!K0>tF)fQdN3qCb306XUe zRHkdUp?5e=BY#FBBO>DojJD#;CVDMne#}vm`C%H znZx_+d9>A;=kwk#GH9zaFIa@~8MM`z7dGQI%SQwk`m!$KfcGx|2ZaAQfZyl$;r_k; z>v502t@sq8tjp;~WcmITzw_4t=|0@#!aEhY?1jiELyfE@Ps>6)rZk_~|2Rbw`E5u}#yUqpQL>+(DwRfS^+{Rds$hwY1hv~e< zo41trlr%8mkxSRJG9@gjR*@@UQkOv!+FA-&USmOu~TtX62lCW2pmRK@86xcH4 zU5ZzkuuPDc>X`-uJeeMH;G;}(`pEK-3kQ(AEC(odp}}l6ILGsSBnt}g^F08?<-Q`! z#kjcwuPO;owuiK0%3932evwlqJ_usa|=>nnP&y@ zZ2{yZWG+2Ja6WLhYVb+}E=6Wx6@Kp5kTL^lA|#HVe{n;oi;G6_ql=272gvWokt00I zvy6&9PU;p)rFxuVP+IvoCB2Yi%JVoitC(`wML85x2A`k|u9R-lCt0#sD&41udfAm1 zkTsuX_LVD$U=MGFxayNk+`=+EwZlQ;8CaUFSau6pb|r{Xg1Uu7g^?`5YZ-be_)#Wh zJJrPTRV1(eDp9_X_`MHRFPG%Xlz)y8%VnS5#6I1`BrUDy%}0=IN3w)3v3P2jd=$x7 zQFf=Vf>(nK&z-j*t8^S$S-&i~5ILn^$GxYa^h=DIN@fwz0@e|&+t@stA$jV7X z$546YT#)w@++4GRg%%>^eW+?>fPFxh7gd))F5VCNy$=8k36?Cwca2e;vU)$#)kt^C z^quJ0l&TQa0npz|&>bGBAjn+04Vi_z@v~Dyq=FFgJTjNQz@JidudoU~&shzHk^Y*M z?m_xRE8UOuD^_|N2+u$d455dSUXV;L9YcE2N%l_lL=<&V9ppJJPY((z!#GX>=QRMp zJf%M0SL!3}*^5%EI@-I0N8Vm3h4~_dNgKl%w`duKe~gtp|1pL5m_d9jiTEolqqOy_ z#Jfyk8zZ(WWpiUnMT@>ilut^OuR71r`lK8okFgt1vK+~NGKu}EB=#c;yF~d6?^Q$3 zD6+3|h~jP*=drZi)R=+4hYv-YaW@CRI&?z~fV@EAxIU%3@s7K!mRmViXBaPY@lrK7_36uf@+b z%v||;-1&g)8Ua46xC1GUv@qgIrCgQfF(>FDeSCCjBQz7LEN-$wE}YJd5ww9~NV zY7{T{4YGV_wcuskT+N&B<0gcg%T39Z0^+zGIVc!StYSB_3 z6$P!grTYEgCxC6W->3KYY0J*6$E>wx&6?+)J;x5yP$jAvaHa=d4YuMc0bf&xE669sQGc;7BW<)Jt5acSm%u@)%3h5RpU_F@esd(Ow& z^VM6%K`h+9MxkmQmlU`eK(b)e`YkEY8yH8HO1{*WkWS%J$(M#LV5B+4@P(LmQaFJ7 z!c5}_OSx3?MK%NQajE1>e+S8=00pE50=eA~sA;lPN|U8hnk<#l)KbaErBa}{1UyNB zay&z8kqw%xa2pa~u0Aavmr8-y7-1SuCZZR{nV2O^+r$6G$9_C4AD2pjN^T`51zJs> zyW@EfQb*-+WT_Mwv=3YnE|mg<+bAoAOQpaNS`|p)QYkQ$%AFK0l>#TSfFaArrBYxR zHTbwx3Y_!-l1TvyOMi&NO_(*UqT*ZxLk8z@;Wt6HCuUNE9i|5RyiBUF!&G5U%A^iE zOda;*3>syNXSf@d^(e*WvG_dv%#p5u;JRN$e4|c8O#Xh=3GUl0v;T12FdRH8mg7A zBMQjyb9BVrM0x?G2hn$RlTG&mvh@d;*NU86fajwJX~$D0oOzwV{#0Ru{!Qpj4Ph$? zuL)t2U4uM)s4ROx`N(A1;>mIVgdC_#)WG*ReKa=ZA4W(8u)_qagw_Eb=YeMc=9`Or zThuG2wLmWEDyo2I<*72|BM4VpZpi`GRn}U%tma%K$+I3dV`Yvml5VS^+c?B_mnCBV zl>mL~CKO5&7+yCB9y@?ce^l!1{xrN5NC%W73h6qGgeVAE5FR&0*oOkk$%SA)HbSNX zd#b_){kwiZvXb5c!r4Ml@J7I2F^tC7)V2+TRwI`M7j1m`cC*38wY>%GeG2QABQ)5u zo;H%V{y>?~2FYb0{9XvE;(aMbP|;|R^0EAHV{wB1Z8{h1v2uRQcs`xqC9re0JHHoD zem^5LK z6xJ=+9w2YitSa7Gv0K6qBH}fpf+XuvT5!STFo@JW_-l8r!|a^laRJS)f?>++3uyKt zg3@j;U`#y%uvpe77g9!#WW*QWr!HfhT{s$odiF&!If6tKiSbP2A#n{7MZ>{~vPx4l zWm*L>(T(8fK7a9S%brGKFvDM&w;Ie#0mL%|{fD*lJ0NSLmenCeRQ{nXE6Bd@E@YG* zvC_)f%UW8(uRoeWu{*=)t6AJ7EbdQXmn!ZO7T1?sv{Elc_+$U?uf^Kdx^j_5GFlnvruh^04aMdS3(V zl^UzMvR3eJ0`^9YmA=47>`q|6Yp^Dg^Y#M!guzOu1m1$ciJ}SiPl^{K>kYbW4vWE$ zUUuWJ-MJPkW4dh)i!nCC6k`sHv4)^T$s88rmjFv8O6F2Vw@k~5Z9^3=g$Py6m&U7k zD->J=Jga#X%bZxv&xv`HFr{_f(GHnKb2LHPrR0<)iB-msx%o`0sr$K~Um{wq?0(-7tRhPB`@I1v8^ap-Ob|Dn-6Cq?(VW?y7gfTQ= z0?j0OE&ke_G;sn=yZ~BN%?QUj8u2{Xb{}QLVPJo!ux`f^Itg1MU0Dlif$eIBm0ip! zK?bKo>iEVvr|XFjxOq+`r4Q~l!L&(Fgm7SjGiv>oJMcVapT1Z}_j>#8cNwDl>BvbxpG~W9r zeZ~GefYb{CB+Zk3VJr0o0`mpHOY2hPP9BIJ#tIaTMY5LV2t*(#c`(gL3pgczK*)tQ zZUGeH2AUP>9FCd_-Glj*FVv$P{Gt9>;U{mt;&{$z#f@#ifo^dS0&4m`gnBhEI4P-|3r6|NtCHcn~l0Q3z z*sLB%{`@Q?txWoq$gJheXJx{Eixh#AtxW3SY)D|g74AO{uUVXDc!DD`4*qubP&+EA zmHM5ay%At)vHs7+fi*z5=GC0JDW(LtArF(^LFq(BVM+)+T-wGvS_=QG{Vgllbz=!UCqkfflz8(pqEPRn(U zZn&I^={B;@Yr+nSl4RvR4u{y~O6>n?vE{DVa*tTWrNpYV5?k&OTW(WG{+sM`dfSLy z+Rp;#?xba>C`A`zE<*cHaTT57QKYz(B9$%>`%jhJ1!Dgwm6pZUX_B^b7qBeTl!_l~ z71LZ5(>y8^mr|k9O2u@KiWwdiGnI<&^;Gd!7RXLT`zb^r{>nNiWF7pKRZt{VAS^{v z1ClJ30{kzd)5>i}1lb{F=XsDqSA<+ULmoR7m$Fl(m7Ng@XR8Odo_NrY%Qd@mD4J)_ z2|(>eKi;zmi7-0Wo|hqUA`@34(Zs~pkhmR*=mkh5{f*B%OZK2q1Rx>Gi~$UFcSe~L zsmXUr))!3H_mL=NCQ+7~gYo-081WaBrA!S)y$%2_<7l0a@kt}CSO>6up`y&5>|d9W zR3;PK$>8Jsq6{wq{OfX(tX`WXvy5rh3I9!(W5W<7@>>tG86h`6AZ0Zbobl zv1@53vS0*%g{I9B8T@*-Q%qZ&tW29DrtLAN%@Na%#7$G#D$s!|(-d3}Sef>fxM@2f z`b-Fgo8qSReICd@&WKO6uLt`HezyCx7{)F2p5FoLD^SvtFHj#~VmA`MW#V}xlDi?X z4+)+_jXs1#(%<;Jv+^xG@shLT0HTCD&QS_bQ9=nSN+@Ef5pfF=rOYf!e*~zCnfp;v zYzxfl0WowedZk{w0ZY78{xFUNx>?Z22^O9hvU+?Bas2iegBJqh4Hhy3jsK4{qZbnC zc}Vm}q6Ud*cO;Vj#^;@tBk=UCYpJZ4zs=R>;qTdCs;R)}jw2xu${7!X6>UHT>m)Z4 zeCwK3D74_MD01kiv3js);MdM`(Aw?JmoRGgECi~NhV(+>TTBc`;#Wvi)**pacK;gu z?H${Kd?%%dFXELQdk)A68aYU-iR}lnsVk>-ie+7;kO*Au%2xP0AA}pba@PR)U4_Jw z)(D;e?9+n9Y8Q3lAXjThQvECS(hpVM1eB`t5XxEs+DD;kM6I9-Lrh6CFsSZsrLiXmR(r-FQ^AvY_s z>*E!mK4z%nyHYoR`s=O=`#uP))q_LLE~M5r^yjY*Zz-Sa?b@5b_LI;)DY&_jm-<`v=Iy zjjjWJ#hF?u2Up&o;Mg>588$rzVsI^e1n2^&8;A=b0rvC5e1aTmOF7xO0#L1ttYtTW z_d$SzwvGl4z)6rYSk|`{6v$1R*mI!80MJJEADACFP{PXWfMxqZCaHrYdjQexkQA!{ z{yddUdZaihHV2d@p{QYGy+}9@3x1P1a}^}428%2dDy;#pj6sR3Sz_Mkq)Pl1Y^<=v z)hzK#@e)_F#2MXniK|)S69K6b_h*Tl0S?-Ex+-xMq^J@PikJ9#&~kx4PKnlJ$hOUOGdqWEif{uo(U!VxUtt)@sLSfuTM zhVXWapq~>ggc0UAJj?Vkh6LG6fG&)H6R~Ps%^A-qie`o~5nY<0M318A-x|@QDEbIR z^J0vkpF?z_XpuRTLoqijAiU;u2(P1XW{HaMm0EZmg%=mTy_< z&>a_3^lT&gVv1f((au<})voBH>~3aN&Zcl?iQ+E~Eo;&k@;NT(IrXY?%^uX_fENA(vA!`IY2{wB*Yvd7+VfIVJNGm?5i0GDjl_ zrDWx1jyt+JK1!)yrBw1NscBfh&=+5&)Q61JuTtu-D0Op!y`zp}Z!dbHm6FM?B+t~6 zTPgXFk=#njIXxhGcY?i;e3ZSpY=T!)DtVRE9a`$ulsX7<#J^Wl>Lf}%AX0T$_?%Mu zf^%NF!0q*JWmH^8$>dkjoQEY7J#if+FEx^{qvQ>g%S@2v0kXmoKE3*Hbe2mDNAflGju6-;Lz;lw8ykl6i?u z+-f^6`6#RZNRQk~+03!erqv7clt*r*>=BSAzP^>R=K>l$4(`)R-4^RWwpcd? zpS!4yZ31$rM#d+;JApi-E9YJyFHuN*Wc4WJ$b=?#5QMLG<#y^VYn?)RCcc%xJ|I|3 z*2-XXf-R##{qa$G8i9R9VR6!CtE+bf2!|BGodK^0G6i0NV2|Fdz?KUZdPjEE`y8kv zy5{M-AJ{%c<5)RrJ7TiWX+^!OLAuLSn9Je;_cE^JL@F;HIsmuZor^KQWX#?RrPfWR zhVEqzJ!xuai>{%;vdwlss~9uL6J?`Kj<3E7&YD&+g)8Kb#MWb)6Q6m`v0|ObkPr2y zfteY+7266*g-}!t?g2bjahj^-i)>TD2SA?eviAx!h)`1-9#(6>8T7%UECMfAisG-` z`7`9D4<4lt-ZwsYls@PNjv>5e2_JQ+9@poT7=sgggnQW6$hk)Hza^46`=#W^DR~HF zN&G)f$qNA0E@zwBbrXo+1~^zYpq}JTH20sDLCjDHFzQqgwWE=20Of3$>^`2Q z^LVq=^Z09bPUGwjMSPY;{CQLt@mUrzyTp{~r>aaXDuSMS46KNRSTm%QB0mN)ENNh< zn2SRcvV2?DZ1r6Oj@TwVh6tMqhuwh3x^S=kfMICRZ#IfrA%8$M>*GZl%WJNp_-l85 zUmN=(jje@wQXenU*z*7l;e}T?YA}-WU`z~B6D#?0df>MbK44WslR4Xh2YySTmm8tK zrO;a_l(%Gggq9s8bO2*=ABB=t3B6DY-AAF@jL>})`Vxgs5uw~tV*QRjO6Eu!`Wj`D zQ^|Zl%Y2P8|7K*qMwx}Bkhv^D=IKYte2>xk24#{{jUH*7{Gjk}Q08z*5s$t>nbRnf zS9rOj$2f5-H*nzAiQb9+KUiDuP&RW!@z?Hb(z4&7?5m9IcPRT#%I5W7?wA*somgeV z*3uK>Wb2d}_KIk36pxeL*jGsZ$R~L-h(3x1%z_fVO z`csoL=q#>|WFr`XTLGrnNIVV-rwZIgz`XoGH`iXRfRQmVaIHul=Iqwr((qKTMf>2J z7M{B@pXVf5rk$|*UX1AsE2zE~<1xJ;4?zagry&^#P(UOQ z&h5b8bU6f>E{7n~O4M%nQkZJE|uwGrk_MVU#yLgaI0r9B?$ntxktN9YwyD?8Loy`qZBuW!2k9{1 z+orB-k8D;>8G*h61akgFS(O4fIfE&nN`O$#0#f?< z7~dH=cMzyn!g4N$=(HLi4a?8jN@@Ll%b}(Sh1du7K!D~4`8qo^k~)KYogF&$X7B_8 zt#}5{gr?9a24?QLr&^IHvvqqCqU@KL!F~};dFWhU+D9d_5BOW+R6PC(sRH&RmTh$# z0c&jeMBdI1;+T(2hK92f$eV-DFoqMEKM3~QBUqiVfR{-G0zZI_h3_--B&uYuxEgev zvrR@(pnK9jpihXQtKCV%CKK;pw{~gqTnd|V1E~IWTUYkL;^TZumyoi0zBPAKLGd&fwe6#Nad_RFLt}4;7f%P-}U)07B4ul`-(pqzH2aD8x5Z5 zR6M@#5!nKGx4`EyqZWtXptoMp*pz>0Z0U0pZ~%|LDH5wf(_*2s=?Dyn+*r{_6*(oS zLlrpztE`N*G05iiovl*y{8*zGYJQNt4{o0VxA$TQ4YCl*hwu-_MKS5*OcE?R`gGp^{;p+xcw*~>06 z%F}-DX~}VY6})H_x;ZIi3r|9=1OjaIy|dW1z74Ycuu2Z9&+bga)QIi;+xviSM*Z~6 zX6=55P43SG$1&4pw$|hm(3Yh(1;ht2s%3vywd^g@3EWHZBfzOT0RgWA*azdV_3c#C zkNi;eBb%2-SHsGOV54!@g!52xfw9(%J8>ScuL^dOUF$a4R(PcYqz`q58{%R*fsH^N zd0jDEfh{`<%S)Ng6zpVwsvSUJ;v*}zSOyc%B(ULTU9iI75Keo-D?xfR7H&Aa!!NJU;lbb1Wo==X1!JO9KzmbY zDjfF!4x&1bYFMRPpv>y~5bBV(?Ct|#cisWc$|r%^huW$72@?Kw2d?bHdp24OsaHA9 z6A)8PdUW_?#J?zzF0OPU;L>?`#5(X`Y1$wf#etHq3m@k3mTiihBTV>uJI>mdV^}B9 zonjKd_Nx3VP-CFC(iemjB&tG4@cZw*VEls;t7Wu9*DYuP?`oxxPzr> zg_t@BIJz{Qps3PZBy=fFbSJP21XcyvD_krH-88Y$V?c5{++vQ zKxjZ(d2AP0*f!(6gf-w?_IWqa9NzjoUd-90&AEx@9Dq3k<>;|+rSyiWjZL_Q;U>Dd z55VFg*3B)<74&a`&f;>0-iCdGsN4n*91+En6`4&NhqPb_H%VZd>c5jHZx8aw{N8UR z(J0E$utVB_>#6H@l6VWXvbQ;1x$pLUKsUf5Wv_7Yt6pXA?Ua9g+}=BxE9l=Cw|C=O zK}2b99c06giu_6Twjz(%hou*dq6`f?qzyQW6T-Ji;;q>E=wR&5!I{e5xAy`4JsQZ@ z;BS8&-9b(tSbxX!;F3Ip0IFvA4nqnXzy4%!DZlDYcgE=ht z*a_uN#g9q}JKq$WxUT{BW+mDl7LPgd*MV}6P*m5w4Di#Ma|AdMrk?QL0_yWFcj?oB zqc7v}XBQdGm}Xi3>%yfKfJ;Z>5uJ)hAxeu<*n>p4{MK4*1@OdiJjJy_KOm&KNm(${ zK~if~mcWw?9JFe`LU(7#98c~oml}L4OHCXzY*yjjsFq%=!VH^rn9>(7h@=ixwmyK% zr7z7AG0OoDmRiiVO*IadYRs{9Jr0(7%(YEL4wj1SW}BMai}Kj8A+aWNEyo6S^>Cp zBp%VJc>GcePpCEEk6mlEVfHZ7>^tCn{`%H%{Ixr$XX|>HCiSo(UJuj6?~f9GmDQ=> z-vEwoM(*>G&-9wd=$VGdee*-FV?%2cl|-PMfXcrZm5rkE?{SrlqO!aa7V&P6M*AGJ z(3t@HOh5!Zk8Fd7u?)@jC77Jzv+%+95WEaGF%fJm9XbOFPMm^gJ`%$g&&5&eIW{*p zz>Hn!zp*1+DdsE#({m7SclOEE9#|>n+zovy5?9(J9V9FxzRFl$1z6Udts>}Lz+!Hz zn7fi>Kf91to3rBk0G}X}B-B`X-6ii-19BF)zi{@o4Rw&#d{rO&}aG$#qI z5PqJly8cO4={_)(hGv4j5s&AET@LI-I{@$3a2x0w0UvhZ(rtjFd+|s?@z|!x^daD$ z0`riU#+GJW3?)PHz#8FPJZpzA6t;+|{6&Bk;P4F<@(t?FGH($VHlYy8gNd9bV*AGAB+LI1jgS4BIZ?C09Nb~_Nmy!C!4DB$&%!<~)%Fo!RgJp@ zKC{MDqk?_wrmAXuQuHn(`4k4{k8JMcpcOhJK`%)uiOzg7t+3PI_}V$ha#yRY5k#4K;5V|3ewG1xw;Px z5N|;1a$RP^J(AmS^xx z`V}6@s0HTPi>Jek!N3qaQ}p&WuPaGa+uN8=Ag#8ynRZgu_BPY{>dIi`j{xNA%3yjQ zWDUyYFKK~D?%9Asvb`O83cKGcL$bXc8iMqdmVCUF^!|OwoT9I}Y@=dc=$YKG8fYt3 zU2}OOoN-@R| zD@8WGQy+Q@=u~cer#`$BNh_5b->F-P_E{1779C5=|7kJLx%wJ2byFG2`%u3@^8 z=_K`SPk1DmVJ{-`2>3TkVXp|FKp5FBqGNsu?| za26$9M6mY&fTQBzc>u)~)9H#fK*|*}sNgPu-8MiZ55?xT;Ihz*r-BQUV0vN}o5BlV z$y+fSUrB<6-(B;=PhLF3FD9?Sb0W4R@hLbsCJM(yerIA8JP$;{TYNZk@F?SBI3H8- zunIPSf_i397q-*bg|ufAXe;p7?)(t4q;?mwcK-n*ig(4?MhyfgGZe|SfZ&N70R+4a zVBTIxdQa@(B5JbwI8uL5d!AJgnhPyi{xgy17AodX!AulS-xJh|Z=vEH6fFbOEhM}L zFk6PLTi5~A)@tA0Lf>8vC|BmMyt{~TmA46E7a|`$#&3jWB~cLi3Jk2k;~SbJ-_qKH z^hc%LCx8S`^RfdhUYTp%6guk`7*zNSy~`13SnV)NJ}ZS(!Knb!<^1=M2?#IA+?IZ~7dS(F!n&pQbGNyx&o$aldg5gd6b z9;5M~f%Hk?A84Q))Zp*qREUAu$=bljY0_bcQ{SvV{ww4=bud76Z56xf`2^)QwI_ZD z@K%6g;S;ow-_TWLKpL{7_3|gdrb`t1*zv8 zJP^BXc^K1bwPO{&%I5V7b?{ewMoTGtjxNP3EX7dhP^EZBMGt=e$O(_1Ek9M2kPGdut&vwG!6i&jIXhbKLkE+0`R;s z&4f$5jQQ%l0{wyc7AVC=pL4;EK7UKZUH_ggIP2UN!&B~nqv&1PwWAF#O3L!Bz_ z2OJtoPBg{+fW+f#P_9+)&#HQqMhj=t@(qMmk?+w@RL1A=Ec}{OP2TP;GZUk%Ea3hl!BQV#J2w zpL_`)l380bVX3x|&4P3SE|r3WY?fp<=~8iFn>F__>Cyv)Z8o63Cjn+j!#0aL8DN<- zoQO?tt^(X+EsWU+pqG?2%ciw=fsnTqgu7s0ys#!hyVl+wFm`vEJ+&AAA{^x&L>E?w zKI}{C+FPBf%UvPm{t5J{a#z?4*E}o*Rk zfP3tMGS*?4G`#*&u7e=t9RT4H=x3~%BH?0#%TRx{cpR_Mm5gOU>O}#6yDBObI3Z0J zq+SXV8DR=iFBNzpVX44+Daf^eRRz{dK^`W|3aXcaya7-ZM4egbb}|aGAIjFoE9guq zNG%9?&LV7dL%-Wcw4*JR0o!vT9>)p96Mn%!oNn{?wWdNW&PtmyOqViDgX~`QTxraZ z!hVgq_JR9WrAs<}d!SX$U*JNYWur&0I85i9OANdVnXiCXn&-KU>-#C94#d48LfUn~ z48Yb2XVaQF_A&rdB<+~wdy$>Y}S0Zv;}ID|sEmBzkxqSHUl|vrqk%TfqKq|r0h8hG4s5Eg4Y7f8%|!2;E90C`DbwWL)6uY+%Ji)N%jEL z4&>wB8l|S-IS>op!UKcz8(_kX3^2K5Hr;ZCDCg;lwV>Obr$>zPD@1vpQ?;@yL|FsC zyh?Bn17BRhR3Hjg;9-@lWr?nqtm}cO6QRq&Tq^zH)uOH)QhGlJa_^TV(?MEty<{Td zY00!Bp6PnY#E;_o)GWoN!5-DU<=59r9-`K7i2x#sL;x?1kv{)h65v;lGDdt$5tLV)p`8hr%3~V?BX? zDSQC=4LpzW11VRMs(&EmPBL0aJSnDsAf-3k-gt_#arK2S+AndHz3fB6mr37FP`iC33RB2(xztO|3kz|0-J z5`HU%o8kiLRu#E`68K`=;&0<^5D5i7C1EHfR6#=a1kip8xe33xG6%?gU6HGS{78`K z1w|jt*FVydxfxW~68@T=rdXlNXviq>(Lm_u<^H3@6FKk03L34ZlxO;}W(Y#V`7o^8 zF0lR?{{*uYm^>Okayfc+{Iw_W2YGUP<3U>X1mJH3AitFIu~wb^Ah34}Ryxt_-GCo8 zTpt;(eZW5Ja%Fx9SmYQEE3;WpYJ!-302Xt{6+Hg5xAz(`7I<@i+$C30+=R3&4mUR)`yl6C9)@qTetib91UGiH# z;v^-e=nZgwjBLf2j#@sehwLPFqaej@J&Q3WU=7K}Q+0?RKruT+{!}D?n(BKO;6M<@ zBi$jIokZ1fje^wU{9+V`R_+)a=NF?)m&jje@Xf!D)~T&Z=;3efblHkD`;+nu4f>aR zj=3Xg`bIX|fA-^1d%%+_+l+zK{s>U{)rCMBjj`lc7Xl%s)vqoD!c6OJ#z4dZzia{q zhdc{>s5N*R_hHhw2^ef(5=~+_{>;O_$T~oJ6EJut&YG%Sv?SR@OA0InBK^Cp@a6Ua zq*=$y>AQ@UnYgieIbE4~t3Cq)i6VI3$p2t~myfH!ITQa&cw)+Y^P*$jULNNsW729c%a@bA~ zc#}ljLR6wv_&l(08muWv;Xz<+SeeM{Kmo5FDdG$TBtDevC@B36zmZbB9@qp4R%|uO zxDDtKA`N#zCSfwO9;m#rNZgJ@BNLmESj)u2NbF?daU}S$WUptDa4`Ko;a5nMJE$lg zNA2}8phBR#*R~-s9uNNh8Lgwqjevilty6(Z>o#1~ z`&}=1WgqTajNo7b;>rT_(M~bla?6n_v~=(zQx6d914W3p8&) zmKwAzd(7cfs806LA;oz9lqO{%5gd;MR}ZyF^e1nx3ZQ2I>cvID%}A8I1EdxBPW7f|n02ywmc1(baT9Q-o4R;7r8RevhI)talZkEF3}D2eKQ zHUaysaEl3lmMu>NzhTT3JdBqg&r7J1Z0n{$kjj& z6=c_udm|`yLQ$pP379{a!7eRvjDH@KMIO$BfY%(8(}Ah-BMCYL4x=<%bWV^8L)T*D z@W3^Ixv7YTNu86hyUD_1V#AjR$Wbu|9KKeIhjPJW+O3}Ypws0$hZ}@l+-Oy-RT)n1 zl0kL+Dg#tWdmou(RXnKJ&lmRdyj4-LOOX~Ul7HPuQ%QwItI-MsEmztU)&joK15W|` z1A&iItio1s{9FkR`louP1DzoJ$q@MMxvAafK=`Xi$9}-vNhBSPDt5m132w9o+|K^F zoI?qJqP~-TTjzaxz$u>%@MJdc@t`${Q0#Ne(`L1TFb{+!S{vaGz+YF4Sgq0qV2d{a zYpN2Tbw7#EvCLc%WGl=y%?{*}DPtWqsU)u;cDex6M< zLh!RK>XHJKDJMw+a*`yCn_EsW7C~Pf;)%i_=dMW8CBa_jliQM?2o9d`X8>uk%1cVc zSsyFJ!z4**y@j8LNs>ZLJ0UJHlH@lU^eQhYQUHEAOp=s71IeTS1%w01x!2-vL=KZg zrwckv~5Lr$yw3;E3E1 z9FZG>BTr@Hly^jK2#&}N!4bJ3IMVtgrVJ6eAvhv81V(@*9Ya+DsIMJE{e1ipMD?{}s9Fh=uN^}*K1PZ9+A-AM z$6whiLXC23F)2Xz$>qHX2YfCBPg3A?Jk#Xz-bng2NK3nmWVr1vlF2=-fC^+LrEhR1 zAcgGABA53@vSuQgtA3d=y)Z8bQL_+R=|!qZ@|9+~d>8D5_{)qc9ZJVfk)-#S%2K6c zlAYd@Eg~oMYjQ`~PVz(iWk!`Q3h{+;dI^O`RiIQL*^PnnF*aiO%Z%xz_tB2avD}yv z&B(iwcJMG@Mm|ewQC~)Z1bRAu>LH^$CFJKpcSa$*fuYfS9)-@}kMdX(qE_G>NXjT4 z2(G}JO!mAH$)o@U7u>={O>cQGVZQ`KcPvzT+w40FTV~<)P+xmButoCrt5Vnsz*w-G+f-`$hHNb+07?~-qa@UhQ740mBc>R@Jr3_B#lSI)qC<5BYMv{`v~ z5q_HRV*>w#a5~|~1wKT09^oehE;=K?<+Lyy+s@O@p zrXtH(l0_A#1@LqYQ_&j0OSB@|EsDyv088;HA45E@g~7Z>ldR$ajGHEjldWLeigsgn za)rcrY?63<8};8y;z{w1I1BM3r*bc`*%EPNT!qVQ2^W6cd&2nZIa9(qEXBm$r4oCa zNgR3u)?^6mQ$Q@gq6xbOi^Kq2AyYOLG{g&%4485BnA4l(=L`GNsSrB}xqvn`&gxqR z^ddpyE+Gbju5r3#J!tC`%{X9uWgP~IYTvK;N($%@0pw8v?$QD}M8KaYU~_^1wpcBofC7e#0P;L2 z7EDW1@i1HjI1^C+zaif#HYq`W^hsOyFe9awYrzqf7x<@&q;mk5?t{1ju(Mv#d3XY` z6;$UNmi(L@>R!nMThPBjY6`b#YM+%x!N$`ogi$YLBLQogmC4SM7s<+W!*BJjqm6R) z%@nXz+H~esA-woTX#bX7dlT&HD?Q`y*t>TEtd!I2uTa!>g7Wpt?+N~q%+f9HBWRzE z?GWij|G-WY=Q~T+L(AV2O6ZNW2SLq+c9vgy(0HMq1EtzakuI{8A+r`=l?eqcVgiFD z-l|J$K)Xn}yFske=8`{}m_)UpE}CB*?MNtb#*0z8TVEe&B6LFp1fEs(25q)dqyeu7?F zvko7ffX$5$ubw(k%jV!=3RC>clc7i5eZB&CE`{)uy;{%tqUYhWjh+id&l`YC9|ZGV z$J0~22UMs~t)cgeytneU8i*!-s;DT4D2Lrfhy4Q*mBTveu-bE=An;9u1DK9kkm^cM zCHg0z(YTtzSP0tpQ4<+fh$de6%Bs1Kn#Mx3(sVyHT?Mdo23Y4EPgChKP}_y78jzH! z-&$a;-VdD$byrf|X28mKf7a@*q&j|Ouhd;db-xB!`Z8F5o1o4NC9MeHBcQtFDaTaL zZl?m`m4b2Usyyvf@H!+a1*@o_7;jQbYp{|U4kp)gUIi0Cbrr0kf;Ch?yi#zVR3S}Gu3DF|h#5?o6K%OO!ISWN{F0W94M){l;> z;6qU33W^uKN#dD;kMcjpXD^ z<*4;^6hEO?j=GtS`Ub$#m%&;Nreha^Kk%o9h=fKmf?dn^Yao&gs{guMYx+Jl{a0Mm zR%-e=H4O#py5ni;Hv!bLIigOwQL8t96xBXNB`bhlA*05JS*kdPsN@fECGS&7{&{B9 z_<-ZWM1nGE{FUI90IOtj{h=Br>eLwWza-uRVks}v>ks+I^hD{)pf+e~;;8W$CiG#WF& zvh{%Jezl~~D}j744uvg)V7eOvTii){=>$;63Uy+jb=xlRHv=!kodXxfQ{L4P2Fr(7P9?`{AbnTakE=iCsu!Oh)24B>EsRa06yI{LE39 zF9N2Pm_f`jh}?t7S-Ry`%zu+CPjaheWr;-no(m-r+)Z=YIY2 zfh?`T<7}a*Mbvn}Gc`;fGy>+$v($ttC|d#8XszMGem@ZFEyiDJHx%d%pjNW1hmrUN z%laTn_De_@Oj0eOL8O&6-lnX@@)L7c`M4YU@_~Iv^c`b%R5mgp&o*7Bu+tjyDuc9< z-OMsDsXH=?@>GjxyaMP~VNB_6(9VIKa8uC#pmc^%?se6EaI_r7;Tbnet#9GQ*ijsw zswvF}$2P;E29qvYYQXWEqd2@;>cDa2C=QR7vN_-|TLF0atO^rfnp>INE3SkGWcr?G zRlP_L^`%c#(K9z6#Q-;1@V82y9F=GT$~!O44o)IXZ6 zj-&d0$z!X8lV5G($CB6k@O8B>xMmRkILUj6R6Fj$z_k>qKE?F$5<~w}RN~_Xe_+5S zB-I&I9y|@yZUr0+Adaxpi^sG0=kNg};u_Bv@Jyjd9}jK?=D&udUme_1C$ECBO!!$& zUIoj30jfHc8tnC5Bmf}{Yh-r25Dk;pg{t@S- z2-p2S-d~uMJ`2fUfC55+)ZFXvH!OSdVcC-p%bt8#?aBLie_`_bH$YNE?k`N~^IP)E zZgp68tHZKe9hTkdaLELS4$E$JSaz$!dbc{PcdLE;jMFKe41uY#Tb=Synh(}srv z%ElX3u%v7y+GnNHYlTQ=EJq@2rON$cSz1^KDm-}J6`xcZWOK*2G^sFpi?uYGe0)Z@E?uYGe0!|h$_rrEK zflwAN_rrEKD?cNPm-}J6o5FIkc)1_8yW7B)pS6|J`ulDNr3f+eI@p5&y3fbU{ldH< z*z)mmzwoJ#0vin6jc4|`r&<|N@}}yIZyqs~;ErUt!5zu;q3giLw+KN}+Klr(@Inx? z_?SJC^(>O9&!7vaNYCTPnQ5GKq~}u=K4itFb^&AAN#kx^cHagj zi_S+f7-0Tf*%nT=$!T8;1b-zh*=CE)ThfSa`lj;LAc7UbZWUpXDe#(X(J8)*02j-I={B3jV~bARToF)5B0< z4>P7&-DOYhVG%$cC7@9Ycvu8D=R-hQf`9?80NJS+Cj!VbQ7qu)gRH=DBA_<}s7h#% zN|*sSHU-Sv!A3W;-1ya4gt%nAXzCoNKl(y`;wK8m7-&DTt}PXU>*!Mw_qOMmmdVR#JSU>X9@j(j_4@@ z9^(n3j2Grn&pD!JXwF=98|2tjm~!NJrHCy9wHr)4x_Z`wQY{n&9WU9SKiS^)fpEIYqFW*B z+9z-Y6*Ah>xO$s%mWl;OjNFL`A&rH-Ykqmd;v7twvSdqkG{3mAwq~TCrW= ze8wYlFW}z^?2UwsyHw$nP3-OBaUq))qf~u?YpTWiYQjc2>uZ$M*GurAii^{vzB0fR zn*e6sVtCBB=(S7~!e^_0WK);gM(i%zh{Hq~Ih3+rX=TGiSqw;}>?Bck0hMh5^N!;x zd)_G9ouEv15{pF{IaWx?Mq^u=B`X$X^W(~Th_X#o=KL4l3xMsIC5uHtJz1!#6-&v= zhXQMLmyN6eqHzKc=uF|u&06CC(fFgd#(|>of2pwp%(op+W3SDix-OKBtSZq#g3=Mf zwlqssB|1XWj0^jTj?)0gUIz0=2|7Gs(962pt3$SzVxohD8B&gBts^EnCPAhexywXH ztQL$Hf#sN9D;Y2H@ir#A?`M-~+r+f>j zCC`a6X=7H!HS9PxodogwfL`Wfm2mI2H{7-9S)iYU)IKuof16W~o)=-mMZWpHr#Gk= z=lja1%Nm+mDIa)$hqH%s!P;joCNG-_T?S+6Skm0 zcHQpnaYllAP*G8kgn?%&NU87xGbVOE%RnjfQfhUj#dd>os!%W_O+ii?u1$&U2k~qn zs^0Ag;F%hRsj(cGeVKqB8Mx1sHJR}pR0C`BwzhO#lhZ&esR2G-lN(^$oglk4 z>1m*`ouF=4RNhSHokBbh(ock>CI^QBzb!BvIirgsWj`)PgZ`njw8E!#fWz>Jc3F7` z;F3;l9T=>Ndl;{ni#S}Bc8pu@~7t>ZOn7&ue=|8@F*Dxkh{OTwSHD8-$MSM`0I)*RqU3US!? z4nluE1!_QC*|(hF8)pH;yh;4Odo$_)M%jn|hC)h9x)xH)Uk2WaS$O7Shr@New+WSj zS|wC>)>b|o$k z$A1?;EvE%K{a~J+0is>-e(!;lXAc%}ZOA?k?0bcsH~;FYjCBC}7mZaDNUG`t)`5pu zX3X$)$4n_(LCF`2YQ_fuSGaJwbuWA-TLg4?&2m6Erz8lvT=opA6g=I)L90SugY9PR zh9IB?HHVuEup`X)+5Ifgx1mB*8+?}W^Lv0Qetx3jXWtV#ety~;+z4zHKLX`lY~qJM zTy5b~G}V58#`swYs6Sg_;6AKfLAGB^hGL0=+d(VI0Y2Ue$HTf_AiKffneN7#K^-Pk zPcW?2?n{vGj;?l?K(>Bn>7sgtQWCiz?P2)OUQ}HntVwx`0CF&s8OEX^{t^h{s|FrOk%g(fWMY7ZUk-|u(ot2c4ck8G;G@~*rE$!qqzk{w*Coz%+x>^3nu(XrX>Jdf3 zYyiUxu=|=0USg7S?ec>9Z2pj<6SRm)IYIuUX50QqS{iebm==zU;fD#KexQ=Z%(P)- z{w<>l$cU>B{EpJ+gHe&MwPVK`HmBFd1rVPB(8HDqHk672vaUl8U;esL`G`7&MpSzB zMa80AR}q4~pM6TfaV*L!w)yG!71VyF$jlWTn4A3QcAFd){Z*dt*J| zwt-`Wy>hfe$0Ot=)`KS2Q&BtGSB&+pp>OOAi=9Elcw$pY57=(I$*6#TiZE->bgME; zRb_&Y>$6ox>2vF-CS>D#ipsjquL+>TnZ4ZS7EMmX|THv1q~Lmd9aGnJc6vA zBGWvI)6gWdlCb{tHOr@W$Ch2L9-xqnC zfa#4m47h_sPzAj^1n9Pq7{w`xT~w+!sMAbPhuok>zt7PllGt|Ay}nPV>I_d+!!wyW zMse-a{j-oe2QAB2Vp(kv6C z*>3n@SYYci1A=t(;(TRMX5>2;CVxAsx; z&~>8AM_Oi`=-*Y3T%{rtJvvRQHvMx=JQE`hw=VS0E&Biqw11k;k5LiyhJ2C5;{^$dyFL3tEb0fbeSm-D-+b7iM1Y8b<0{W@q~D( z2}9ikuobJ-qhb@3_tMIBq@SS0Yp`6$hiM1#NJ1kxx;(n0#oR~rteF3(30{1SR%!Zc z%y(4t=%<>8vT@ge~157s!Fasg4 zW0*2By&-?hIf5>{caDIV%<k+QwQq?)Rft`9=LKcRrFZ z7#F*(jSZ!TsUW>*kiIXfD_b`vce;?+-_iMI>7c_TmKZf-Ys@SwE_SvR4`fPoIsS0<^WUQx5Rd zK-aZ{j(k)VhEOhZkF`bSIzYB&jPQgg_l%&dW$qmqrvWtcM%`4|IY=*2s9F%~y~s1- z6)Ut%6ce@SKI_;6r&K?>0h7hkqev&UJ65kyJ0JU*)SBKScg+$56y7G4;adLtH%@*k{aaTWR?|Z042H& zk&5`>ln!w~F)>fvmzlWdM9w<|xsmIg#6ge_N<_X4iN~17=}x(iwpO>mzMgo6dECJA zG}o>hSTIYPs}5CZXEkmU(kf)#!^W>Ru#gyN+D@&S7!FcRYB1XxW@n!wsJ%m**`Ybc zz7*>;$wc?3eL3Nc=CFxoEK|HMG}2A@W|-bLGckP4A_W!CCX(%)m2r{cnX&!TWw{$t z2=GMbshBQsD;Ya7$BkUGO4p&vC5tE6%#uZis#&sV=ALdSdP5wcSYm>=)DzL(RlA~_ zP}K`}iKVU!6%%imRH?8$YE9qUEh!_;+x-G$benL7Wygqa?RK`seqH~w{6+>-?1rZ<3G*?@&D>M z3+FdgUpjNqyybJ67R;_5-L&}9mW9pL3z}M{FK$|NdDEiC>iI2~RxNC9TCj9cOZDQG znX~6Em_5C5?xO0JnTuvOwN%ZY+q}4G-t+;rmp0An+qk%S`jXS;&AoV5RZYJW`wbk} zZ$R~u#fz%vE|@iMNn?|h2z(ah3m49tHD~7B1xM?jJ!@7~ZNH&a^X4v?xoF{0=D@gW zuv9C%P07f;WLedcS+ul$Mr$V)NgE>glw5?EdG`Ab@wmMJmXLdCgw)|{qBm28Fms;HG=X(E!syW2@Vq=h-1vq znr6{#ZyGFUCi7>`TC`Ayd%O@}TOtLHC&;YYtqK&RXErv{H(m+~M6S6a5Ww7pv&1k@ z5@pmi4%zT!BilR*JC`AdnJO!80Zmm+U8M~jx=a?TMQkk5EfeXv3ofD86=CMAmbvk$ zo;w@9Lv&KCB4Z-!i7?fm6j9f22xiV=e8Hr->|k(8rg`B!dKq@>6l5tT#0AdvgNFa& zz9wJ=efYN0^8W-Ug6lduT66r1+Yhzv*x}s2%30jtAK311e9vDrj?ZjoxN|>l1@-yU zd}X%ty1xmCx19T(`+ZT&*&l^kpT%2~|Fg6B&pPG%0!+F-+qm{=mNB2}ELWzO39G8l z#hfn}QlGFk{>-gP&En(3(Jb~QrbEZHL3g2;8es~Aeus0R_zVg_!Z4CUVf zS_!jOAQI}}3N{-sV! zhpz)W)_{|oElK|0T(v!?ZIwT|J$n^~$HT3MclzdJKbq}-Xl1*vGW*enN3)$%SLQl@ z@{P}SPHOOt%t21SuL4(L1bj)(ejHwgq#yb!autJfnZKvg;>~&Bcsc#cakRTj-Ylo( zQ2ma>7`K0HZ9i1Msy^F!9l&|*kB>R?s%yq{yLx5rbvx=C9(C@o&)$I%eN|h7v%-16 zx!hTl<6qL=(9wXO+qLaWPz64#{fjer|9{+hf0{A&|KJGs zLiF%zoMgu=LpC~acgO~iFl3w6rgsGj5uRNU^uqBGM9I`UA(U(OCH~LsgurMS12L7s zT*ORt66X|vymJbGUFHEr~nMHu&fjl&KP64DlrvSemJ&lDRn~4O7CJAhp zIR!B8h!0LPr$ACq$vj9fYosg4oo4_SpJy2maDesUi;TE^*b6G8m`Ja)RuiM z#_qOkJbbm;zR@`cbFRg}3dG24--P%G?wgn`!{4=s>V1`24UfHZ#tz@`Z2aF@vSSr4 z09v};pE1r?1JGHH*+4~R14mu|{C56nNZQUnNo`32CS5JGUs;Ms;EbgAk~-=e8rpU^ zBkCK*oRR)D|F>6eUv=o+Y+psTf3M}Mwf);xI>WVg80##Bs>_|%oF#1y9sV3=Kft(d z|Lk^W#G?&6kXaPJm$bt_Y~1^l-Inv{jvfA?Fh1`NNX0W0n7FE64f&XuapF zNcZQ`u7)}wFKPF0U-@44A(?4hiz@b6O?ZAmwh2DPOylz(`M-RfrC!*6_ObNS%>4du zY-fBCCVSO-n*h@VnPnu*A<*&1ryOQJ0i0(J;Td%?o$xIC0qL<_?(g#7^u^Xv~0G*XVeKLCz|{Q>4k*av_ivceyL$wbKRHWssl)jOO6+s?eQ z!xzHvbG__XU-=&&iat%3^5u{s2XOxXy*&FAQ;{!+qUP!UG>gWWg3N(U-R(lRsm- zf9QKyG5UvMjm`{R;S`V|C!mB(}Mr^ zUu1u-r;@9`JdQfRoMx~7q8tRp;WZr4TCDdi^mYO#4(8=Z{3KlBgf4yxP0b_YXT{|F z7>x3?|`GI9{eAdbL@$q?W;%16xR|J{8yCML)?1}&r z-w8os<7wbM`yilrAP>#m6#?>-c11uoTOkl;lE8M^6#>TGp8)44?uvj}?~1sB+<7N( z$J`Ym-t3CF`CP4}n_UskAU*FeKyqiA-j`k2#_%4N02rTyq7Vt2A(Y|S3?XRdt2nBt z-O+_3VKam|5;j9%NaAcb9;cXrn%%dA?KyKE6tRjGdpW|PSDZO*Wm1p@2 z+j;Ee(QLe3%FJGcLo5*>4z)GlYfZdE)3_Zt*ix3$u<{J&q`F+^)Sdq2IQNPCKR65Q zA2=tC-PzDErrVB=Ly$cBy${CVbjgS@_L;sqzCl~!yzU#GgFja|Z{QV{b5b_7Kj2@2 zw_LCK)13YODZZih`(vF4#@c7NS%xyp5*(r#nX7WG^i^hdIQ#IwSN*@Yoc+}ML7h?z z4ybAgc%I87t)3ut`M;(f zu5(VV<0&7U4{AwLFAlK~TW;(MtaWUKDn9sylTM6r!gn6oW9d?{KAE#Aj?uL1s%-t|;GIKYe z5>{nqIvk&0!Y1VREY2_slPUkd@MHl*tE{iT0<}SLp)Y^C^mRc`Z_J>^GjFQI= z=k=@499w_p7-yL?Vin$WV4dR6!%0G4rOo#@avaYu2MYa3&H=vPsb9r~!xA2GJmgPt zwm2uRI>eQQe^&b{=W>5hyT7^JzuRvA;3{X?m}~SR18ax-o$ujQ3OQHd_+bOq8u$=k zgmdBi7y4Q;QN2rd-veTuKUif2Tf6s zWKpt3T9l(?Z^n86B4&u!U@#^rvC-WCdZy9c?8gi!Q@O$bm>Gze0ffhJXj3FjQWBj~ zvLr>>O6*upqDoX7DXZPASF%X2X_x+RRh*P;%e$_WD^#+QBUf$3dQcm0N?Xb2`#a~{ zN26y*%F2qWXe6TVIrrRi&pqdNe(&G!NLbr1o*TZs_;V+V=T1I0H1?LNoH21}yy=UN zJwp@)B4h1M#W#QFyT!AQ6yN^H_ZF5GzE_iA^1UzCZo*BG>ACaf;xB!vRs0tZKJvn1 z-Gr*)_u#tt(C~Zy<|e`$6qi_g)3e{Y@tKd}(E05*J@&;L^&H&}jp)gni@)G0Vim(6D z(AZ52AN@b;3x}G+`;TEbd{kfqKo$Q3R`x#{{`wz&_g9Ce-?Aw1_~3WG``w}G8xx`d%j+>V1_Alq0*1i7kw>CFOa z9^?pk!;I9aJAu>XIwN6vc9G^`G-mXBiLz!Yfn3}DjCTfMQv(a46xA7FlTy~;N3qY~ zM@?enlOz$+w@{xk@o^_p%G^s0epKcRewt*b~H4gic;pzINC4ZrZ0~ufZ%7yGNcApo7P0nS%wGQ^TPjIA>#KrM-#KoUJ zG&FwGk|ZwJ?VD0*DJ2;7J|LD6G z`n`v|wD8FFj}DF8&@S#HHWq*85v+fUjRzYH5fQCkFYcWj{>Sql`M---9=Y+c#~za% z@Ko`Jlf`@0`mNS_>7noaAyaYX4#lJs?2UQzVDuqLETyYlUpg< zsZ|XO)klWyR5A22nC+xRj_uSFIkuC5WV0TMW%}9`Sf2 z`%amS_WgTbxT$y~lS#)2;QvhKy`jRpe&~wLAA|t@NQL_!u72(Z#{aL3fQ26+34Ymx z>H(i_6?pbuy2m*OW3z8$MLdRjKCp;}Gbt`-T*G|EhT&Qul>#u#@ z>Fk}CrFx|Api*S82ego$e>W{;xX-)7BYJJnvb$@qTX%&-x9*CmZrzoGZrzm<-8#jW zq}udG4m}-aQ>aP)F%Q7KKYQrV(DctJxEZx1jug&We(OKRo&AM}(JwCEI5hTV7o#j6 zn9t&ZAjgv5E&kLa!&@J%7C-vXmr#T~Jp698`36k8`+J*Z=#pM^_`VnLm?wudx%-o$Hp?63a~^|e!ve|Y#Ge)ys9nWxI|e~)BELBmCEgotjX$;xm@dFvR(CXWi&+DB-A3H?c^zdhk&lOG`M zlm|wUTl#VSLN#3ypMe(lO~d~Z4d88WdQ^Jc;%g2Sw^5F&8kdyeZ#@2y;X5AWllC7; zs*3k~$J}4Oi=1Hi&bv_E!|*N;%xcx6ai2^08=(E$HA zDL`LAip8JERj(Ae>Xi}&pz|tBoPmc-+%%lZ8NMj6Ye*=m_F45=DJQU)SvFBTn&-4hs&qzrWuO6Nqq#{k7Ke~tZ;gZ!1mpEM5WpKcN zrOV1kJd}}-C?)a{*Fh-aCE=3Vu;B!qfuqk}( zL>^~ra@UO2wl5ur?W=bL@yA_z@y8Vs@y8WY@yC^e_~S~6_(QQ@`~hS1d3G>JFaD&> zz3}tguOj?>sd(tSzXB^StNrIl&4hRSH{ik%g^ZQQA-sVjb@Bd_H`a&WT_;|^ISCYR zJXG9*um6KDED=cXH%rfQN8SUE;UE5Qy{r7?hi`ngc#|ZHJ8-7oAa39eq?y0MUE`yt zuzb8=0>G)_eUE(mRPm(DiX;e)@*mX~ z=6{x;K@ETKAoA!J$=P)iULCb(o?U!auOOcO9}fR-PJVljMRBkE|5kqcf#uBLEclY!f-B5OO0>^PN)-DfC2A7s zNbLS#&wK7<zRq@*5DlKy2s-DP+s|>^>EVmwB0t_{@4&otS5-zFjlN9xqL=4b3 zr}ngPnLdlF9YL0J*FT&vk(VRO@m}BD%W_Zr2D02IiyW6qjIs${ zZww;9C5ZseP5$w3lb-h(9Qq}4{frm6ehs5ePL7!}$sh<@oXS@H*`?tVr}C24NBSkL zStqWLTuPaOKlfpRwqJj;_`#FKH}LmMB=$Y|%<%t#aB^GC{Kt#u?Qojm`!F0Ga(}UX zsql09^H24sp+6teADOr^bx50c5X5{t&T+R}aP#FyiuVu{5I(~Ra+iZZ^{gwegt8ax zemclE2!hCGS@DhHULvkpME3ubh>byz{09%FU;OP;CYKI>ZfOxQ?JXQJ^Mxe@)BWNN zGS}^DlsA}LJIB)8a8mLVhDNf9JzA`Pr#OAGSU>q_ae8>~{~DgHy}3C52w9JnWs9lu z(x-BE{j+b?mdwKVXmR^HOlNVMhu#<-`oJT_8)kvHB@#{1`%QZ6Kb#Fb%}?uwsQ#%#%QqCBFBIP9?@eI~&JvB7+oIUlYJZ8_S-R9r3AtvR=DZi2Wi2ro|laxQtZ|jC}^)sY* z+pDP?^KBNRLSdF|PMdq4W_%wnK6TxbuX^J8;@b|n7yj8-^~$9E!-rp5dp_I7@I^kV z!Zq{M(mbtcmMGus?|+~BExSL${cW4$aIgOMLg7yCb#0E_{EztOKE^$f-tGSf!}9j04n2MS$6x)_@RP53;`zVV-MUWn$uf9_Pik@0*bb6@3eQr4UdYG2{L zlDlgT_5CU@Qr@=j9|0!a>=*Am#J4}ch$g2H`F3Aq<2`Nd7MGtWYBq;HYb(T;hBoz? zLg6#CXK&r(=X;NhW&LR1>U}TJM*FdK!}}MXy6*iSFABJsP`_cBa^QPNu=UkH`_n)9 zO49e2k26l+w^s5~haL!B+g?!L(@gjauFY}+N5B1A|1GZ*sPkD4hp7F?i9+Fz+*lZh z+h^Apip{B>`xehdJg5Iue&a7NH(Y1-^;#HQX!B{>JYj8wcQpQ?q)q=?X>GoB9cx9x z%xB#*b)cI^JW?CF)3BQQR=e-h?lEh3C%DhxTwCE!w68;(hi?amxi(>K*xarSTfq8x z>m7x{m#xig<%!}wLXSf&zsN%sUdeiB@9CXiqwN)IJHGt{4X@Cd-WU2>es`g8!SGn? z9_^|pUd70+D?T0oT^l5{eeO=?#@gPQZTtCb+wk6289eIVdqwXZYPlDWQKxZzll#Mm z48HD3*R%_Keaxex6o0Dyw<<5Kz1B$W|F-JpG?Z_icY7(6Z>Jp5Hk9w_yZ>U+=p=ypZpIq_4c#SH93!e!Q>znZEKL^_9O#`E8l+`KiVH`^PBjzP?%W)1v$} zoBvr4=lEH9KnrU)ev);fed~r2c27Ybjsw&TkNADe0gN^x5zS(m@1T|~R&olE)hY+re~uY85F-Wi_%O@BX( z<5|joksZhO!Et1H9O1{W4;Ko`-1NBZg-^cb%BK!};<}Gt|K#wm5B*y4=~q4V>L*?^ z^sfRGLuK^gWB$33y9$Me?K$xlPY->(*cE1d>bm0XLn35fb!fN%inRB9rsL>G>xPH* zo-8SI#BJ!0GjDSAOzWXBK6^UQ)z1$tK2dBLqFA)%Otg50Klw@+*KeK)cxQa^iR-#T z%WT?;>-+iFZPHk1-sVz$&n`pn41V+-@NvJXrgZBWInA%yweDuUxpp|0c6<4Df;F|f z^Sur?JD!DhyithiW`F;y+^=)ZeRxU@C%qT_;=y}i{x-RHv(5M8Lu*eDIVvWEGxUA; zZAQn|xORk$rAp@hvG-9J`0UrO`fM2QV=;UWk9!{2RyCrmZ+(t?U$lEIzGX;||NQHO zzyXvI-{#8u3xz+n`Mq=T$?KBsH1vRfvtTOBUF9sg7whlyhty%+b(MU_7j@shbuHr;ATPEj}^y@#~(v{)tz+9t?*6{Q1{u z9@PHXb8bEzAM1Eg^{sm^aF6LQSwZFRQ~r$g-P#WPngenN_{9sJ+xx1qZiUGA^XUtP z!UJ6E9Y*8ySjvM#;pLn%K{dDo;*FE*BC$ArRBFqBAPR6qL0bt#= z-~7a@o_Ou24!IEpj&kU0$y3Hg3NPqApS%}(>7VPdd)?>FdRb4ke)D*iXT! zo_lT+9>tzp=U=z|T20{VhTiYyQGI3iy2^j_ z2583>w?A+8IZ-iFUcG3ErUHi46 zPZXcN?&Gg|>iQ>N{lxI64&f*vP=WCN`9FuG7@gKL-~14~x_bthHN_U-xr(GN+S}x5 z+-kr15HyJPU6ZN2e0HPXvmURg-4`Eb?Hn%N4tOERsKPPDFZlm z!b<|`<5gcjfQ$rhdiI}ujQ?!j?p%DTxcu=UsTZJ02FHwzsW8}8+YA3G_<-j$4wWDG zW!0(t8OopM+RdrSOAqS{wN9FMwORiAteMUGB1F>7`;f;YdY9%v?H+r=$wAD4<5z?s z=qTL(KKCD{ZE_zzCVT&ZC%Koo|9+1@!t-C@{ymxd7y9mxJ>_Ur(!ZC7!tZPYgZvs!awBLm@_J=&NBH0$+mdEKbrsdD~6w%imzV z7=P=AYwr`a{rYdF`$XmI{tH(Y?5O-U%7b7>dqnrIaR0^jh}wPnw+64#xbNq!pW*_% z(7j*pNr z8ppkIy*5{lD|a_aOSN)b>Q8x_o98=PNyd0z35%kuZ)iV;`sZbcSINVwk~Z(BjZ=j zom(B(ztPd?jyp2d>!G?3x0;>Wa@<{PS4)*nG&w##JAR_hz?t*!`vTovo3*iyAq9kG%UVcJ+HT zpz)*QHpBDnQn@=|hTDu|zTPZ#<1@{6CFZ|sn+1sdRlU~j)~j)~QK^+!m_nz#6rZUv zft_xt+v`M~X0}+M*e;*$)|RSGt>O6iOrcX-=yaQ{XmW}-b!zXeHs|A(n~S*IY*b3! zZaeNq(}mJ}++J?C$`PMv7n&glV2hH-2e-G@`0J zqCfGOHj6oCw@1fDF75Eg>brNhs^!IM`P7I#F*>Rl$NhJ2f46VWS1)X?9ZhaBlJ*p9 ztoO#fj$5{+nnCK(@!sMos`;emnJA7|_K2cByT7;2EDDG&ZQ)9=bzdCwwzyM{mz%9> zBVI1|;?vc3r`Bvl18eDVzFu0ePpLH)n9cF=>G2-b7gjE>3oOm^?N^%K3b@DTD4X+nmnO-?8Y1CcGf?r z`Ri()x}A~L3oA@oZJvG2l8t36CuYXR#|)-C_|_8ejcuPcs$D?oR3|!o>-yfR4w=Ch z=H6X)B41ysHRF1%)8%KWv}~WAuPSsF+g*1r4wt~4-$R|d8)fFX0T@*nRI-=KOPz(d zRIe>GMmE>MHf&$}y(Q8@Z=H*5!Q;Kr=twj%%Jxml5873K3ziD_iswp|mjPq$RUWkD z^R%_SekpeD6yTDbb#2~WqXP^^<2aJ<#25GWBmMH<{!#r=O`+CmwVT~$Tw09MOBNZN z#d=gnRxhnw6u5_q$p|p(b=bG{(pE!st#Q0RbFyE>Ia@}^d6Q!5QU>2LLW~T;!eI+~be>(_;uSp8^n z#`cNZyPaO=^i*80E|ki5^ETb#Em~nl5LcI5R8Gwns-;@IR9$Me?~aa4j2ABLZC%(M zxuUN;yL;ctc04f?QFN|2@%GNf*3QP>{oFN&oTP%zFRiby#d2k0Yb2xZl)J5D=qeOC zow!o#l;-NyD81C8)pdg1NPX!qzr>svdQHa594atU1jo@j)-zYv}C z6{A|*nteTkU^U{UTBmHEo5P`??I|rotJf_93{ad?)rx4%7~itDv%UfjXNK~(b$@hB z%j}y7rB|ArZo8)GvpMa|*Xrd)H|Bp}Ir`{9N*4^Ns{(jiiO=qcFs`lb0CjxTIRV{% zT3hIrTUwYiwMH~^?AX+?!aRGhUOpAg8Xay|>(x@H8Xd0huSCa=P8>aUxF9?d&-Lb` z>G2aFdw`(Uu9N_Q8HSia-`#r0M%s>>r$F{`yuHCP!4jOq(`GHQ{;Q4CHEr%jrMeuA z00!gZ6QdC6xLhxFI;B9EH!j8c26nT^F`Ie(%B(0b|BMC;Ie}^xs@;WlEW-X?7Q-W( z{>pTaOFg)kSnDyeq$TiUchw?PHIP=LRQFBBz#{-{xy*K%fV5?4e0-{UcgJ2iF=;br zpdD@R?W}E_I~VWq(hl!2wxir!T7u=#ARST?D%!s!7bvD>_rliBUIYUo;*onrrON8} z%H3u=hSs%98eE5ot+h_i#7po=wQ{M`joGG*Z?+JFq&xAM@?xnSFB-tOYk>yq!W#+z zY^wuiDA~oa=$L=VUONHSUh+>G1`*VOL|W}y6JmR}xRGTe<;iplf@YE(2xui6kn2Lv zhN5K|=_Hr$iYB95G_h{D_U6gt&Gu>S?qa1K9Xrk(c1vxRGv1h*1&!H~w@M3DHQzdyXUV1}g*#hk+R+4*5{E@%(_8 z7_CZLEQo-yO&irV!b7#)ZZx5|U`|$uX)o6+k$x8I73-&7JzcF&$K?_noL1D<*18;c zM;N6RciVS^pjXG>={Lj$m`~=&$f{Umk1V2Jj#i=%In=+szbDpbWNvJAG%{iUrb%jS z7;V;nA;Bj}sZeIgs=!>k+UOd$CN_V3yZ~oCUn!rdh^%Ry*^xAEbs?kv{kyTZ?*owmxTn`k_0SMLQ%H!huLeZ;ZZY+LnaQXfHT$D&5B zUiZv%d9hZnB$J<%3iSr!W2M;>IhTv8Et#;mwvFuv0twlEXPUh_yfVl)s+JZ?wT8o& zlanVV1A_xDm%!MlE_ZVngF!eM%CDZ*^70CN-S+(>Yh$~{sqAlTa)5lU+DM|1-wb=B z)Pnb~IOu@ofxWCo$JCKW#>}drh<3HyL^?3;WWp$EtJ|*Bz!2KHuxu04$ERnfW~M=d zY^l!OooK&u`a5%eK=(q=@ z!7@U?W~PmuVE~(3m(IIC33W88B^VTd3%CG6!@LG?sx-8FL1a3X`5hp#-s+7d_LCGE&O^6c^a)Ot7&XC?*`AUJ6_3 zyv)-b5KE%f)EJM6_%0Pk*GbEOFC1mF(SYBW677ZDvir5kVF2K`cn9+aq=YHc{AeaM zD!b>vhjx{_0*RZEST6BVTbyI7Y7MBlUvDqq^{HhhW_nI7L)X;>q>fIx)QAqheeEz} zWw*o*oH#ZiZn#um5NB_s*s%$$h>2|ns~Ci&f&+uF?`Lz*@r4@ce5G3N@|yt21l*48 ziK)rsGvW&T2lwp~Cv|rgrS);l#oXQ9YUfO;WlW9ag`L%l+aoJuXUED*EkkE35Q)9Z z0P(66DI;f-qH+K5o^~5Txf=0E(m)lG3`RnW{sy`)h-AM3-dPr8YSuWA`AQ#~;W)nz zFy2~hNNDHQcqZ1fG5Ch$2wywKb?xBEL3i#WJ3!r|uAsA!r62IJ~HqdmY)PP5t zgTy5|ABl{}>&P@fh=h)6X-SenwF@URQ!q_fR#clpAVpM@TCcIt6HDgEMFxjOBPsqs za)K4o@S<=54Psym2>9W`plC8~&2?f^;Ix{ov!S{EN=Al+F|G|F?$Ga!{_WzqX_SF1 z!)eXu#KdG>Q0sJ1>@e|ay+-Y>XjT|n5?$wXtx^cOtCYugoS^4Mx3}(F-`QRTtpvHH z3>=6$jtr1n)=g>&a?2H`GNfqR))1iJ+Yqk7w@_KNR_|2rGJ#1r4~=C#a%fMRWwF_` zD%wd62Tkn49~{$kz+pAp5FhvuHcA&QoTDk=`72?c0Sat5xeQ+00DL2<8w16-I_e z>AWB)Ocxx!)tD;l)@WoldRL<63T=#1j)G=TIiHSZ#2*6ZsesYDt5>SnDg?Q*T{>e@ zDe_GQz4SVc=@FJfEiYwfyU?jtPigzJ%W4giVugZDc^)scn+P>oUiFVHnWoT5(P^^@`Thbv2+(svW2)MJX*Cqe+phF znt(QRA#75h8I&X1Y3U%`(xSi^8|e4f6ynn*77r#JwuaXjZxm!lFePlRSZdSgT-w~Y zbZ=Ir5p z4j39xt)TQ@gl;nmH)kEA8DYMX63>Pk41Rj@#Po@oOIIIsgQn(R088xk*JcU<+zWsd~J3aT}c}V9gkp znw4s1A9!3OigQ=5+Cv-YFKB8y6CoqOOIib=+p>)z6ebH4gS2;!06flwukP6cT+K!L1) zuE>*hZ_jf`W8}#A@1qqt!)^RFpi^M!6Cr)^3G(ijtXD!1#)2 zRv%-mU`}ssU!2pf7j|b%4-2~&#~YVs;{Bs>ydUb)8Chtz0`B(A=H#(H<*=JDG$>G( zWt0nU!sudkdtX9i7OQF(HEbU?urV4Ngd8NnpOvgFK;#-IV%Wyvl5Qkcpj-;{1_F{` zyvWpej;$D^gcl!iQ1?#n0R}S~)CS6J1pLV92Io4k@#3x%;sHw6WD7d4$}-Ixrs*>P z6lC6l{zU#aVM6Ch?RHHf7`q+SwEIA9U;Dlu1{LEBOy%rB?-EC0O^SvBaj1%G^%i4s zY>L5AUtJ;DP-sh~t!2l+o}!9qG)rxm!f<6P;Z2$`#0ABMun2pu5$}yO#p!A zF)5twzn}m4M)dPP4}LkQVHC>-)Q#AKa554I;Q5nH9`pl@O29dbo%8tg^!V|qvG0G1k^XP=TLJ=mnYstd9 z{9>oN2%!{^>s-AjBG+9Mx=#u+BEnuKMrX{A-r6`Kg?Wxzt@MwNFWx*B*K2 z?mNe#<6~x+2vjJMAGEufg;ED@Y}WJ~m)7swTfrVZQg=F_Rm@y_>%M9%8t4Dah71=d zzD~DJ!O+b&qiL|BH?hB+CRs{3KSFW>H>;3oK-pqN5`G~$?h`o6P=(V{2uu`wl-Kl>c;m52G}-{C%=OY zGTLR=YEW?cv3U31jcvvVtO+ypEBT}>+TPlBdLpky+p}_X1Wl1CxEwElUi_2+%&hp$ zW*t`piGeIP8Vc+T%wb$cHyi1q4a7!=m5PQwZ#^6kI;PeG2;HE=d>{-sL*G~mD|kJi znbCLhBE(HcxkAC-cvoHefy3`S99_|0KGYd?&B11cWto~(0}09e$e?%boRf_AO`|+H zJsLfr+y3tOxV!J}&i3DQx4DTCX24C|b~ou)CX14pEKD$lL(H4O80!GO&GuU&U@~1E zSn?ZkAkP+>I_|F2!_e{7$D!(LBnIxY@}qKJ&ZkREeh9JEV1|Ea{KO9H?A$U z>W117`!YTOIAth(?qORNFe;)~uZ>0bp7E)v`u>WR2He*!p$BSXh+V*FtCs+mvj^BI zDcPC5cBR><-yNB8BOw-vS}rRGB)~Z_={B7>E;+W$7KA9Js&IZfa+K2I8U9Qx2{vZ9 zKTIXvIoXhbxk)T1C~@08CyA%UfR_B`bEZl3rDkHJkd$M)*Y!MTV*>?W;@_gSv zoZ%*+X7V%gM#vZ^o$dWGm?PQt#<=DZ6$vo6er0bR1M=1-QO{rY3_xVeRD>RrrlYs{ zBKw1p$SkH_oL*B54{VnVndb7Q2dr-i9?F`A3!DuDO{`w0{@xcoa0gv7Hm8PnwbFu) z-xhtSA5a$>J?ZAqK^ih~>)1JCnz(Giyv;i8GL*_uhh-~(ujNlSk7ffVq`ic|!nUnr zcEEhG00EZ@I;F1HP`@SmHrr3B7XiQnJ1)6`rIK?)UpZ*+9Z?JBtE(vQ#hZ=>@0wcU zbnvd>GDAN+)^t9Cf-OuyNM!;pch!fOW~L*QcwPVm@wN@B5arNdR^+n5lxR~mn4dnw zNTZ#aMGly{fH04Mq<2B;uh!d5w@f){(@QBrIx-mrK@)80yyLtE#v~(PK9$CtOG8d3 zTQU(I9t&B?>5ouYYNLo#HY2^fK_+KytEk@CG2=%WnMAk@Dv&xiUv#saRsQIHRvRRK zC74=KP#~C9aF@b+K@A0Z)}t<%p47qbq9sOR2-!+!9uKzw{c3%(VFX5APHkMAy46TF zy{?lEkO_>12I&I0Z9J@UMX|l&OC-?Lnl_+5<)V$Pua03dPcj7^;3bmvHCv0AE^(W% zfsN+;U6qFLD!!m5Sw~>^`K&oV0Y>>l$Z>6LWp4#$E9=3gszMbQg1bhvWo>c<4Lypp zl=D4{7~>58L+i1X>r=&E31AT_y_D$n?u=244+^54_463ccJ2?{B-rV~<(18Svzr-P zQ(b_uYu{})#eN!TI+#9{q69{p1=OmzDC4oYaqj;3-2SE2J+P=eLsh+h$-Hs7^0}ds z7Ku29A*_s#R0US$^47+h(5LZcT8!CL0@37Nb3>e*1L1h#mPgIX=Cx(8ZAlGeMBTgj ztf2Ojp3Ww8+PEk7kZEV@&1P#(TE{-M>~Y6r(S=uuH|FN`IGec#q=`GgE|@U~=QL8+ z_L54N6}j_xf5J|0E+9WH4VKMG%}|%NT2eCAXLIgkP<^_~&`+h7AW<#@7EE+HY+yj8 zh9BQLI@z-k1sQU!z-FTzVmaH)l);kFwf#{fE~k{d3UY?5OiI`^c@dvVoTMvW|CgAK zJp#@c?0k)BfY^IH@4;W&t<6d<$4$_xX@mG;ueGUMMVphYw?%S}lg?{W&ShqGXO@s> zZK1qk3;FbTX}t1Ot)%bZm-Ng9qv+HRm(MaqtM-P z2vKcL>a}S0xUtgRxh4Xlu(U95X%04vU;Mv4qb*mrZnedGU^N_#?lsJL2HvRGE>|O| z^0j0QvEvR6HL7RCwv1nKC`ed+u?K^WFPHmeWLOp4-fPM5Rz7h8rz73O&(8nSsFPTz zqB#EG{tDirW|9?K7M<`~TMXif*4AC~q|o)n?Y;Y9TE*E8=84a92es3?Xih8zY_VG2 zW=>+le0+P{kn?OOy8Vu5aug>qYbhQWVxt%kVk-u=$5(*%xz-cD^@pPM&E0kSlKKlC znZK~jx!2tm-FIPQa~+1~h->g}-qY8e-AKAjIP3v(Dpb%G$Pp%K{!8=KR4io-9y=w1 z>)4Z`oI)AKt4{Wr_vBDq;FGfkLchmCEJkny z5Qm19OaSibts1<{^h$zHnAYjB+HVxm|*|R8;jq?BvSNv5AAuO}UfmZdaL8YdK ztN_p6OztIXBp;mtPRg!&ED9b9DARgGn8*NOmL%OrOANtl$BkBCreEB{im8we6Tdt2 z&yPin%R$XE;6^%P(L9h&ql4NkSWRNw?OUKLhJo}*!LE*=Sk9QS**&}Q$|g?GQW(pQ z4bzioVTD(LNU9iodE~_8U~*<;hkj~|;IKW-p#z+Vp+=^O&5q?HJyU%!bA zzmy3W;9B2wFv248Xfclz(S~{O!@dj?D&feyOYBq49FTFegTIvuqc(rHV+LUR@QCfA zRs%7kCxMP-1Foi#Y=fpWxGWx<^2qlzJt6s_QBklEz%BzHyiTB5u2={dXVE0qT?b=) z{E68XQj)YeB6o2o2_6u>qQcxn;lS~gqm;@)woteW$F}i>tkQc<97!Cfw zd)2J67V9MP>IM({8Q+yL}F z*EV+0fpKxz$nu#|4QqMb$g;mKG#FZhPQJFlAZ^*9i}uT?a>9(?akWu=`!Ar>#{HYX zuPe}%B@lZ}d-$k3Jc*4h{dE8NxICa zK(dZ2a6fSs9-iji#ikf;@$$yXB@r@xUiNZi8x(US5kS-A>`X_GpEy2qf>^rg*_p|y ziDSoMo0%Q+=ACDaEflRI&Su1gqNTBEI5{gg?H1exL%7-jTDf|0_xy#m9a|kH0y!3M zJEt7-*L+5XSajd(WD==N8Db;&ZuV;wj~~=1$|5hkstb}>67H5V z2|?e)^Zjj;#5Z7TuZ(QK2}mB#y7(TU)+}F1h>Fy6!4g)Xz~{N?rqandiUgYE-SY53 zg^bJTBmqh6gI^Bfbgr7v=Drd}W!8W@5WNeq~!WcZR}-gWmU;Fa}`N5sn&b_&QxtjwtFNs1MC~);bQ}Fy&@`k5!hu% zJDs|mxn>MQ>ViodV4EK~C%-_8bip>CVt=}JpGqNGLEw3LHtg6r)f``RE;anRmG`dV+8#vW@H!Vb zY?gR$+ht;)2M8CwY*R{;+BJfm zvF|d3ZVZG?DX1(I_!LYT*^iN1p)+m>Ufj46k1KD$N!)FXJeZn13A3Ze^Z95(^*(~19?mh5t^daJra#+4>jt4m1HW9laW~Lumo;-$rWYX~B z5)MPh&~1Pf6&4MxW5!X1*W}qsybdAzWuvTpbzn_2zzH&rYx6>=TA{vR7w`&EjHP9? zO41}+Xp^iWvbH2tpud8Sa#10`yu6GTtN1~l_VM8tws!Y+kFI}kf8(-HWQbIg(Sz_N zd6^QnZtTCT0iYh+wAZFoEHs~wLO@cBjnKY5TfwUu-Nlh}tLO)Es1?x@z9S9Vk7!bG z3citZYh&luP!yOeva5?!8Tnd)ip|pL5{i7bv)G|FUQN-2xi2KD+xaC7?~0gk)@C2q zB~L2CyP8;W5<{wU2Z%BV6pNuPnh#pCs75xt$9%>)f%+Dlnn?X59t9~9?itXWs#d|1 z-P3g#wIDPe5ETajED$Uh6_h%B>m@@)l_46!?PhQp3_4EC>#Lh1id!FpzZs2WqTIO@ znUY+!k?G6(RzeG54+~-GF>$O}f|F<#2f0}1U7JiVnQ;7UBl(Dl3lr1tia>;Duh*aw z9MX-kPsktvJK7U335FAS4a{!{gFc+9zFIZu-&uJ3M~~9CW)RBJi4&9KCnjfcP#Qlz zJ281|{m5}-&{}+Y+5xANe`X84tlKH>qDgVWzYJIO)3^w^_NHqStU)qmWS1wAMv9;y z-)7l#yba%bK>@p9ds7DXp?1p!;zG5xhr+jJuH{l*phgQG~$ER z!Gxe_OK+9n()w^+n(`&{3M-4Zt>X)e2Fe9263pfT7L{oxsg0<9-~rhi;_X#zg9_xr zxk)P_4BM`DDVx|8&?~r%`AO~l&d%R9a~$4#a7T*s1nwMd4n|k(>?X+oZD9JWI3Qlz zW?aFA^Oa~;%Zq`whB63^CK%5);r7nf-qsjW`3gg}4QMqHm~i)^wp)^1A{zO5*G!v} z`D~uif}@&moko$2ms(vNo9)5*^mtdE18xXei!WWB-MuWg-m|+`q_LMZH2i=E4quZQ@wZA3l8(cOY=WLX=wua6{A>kQBV+3E(W$?d; zbfZF`3m-<}HMGQyz(@>zB%$3Hp!-a2fSu}+g~>=D z2g1Q=jKEt8*$|I#mvfjGQ_)xEVgLGa9fJ_8F*BmgXe@n}dro87m^Zl6cB3kLy}z>e zII?UiMEtS5RAea1f{*eyG+*9MZR$IVVn{~g4*)&DqZViftHq z2Wu>L-GBrYGM}UPMmZ}U&K~&`U+}3z+HE;IyG2zfuC1mnFlg4HiAE@e41+4i+fWs} zCxi_WM>zw=Mr)z+*4YoZa%36{W*^Chv^ix=Plgw=+GtJtK_#^FJ`R#jAEpoL7>DuY z*pBK&U%i1&-WU}{iRa3Jcr5uh4(26Q1Y~#Q0QSIU8HF? zGLZ!&c8Lm(mds2$Rc0tzTxm9GTkvd<5()QEKJcn3+ms6}dIy=GuHH&!x)*OX`I1^q zSu39Pwdd7-X_3vEF?ik&*~y`R$1HK;+!Bv`g}dl&%S_hcKh;U8QonX%jk1e;s&~ z4~<5|wc@7af}?pNEievkVPhjFPhrtk9y8-3LLRe_DM8IlZkjl8;utCN`ebkcwH&O( zH~JY~AozpWLq1!^3fV}E+2+th;)q}mg~W-{Ly;5+SyEzH`+4OEsv)Tp=mt^-9Fpm* zebqE)A{h^uC*ey^s+Y}%;6BtWu^~f(eVClQK+D(wEn|beRiVqO8nwKJJ7(P(*}E*K zR{Ke#@uRd1lSO#G3m}M>lmzQV&Cwg%@x|S%TBCiGwi%(XYJ(1qM$HQjJ&+XMeU5N4 z_U^A2&aTf)lgw-YB6Boex*^CM$)_A!b5nl4qE9p^iU=!+_qotLo|%Ivn( z?Gac@0yY=(K7J;*C?mu==z_E=`J_9B=}TR~KZ9Kr z%bGEAip^9;k=^a})g;56(;azyUT4CDwu7!a=t_u6QXG+%u3fz=BBLIk;&nek6(hA% zhZo|uG<9_R$j<77Gi8_2QjvMf9L(&JQP^fN#O-1Li#saZH zW{jV-{gt|>xM0o1)jkQ<6bZ^FA~JaBtK$V3$enL2mAd7{oJ*w7B5XU8KGUL+eW^9f z^hA&&rVQgINbf5xi6!I3l*2zbod?sqK&bH2uG1|iDBc&_Z*+n@KTmDc3FWJ16 z%}G}E?G@HoB7x~4(o9d;d(nsHWD@>xcMnUSEzL2ZM5QxP=2~-UsY2<`iL(eIAa_LxqD+H) zC?6?ByG*sPH91dTvGi+Ze{(wOBwLtMYVK6+u;vY^+vEDua$o8rKsMrt+T2(mzWIq z=#ZF3Y3A3oZU)+SLBa{2aAYZlUv z2Ib<$wmJ<-RUNp>lRS%Z99 z5^_!bj_B?xIzqiVC3?8o$VJ~Q#Re!EmhoqbDkp?J!h)?JG}Es;ojN`A8By^pkQ+E` zXExQUu{dsmDxGef%Nv9>&o3LkqyX|5nC$D z%v_TLUdmq=y=Gc0LFXXRyid^Yr>}5&oE9(UFh>bhjr&MU4Dfrz0Uo%ywR_7gXi4-K ztNRNPDOTMBKECXTTnY0rLkfH)TWa}HnbY?v#Vwmy3 zVLKn+lgu5HVgO~tBH6E@fn45H zOU33LJhdHdKXu-V-&AD4nQCPS|CrSC9t&RB-d+)K2}xN3U?{l5NGP^IakT}K=(tbr zQ``=8pu>|4g>02W69`zIm^ntr8Vc%v-pR@=&A|vY49Dh+b~l@9L$-e&$XC%_=M4FR zQ~AEnWs#xd%Pmv2&|J{9=-3GT$4soT3X8s9v56Ab|t-t=zv0b|E9%dL%UCFAln; zXBxT_Ivmzc-!G)y$5b0jIY50Zvd|HFli@euvq(gyFZnAgEyXgeEl;TB@0Jfc8N$7a z8GOGh4MLU>p#DxzCE*^sgfu%-(P6mysY&@x`R$dsQ{rKDVe8`ht@p0%Z2r=P^-Je( zt*r0fi~GI~<$$x^xxBu!cI(BxdygnO^1hwDTV;J;i}8`ab#H5H6Me|Wr6Xb(*Ei$I z>3i2#Z&};jj?b^I9+^HmdxS|{+1ZNs%NXTWkBlEZadc|x=;WSwFbGu5RwH zt!rpKAMctf8xo16kme3!8whYrTO87fVL~~(?wksOv;(e0-0@JRkVEC!H7QkQ752Zy zS+)$Jx=W-+Fso$_?U0&?s0xx?qi>3)Bq)Ho7@p^}tfj>dxKMPLG|ssT;-^J=J<$(d zVu3(e7bJV%fm(fhx|wsTI+=m!4Cfe(rdXeB zAmABxm1WwOS=y&Ziw@+{5jShfmqdq#JSB%p1Vo28mHVl|pAbSi<78pWj&8eMS}GJz z0td>YCMk!z>*v>Z!u_yGjQsVBt^q3>#G6jVovk2?S_TBX#v99?PqNplv{L(5S}4Gw znZu?J>(>|QpBehteP?PFRxGt$YrQ*>tbkX$=~CE6xVVxF9lw9U3=m{_sC2Z1mp+4! zZ&u610xc$##-+AWbI-e&B%W@{T$*I3%Jv>`0fH`WtnO@`-CW@m1%X^<@fWMh_*A$^ z+pO=LTVYwx63y$RMb-P5?wBzJP~!a(UKfTWOfK#rtt*zcok>L zi%1P81ST;?tF!AnlfcEuhMi!81H&B#CL?P|7{GeVF-TE*sc%Z7y%MbvedvxLV8C6= zf@V$n#90Te=N<*t&J9F_c~h;sqGZhU>>xHxMpSGH_;#1 zxgK6EBw|4ShT?=Wj9+qIvAx3XOyb$yn%g2w;BGW!P`98}&H6qF8$zkdC70*xfzGdWhWG^{O zN|6k5TW|+2CdydTr650vAm<(8eZK&mEOLqOL&Ty4uLxTL$18XNgbWMS`jkSqm4H>6 zX0i#!oYLg{(%(g$wj|~kZNAe4#yYdE^H@NAh2R6}C!CstB|;9ZG!xg_7DiVe&HxW^ zTju)Wig~^AM%^DJ=2O2q`3a4a&%K2xkQU^vqSRYvrR+<`bz4Mar=Hy4F3A9NLF%-4 zgSXrk-Es?8W=`O7@^)<`c>{c&0lvehiGjy$cL~FCd~a5^WMg|VlJg0$QLuk^_C_v` zZT8tI(t3yB;RcPdO&nI-7BN+x$v}}KM|15{t*#?Sb{Q1GD69zZ^F9Nx>~cwkA@fcH zY!U*=9iwZqSBCLTXA~d;4Ihc7v|c&9t3wT3L^PQ~lmRH^h?T{VLHisQN)cEtD-S7I z?#8DII*`UQ;&@ld904Dk9L5ul{NnTsSPtdxu}qcDg&WrgWlMnn_2FTg8Wm7xu7xM; zV=?yyC9Wm+Kok#0wzy0G2!NS2Y$!hsG^6h;J4$f6%aU!JU-9XT(reC=G6juZI=#RTQAPh8i58K`*rm%MP%G7Tbb_{H301($31du_%4H#I$gf%h zV@4(1=)Y?i0vtMVsjC8)>sjjq9+XHen2wY+jPt*E#T?nA8kzJYfGko6h&ABhB@+gc zQsIowo8U>B0HT&e+%Qys1$}!rHl4+lmd>LEB}Ce#^6|EQ^QQ;Oyli7%n??zwzN0hK zG-`*wg3o~)ZzcxPhLVItx}n~^B$H-3(zHx>siI_ie+Qm7%2p8`0Jd>AVCC%OgdTfI zmP}^A3{`M+f|CWp#c*bW8ZtYU>nJd|CY}zg<@Jk+spEJd1o>wYg}b952AIHQVl@VB zp^W3Oco;hKr`RNFOHQvzpbOOj2g5o4MKm11m==I+HU1C^E)xEL3_IT9?Dz#=rn8_+ zHpQrd1}CPc@R7uT;Vn=~z-RUhl`S7%NN%YLcTSc~5h5lY5sA2|Yq!P4*m3Tnww^9A z;Dsa*!J*Q-5#lK!Ish0(t9MSKE)knZt6U-Fj0-{ zQ;uqeTj?AM#mi$rF{*?ZDu<6wEe0;ZP#m2jb;XpF^qvkl`M{Ynq=+SX8x9qgBWHkb zx;tSnxTZ@&J|kI5G>v&+%LdNTVnwrsf-~Wk=9qZPDs9W606u@5AwzPcF?TwE#g68O zbuD|#fadJejK7ILHNfbN;>u4*lGNDK$Vw*bD$4tlOD%{c)1#cfoe@|i>}X>MdHBsJ z94g6pH0j_anXJlyQJM@+HNw_ zE@fd~BHNli@RC?lv!-Se&c^WjyL(}r$~9{|D-?)Naiy(oR$e2vqCQ2B_)N1oWdw9N zSH>=zD@z#HPPX&m&AZiD8}b8K?5EBLbAjzHQycWcrPnsBY-cUWdS>R{U{hfWrJ5)u zpm%4gr;0KfOii1FlVL|qPi?4*&^vd!MX3x9BRTV=qiJx7?Tj9%iz;2&DStU~r*cI5 zw|Ti`_cnK0$0ifP>m6e8-jGtD`nM)_+K{SI%zO?p0`1AEx1o`xS!e%9cSP8*IA2rx zp=yTYV~`L+K|yc1ZmQMlEU7z=O>39el9G`+pGONaVi_eO@dABy)=qv2#*QVdO0I_Q z$zU+AaL(uF4(m|Cth?KN%O8Et{ky^qX<^-8c)NUF+XUH1yORICoKE3_g$3BgEbUN5> z;?oWWV76%vJ~!fFN&DHc_2{oO{bENUjrL47v51y0Q#R#n2w}1y2uu+o&)$obDLrg@ z2N{Q$5Tx#`)<(U-VcQ`1rOmYtz35hp67cNJD z))7)}h}k6t4W~OwW6owd;Ms%pBjy8Ar)|<)(l&5ceoL3i>=>PG7*5u4B0}Q7Wz(G1 z=mhpm6EvV+Vz&$|W#weHL=HK3GaKl+-Lsqbl6tUzzWrGuZskM429SiZ=&hj;G+~Lx zk`Lv$xusBVXotFFHzfEbi&nHRMwZ6P*Tg-(k#dwUmGT&39{EZ87Q=^w+cahZh9FUq zk>*Wt-oc{3vXDFFCPEciV~1D0fuoSaTb2=8F-!PqxMRVDPL1C4E52U(1g9ssGENLD zb_T|gKbc3|YBac-PE10)cos#^}rf^c#@>#&P4ZvNJtC>Rp$ipV-mj(m8e+O6V)0K`ywnbA8P;v(c3Fe_< ztx#N=D_hl?cU z4l{gZOdc|Z)GqC*delrG#&st?pB3_?ScZ9R7Az~IM(jkL@)8FqBxQXguTI%$(tV(( z%O;#7nuHUxf6)9EdKRxI&_u{^VS_w9V^$-Mc*DQB(iXF58CSES-Sjvf9f9esBd$ZdlE zr5a7MDjvU<$?+;Ty{^#&QHkbG)u^N+62L9{2p7&dF-Wo*+1`ZLTM|)U&WmUVQHiyy zr<;TnLMrTFQH6i#h)4FD6iMEzHeYmBG;%FM9--sT;yXsJubkD_-Ot#3t%WFUhPiYs zpmq~j3fB{(O2OCSV9H`1c5dalvGsl!raB>=lqiiVa>1n4_44zFWzpoj~8{%EB+RjJwzGyoi&+FP8LZMuu!g5|vK~(7Fqj59lYvW`dtggAV2@s8 zGmw(latjaGXcF(rY?YU}6G^Wx3k*&LFS-%Eyg#ClV=wuSqAASf#&lYgvB)C)CA#Hr zr_uk~)2YWlgwT1hROO7$bSi5w;W$|?282)kElg87T%HZHCDh_#2I@{0vNOdp*1=X+f)L{-E5XlAE+MQX}qPubtv@klR0*sDB=h(u?LXbh_T*{TS<_c!9Jj zCdN!o%}zO=`)dg=i9o=TrYS>U%1NOq4<$SGF32%Zt!zC}c1mG{Wa`66Twd4Po&HT?@xw z<)%q7JL~6w5Yvb;IQRRW$Q)_htw_=UQhDYm2_5P!ra~u9pjLCKfTF_=qSx0V9$ZI_ zw7R|?X4ds&`^(AE-Oy0@JWF9z$G%ibekMus@N`^v-FvLbpp7LB&vkqlf6&KR2pG~&BaB0rY$_YPtbSq#aUua4gDV=6!VHkhW0r=E^}Laf(vf* zw{$*b-d5t{AMhy;%b{GMsZdp>4*AME3I!WU3ShW0LcyxYV2Xou0Hp*J z*j7+KE1N$bYKBGWL#l0*)%HlIQ2{t<4{VD8U05b_<{Y`Th+b7nGOF<;YH+v{Hs?w2 z8E~IvKgt`^Ij>H&SvXVjOF5OhgA(yqkaq*3k~jnNb!A9{TJR|xWT2xY_rS;n%Z(5gY7Hpu&s9x!D)jtTatJc&fv)bCwow3-KnYh-3 z!By6DZgE8AIgY3#&67W*5`e9>mU(@^-(=2R-&s+LHjEcZWd^Gsj&_L;cYYZoyQ8=I zD~l1g6Bq5QxO&|(6j_KU{u5R(0F^2uNj*0rh8Taw{!diX>ibbzwQ3x81nBUAE4h%OV>^l-iLuXg1B`*<%EU=QAPD zR||hu=(8c_U?x4Lw`6FCTUHP>AQ3C0l_xLYb!;*6=&_XRAxDbvoYxe1^ zW76fyB}*Q-Wd^t4E%^{1r^*+O_l$sZx0iHs4#o{XL9xXQcmduAtweFc{!9;W(v=;>F9P7O>G6M|Ge! zzn)-24*>n=3;{DKq+Uf4Vyq3P$_@0|PG2-oshik}uC3Nhnn|(iXCY_XL8&PnZ)*fs zcd)enTHabPnVh1HrxWuSpr=pQXy9X9yq$CF4?eZCdzCx}b*E#k&1aC;gdB&Rg&O%d zyz1v*Jdh99Np*sw;SgU50xN6jp=Ovzj)zcP*au1nTQA`U{Fq_cMXc{sZb-dxmEM};p|84@|1 zUDJceK1Z7meraDWV*jN8u2T>6!R^FMug#k@;~A~Dx5y;v<{fhy;*vmIhUE-*h09x_ zOeR33cy|&wOs#QEx$|}sw^KkWo!>s8X3&=nSmZt%JC+yHP(pPxyB{Q8Mvzqy)B{^!76_$-dCm;xW!FdQ1I0pct zIF(*qx(LaMl^RUk1e}a1JX|(Hb4W3bt)x@!vIwqG$6SSTtmLdK-Sy4}nZw~c25r#b z9VDG+lr8Xp1w~2J27fGOBBDaGR&6PHgljjQQYdy($ID)Dyacc0l1OUhaietJdUg&8 z$I^8a_%m`*=Z;85vk)e(tm4SKNxdz0V{d0`6NOvEfn<&shC6m29?mRLIDNj#Tz?LB zBSp%=hH|TQarC0hbtM+o(turhL<`FT;c{>bH#v8SAlV6a!?nb47uG`$2OS0hh5$H90XYqXsGi z+2E09#5AI>Fy|x5BD^|dj>YokxDq?OgFFaJ zrk^B1lTDHU(tW*Cw)ly4rZIm2wN!dIv|GHWUT)t^O3bNo`N2CEc%kRaQ6+qhY%3nQ zfv9sT@{sf{PoQM?%x+oUX`g#zv$6PlqRe%9RN(mW=%>q7qnd^e6rF4_#9wX*jJ0;0ifhvT<&P{g@KfwlsAfhG7@5ughb$5w?7RJ zfo=}SvY_YArZm{gRy%11!5m+`*fi^$iXcB=jE%X&!CkEZzIR`0H_5ot_4zpt#;Xmu z&F2vV4xWd3Qw+Gxm&e73P!1QvWiG3!&dGn%j>a0vc9CK1iS18%AdQSEfnP%WR*{Aph^cO& z94z)350cSE$qSP29r!^0d(7-+Y3&FTv!PBqvy6^}@sM-rC>NJvGsqw$2-l^$K50-y zUESg5GLcE2M?O9h&c~$%#TSdY4|xDC??5>$ov57$jxN&_vDkae;R+QdA-5#f_i7vm zC3)RWh{#f6B8Zo=!*Izv26#+(f#E;`k>I$Szmbr#ocAgdyNM%ja?@G&H-B;ReX@_^ zd?eDnBRl$iIM#1&%E+%=d{nCJ4k{ivI>a(o!=55Hc;*p1t@uSB8P7Z-Ph-^8)p|pm zF-Mg8{ndSMg61TPB_~oTn{c*NNT5f203MR2Zgd;lq#>_^26m0Fzlh|c8O(Ms$mG-gT@6Vs% z&L`PHS@z|FZvn}5%YkWnFYWIB)5LAd_f_(7riTv1V!*o{fv3a#dyUi^YUGqsW08-M z-X}pFDHcgji>hFQ27P7%#E@<|`8CQ`xd1VD!^~>PDg(U%r$|0TPH0h}ko?>BYd~c5 zE8#4Ix|(y$Q5F9O^UpR{Wod*gZ(~LQHbL6$smZ>y+X8q+llZM_{yjPm#&1)UzU0uf z6#16T#5qXl@BSu%t|)_#&5(aU%3jRNlt0WwPkF8d0oESEDd%QoDdVc zf+Hy6J-mBs6@hcSu$kI4!U32TqjMxxpv%w~0s_NM4RL^0hV-4`932h@kP841?|gG= zS;oS=b$kub0PEu{&p?|U6KKzoc@e5|+IFkIwtDsusYnv7OxqgtS4y(MjP59~2v7!s z*{$s+F80L33c(5X7x3M|yB9|WaemGq2IW#>G2`5IJeZogPEu`rKq-{ zT`fK7fcgS%ttGRbn}Z`1bgoVKa2b1;kzuH+781pfEhE1Y>*~4Fvnl1jEF^Pwcv}fW z9Nux?pyYfu%zi_MR;jO!euE<@r|+f6#>{jyn zus08hX`TTR2!Q9q6d>h&c3QZd>3{|Cu^}H&n987y3v-D)soV(YZBbH%BNJ64t*upw zb!#u*6_dCMH2|C($Da2HN0fY|oElh*ow>`&*2&pDA~4>$bmA)KF$>STqiRzHTM`S% zJ&D>O5i1+Yn-=7O)@Yg|%@LWNoJc&fCMN-yrQpqi_EK?a!Mp8!(E~b^%%#;bPxIW4 z&sn}nc7yD02m%(I?+|N}O^YfN=cJQ)EV3*x5#{EbF3OlLa-T_Iz$y=Jkq}#D=m_Ws zE4YHW@Il(e|9X4me$G{w%Fg}1J(|v(ixcY58ak<(j67*WDs_a8D1xPIqR$X393(Ri z7B@VQz_y{#q?G8-=1e#5&L;*-`pEc~aTGF(05_S$r;u;Z4izoUVR(=$HUSiXpMw4( z^r8F|RxZj?%$R!vQ#P8gV9upt(Y;L@-$8uX(_3tO?~QGljz$Z4lcr@ov~)K@3&b7B zVOp3$sztf=nflCSj1B?L!O?uQ5PW3=cEnA7Wc|weDyPnm5<`T$YsL#+0z%>vpY^oe zzqGS{p6t+MDO_E_T@i<8TzlOmy5n=+M>y#?xwo^mk2gA}btW}RLY8|E?6uCkH*ON% zEu<;Npc=>&G49Y7Q|y8HlaglLskl05w<>tpRtdG0HAY=xpQts;Iy0h;zQvu}A(acB z8>BsISl*uWTKT}M@_IpzciF%L=kE1tL@~+Ilko2OYJnh`XHAC}+|m7sFC;Fe#FOA*bM=L^0eJJ4gqup2mkO0baxD6k zPE7KE8h{G^3z)Ri(d77nQdCML>{d!=D{YZ+K=b4U2Ib1G-Sg+{NSWb||1@V8_#@;{ zRCjTsZQm)b!s{;9CnV=MkLYS+F|JL_(zp6b^}=Ggoc0TJk_qbK{;?A!jRY}2HwZ!z70 zqv$K^VLhGdr#ne{I@8OGA$C*cj&rqnf))rHF==9VQF(Qn?l5e{&Jhkpgx$hjQMl;; z8lk-WpC7jFW*eZCe3py|C5-te*&G=G#n?H&qGCmSR3MSHN&?tDx!qh5Z5Dt|g zvh)^Gd%=x#Iif16He2qhRmfy87wTd?at=U!=_`Y`kX4&H3q2en1dru&njWZO(JTf$ z1ds;n?p8{;jQ%7Xoj3P>V!hj4Ig6Nso)t+o|#%BdFV9t;c=8vrbd zET#hy!mh?=$fA>?{t6m{Bivy~-iyU4H-o0c=`@|5gqdULB0w1uET1zk7Z1>{PDt@* z$efj0+mHis;iV*)Rz^nn<6B8Vax1@blUd(WDbc3}_6tqLY2l7QSo`XEePSn$m5NzM z+M(((^zIalDMfWjvWPgIA>or@H{6L&iw4|nY7V^5jcLb2^x`_<)+>Z6X53V%KDV*H zxfYy7bCE#UWk_P`ktTfV>3}rJ%Sn(#TMlekh%+W59Wx6925&G|?bXDD`Aa5Tw9ZT3 zohV=Aiw772-RE$^9ZvCRorMi2oy%T8i21`%edH4r8G5{wQIy0UL)m-CH-SwQtvic zD3>HZUnPj}LPM`}dJ5dMP%7W;I1gvNtlGAgs{c6P8}jP;^VT9GM$P7&X}S2NzX3eV z4?_DjnWEinGMxuao-8>E7}Yvht=D$j6`^%ecnFuNkLV&3zO5e9q8L1oys>sZwMK^D z*6vk=P>$)=hR@Okb%=*=Mi*qm%U7AEqTzD5vHRRE^L`PtMC^e%Ar+<5CBpV5h*u}^ zEXR#z)6RwiOsE!tu}pjNuMiW1VK1Mo-&IEF_4;!7r+PkTT@YMtSYH1)mI;i6lpMpk zy0NlpdHi`1QP*(W!VQMAWWy&VE}S7u;DV*AVgD-#!^QjY*9C&?tlUTC#?>~y+Kmcz zWR8xz-(w0(bnG0QD5VOF`ryByKImsDXtJ8%3}z!kp(u%CfR6|{Mm#= zHp%+z^Xvwp-RIdqN!BF0F}s1FspM*IOBD+W*UPQc&8wzA=}&H(R$i4VR;;n6idR}` z<+il)Q!M%Yij`lbf>&C8@6S0i-#@z>u)Tf#Hks$lcjnBQ`OeID=FFKhXC}D1aYVDr z)o3WuueIA|@}um7#e^Z!G`e7jT%*T2{;V-b%F)tegtLMqU#Z>2i(-_Ny2X%cICNpD zH>Vm_W2rPEloHKlq>Mp?7tAfhSuR=S&;YYX87G0b5K)KikHrsJU4+eUI=iF>x>Q*T zi@lrGx&XgNcXR?->#X=Xh z8+3Ls{fP#Ul>-4*jr5W&+l_M&F=jTFDgE))ndA z`9jsWP}Yd1oIZ^U%>~CyQ@N1@2dFh{$SC>qQp_Fje!Q)-5a|b7*gLXxW!Os8{-IsI zC)sWEMC~w)V!0tjGg3E+fEt}(191#W47R%(A~p^U~At2gh#al3_{b zu=|#X-*^mGzgkf`4idaT1_5q3gD;(c7#NL&CD>%9co*a`?UcsGCkJ+p9+;Sfp6L^q zgql8t2|r}QL2q|pK*o}-IQ3no<{L9hC=-baLMT+g)?u4yfgozBjvV5i)JYmTm$99a zmT8bk;Y`BE8Fe(qBr;Q?DP@T$K7B>;rz)RDtEM`Dc8`WmRM9;!55Q;W_n`6!Vt!s^ zHwNy8it@;cPTBRVY~L>VU}+WIFu5vu3tBsT%-YzCQ$wOhgDT6J)-{3m znU1Ps-NB}Fx~(_Op0n=k&>vrutxL8b4wFY(r25pPKWE3IrkU}!FpU!~fMGgiXj|D~ zhqyV~mq-ReH+f$$N5RbNDl4Q660M2dNTalOAI;o`5grREVajG>gl=cHa!n8yOpUHk z0nOHPa)`>dsp3*_-8(QuBx?&A`~5;I?E?Gp`pk12(om<@OKi8=&oEI)3Aw`E>OS0j z!I*a4#*IDf+w}!Q2Q;Emq-OdVZo+vjgeEs?+B@`+19poZGBSxjkPmP7tP~+X9U3~>nn<5hi@|XXP{IH&xBbx z6BbMCt;-*!vuGFPBugqfzUE%;SLu#pu!etI0iQ93;@gqOFwtZWJjNwzV2V@4sH{3v z0XElikmf71eh-p;hI53i!PG^tbwNH|+nFga7$CzQ*`>c`Puh81cUbz1;Xk7Q=uIU~ zgN(6fqDwG`Y!AR^s5E%Q?>>P~^yPGVe9^9sFmqYf=zd26yffnjeM}q!O=Y3UzLnK! zRv{Sm2C%5;>4Anx#WVI``~yW&A!VMafn@#cODvO(u_3%4W=wWR3D1AY2E(Y z%q3!0M%((nl4-~PyqAXgonf=BM3v7Hu9sfX4`oGI@{c;+>(V*_4NsEPSSQ?Xq-~(rH-a7!iXYPca!dJ(l=!$ zdWj1f*wPL6j**-%D=k&;X!V%O$YUG0YD+r7MpS{dXtSfc8#W;>pTxu|VG+`WmKj9qLEbGY5~ z9)cJhw5Ae@ICv3ndf zfcYFLPA=YlVA33!&X!y-T{;DeO|H9~*^HhRo@n`q%aW2thDC9se<_OsBVpW}G{&4S zbKomMMCq;dw!t>tbiWsK2)4v%4NtZRWDRJG0bdg8>55Y8VDj`<))AgISu$qOwSvsx z>(N>LnTePOSP$w?Cc3V;B8Oq=av?_f$|Q{x4l=3@EHxSEd*JZcU(NWbs=#V;w%IhX zFgm-4-T8RIg9!+1(~Uc>W<8241=X@ms~dC+E6t}VHTW$Yh4J+mF)~t$%RF1W^PB7~ z_O9asGoO%qxbP{2qzpo^x!`=3Sq3os`>?t}^F^Yw^;INSfi8Kmi5W=x18;1yE*R&; zq?ci9scM+=s0+yyU{n}p=!oY^;63tDX`D|g*KX{irgN9BC`fB&d{#oN}_b#H6!bH-8XQt({Cjw(eS ztWS*C2?b6=3~`qDJsgG@8o(XoFvQS7g-`@|DppX5q$V|WPh41#PCHpHqs54Zy1O@E zkIE_){Xp@(7(DfZXPIZHgwJQ^ftzfhHhq;5R;DxUiXp|Eea%{cLFihK_H5A2ArBp> z(y+-Q86$c~&!qH_VJ)iI%tK3pKnD5;071$h^%AXphNr`iV(u3yfcf1aNLzU;{9_K zKTV}X)e-xY;sYGj=6-QZ(u^@pm{fZu40FVSpY(&q<*leuDASey$O>de@0aw<)O8e5~rSeS%p zn%O;$!X;++GGB?hy%_Q>QoYlvPGyT*h=<0>xME(|;5}d7Gh|$oulOTOUrIUQP{{ zk8Or=wCRet5r-Ex+u_-X_}{E!w2@07*$L4d_pUXpW=?ueGLqWrM+5b=wNGg)rI@x> z3@fFQKIAj)2_Z3=`J(x4p#(*0-SoMr)~z1ws)lDeAD3UsBt0q>|7fW6b8)_8h?3+) zK@maqAv!`h5Et`HqT!^8e`{%E@5IP-q@2y;i0GMVr9qqZy5)v5&AqBkX60mynIReu z$(ae%%hCtV%WYY&-qnejZxm6GTe&8RE%(H!Yv6ksQ^c-`at4IKCAw_Kts0*J1w~d) z{%I|B1_aUIXrQY*G4h>3DCQQFUxvoASEjN2mCAwLW!72g8HH`zlT!+|wZxQ@-MPkC zr+u~4!lE4uokfa9EaazMCF~CaVLOARIKk}$obu;Ffb=|fcoup(b8WD(&o7P=LqSot z**S;Am&ey8AM*>Vl4zpMcn}k2S!$myrSXtVq^3=5BCS-$PO4;gjt}+UXAD$sz$4ZJp4D7Pt`O|2m*JxYpWdwFb~yDePA7rXY3 z51IkSpiJY!56+!naM+BJbR?~?rK_hDTLeF~X}qA_!w8biYE)&fSd^ZeY!3;_tV5V= zxxVbac8b7KqO012l-}+)=cx5k9dM1jF~+e|)vO+L=VCeWv(#i^%APH3q7TktNioZb ztYpZJ{M34mL^3y;l-ajxIGgzXG?pfjKndn^d(V2-zC7Dzu-em^5Lbq=K9mh8aNu=p zyrd07^9`U6S62&R!f{Dqn{BMvmNo(~o8i;j!6ao;kf{+b?d<4SxvHb1ebw?+*f3au zuEh!skmMgWcsa|eTf1k3P~QtjD1!8Mju6 zz5}iuE1e8+^%0a%cA;_v|2Mkxmh^o5Z|^P8Is>ysB3=o zrv~?HoYXH^vTU(?_{6qsxZb2bX)n&O6MX$IfAA+oAV((TDyN%ii0rt<{D?Uh=Nk4G)mY+kp94_P9c#13v+{AjMf!3NbQ)Zdwg|R9|F2oC_ zou;K6Krk%;-f!Ag(~Kw$7CF5+Sv!!TnO*&*W9gZP?9h>~^qC{aZ1L1CoDZjZu->?0 z#cFo=P+7zfgg9WA>)K}OOu4QYm&AUlnRSE7^}B-GN2fP7M{za)`K)~T~aSPGb!p8f$h zNt$3!4JiHvIp*mE}4lwmtu>4@N7 z0|euJcQ`y@)$L}5)eI)enP!#+v0=GHg=JO6lO1wJGOdOCGLSSM(1d6g(?HJ-66kx) zDM?6?YvYbhEE`KJw48B^w6pGq!s4U6o!bz#Al~{FcSJQdONDT@r8QB}Ub>xVSW?(M zV5;&CDEP!A{6B@;Br8~IOl;-oWIUze92DCby>V-#-?v6OldX}BoPI06b3Bx z<#qj~=z(JHG7LJxmTOri4{RRTIp*qmzPd|RTYhnjRx;R4z>ETR3f#&9TZ3qzCFT?` zDPa4;o%))ypGnsG_-v<{XU0>=41dm8#K;f^HdhOVJ(lMj z9i7C^gu?&$9~YSgZdlTBB#$V)BG_Tw#E#JWO6}->W&S6sY#~rPKtbO_@~LnmW4q~K zGR=g|Aa20h=vIJayOmby-MleugqY9fE4wu!Y`Ah!a41x;4?&{MnXS28C=@ll^V##l zCKB7&y<8>}ILWTe5TBI?uH~3hPj6}3v#L4yg83lrlAyxIP3xE!ea5zPFByv_X~R_B zWs;O2q%AGFdSr6w>dL#4(u5lXJ+=zlU)fk8{e2ULFA{VA3}9~V zzayCY-?+J-9s6Eg`eAnpbR`#x^Bs#{LC|koAOq{KXKXaqz9bGgd-osj)~y*eUMIwW zHrzILa34W!Fe}(po8a=YL^Q2v2DHPan9evXTlRV)NuZN-IzEEJ(BOy*!J>%D1y0c} ziuCTe@0gKF+Ur@RdS=9--Ft_xig8q(YYkzd!i?C`;1wj*zZ_MPvK-)kf|MZ+ccSv8gI{&v3-QcdSLNKZ( z6GDO8oOT0_Rz~?PNCG5>R&FxrK%?sjJ^T4Oq8<0=+hpD;yGgG_PHvOlP1c61KGbcy z*<(vFTYB38$?5s)0N(vCqqTb0#UUuAQsJ?Qgici}Q*A9fUl_*8p2R|d!aKoURDwB)A^g#b`w^wD~jRwrj-@a9pe2bdC)AXsP zzp;vEjG@Mn{f=SQsMQQ6q6;;1(Gf7H=zyb6F;gDgo0=L4CXU?39?EB!jAI+z4+V2v zm*nZq(BWQa%FZ~7W$DZ?>QAw0=>aww8`CXCC5a3;|Q<4X?Z- z9#^x+@ZdDcJEE1uNK$e&3dw+Dy13D@q}DvPtlGG*KDnEROmB4#38|b8x9CzbU-7E? zIq;2%7hSaGroA?GZ%3wUr?=xEoQ}v)O%CA0ABjvjN7u6%B^*SM%=G5dfKbr}Ik#d+ zRi`3V9o;(Q2C6+`N!!x4cK>Jl?ZH4(+-<|4Gi@cgJ=3;~N1!gST3c1N5{?SLVgqfY z)d-{Yu`x8512%<&?&}!9m&eh~EC+U>ilcTk>vU#9sNaNF6-?2EQnQ^uFtM9$%52f? zqM5cWo0!h2xVG>Ljpo1dpwHL4rb@|*d zbLjn%zjSj4;iX9;-fKXTR^)J0A*9pkSOXt}3{9<-Xu2}WUm-JdWi(s7Xl+JJjfMO2 z_Dx)#r5QKw1E*^p##hOTmK{XTIgtlS%1SXeVl`w5k(1*G_c9Hr$jrLFzuA6k4h5FY}J;XKUQ-yyz2>YNsMg9u>)YnRJDGw31-Lhw6(XWtu4V8x#OdMUgf?A*po$h87&|n{WeR?S0wP;QVMrZ= z%F_(p(StS4bY0IVzs2o31ixO6sYnaL%u7lwKdfYDF^4hDM24mpxG2tJ&c@~`+!S^s zjY%-WrA7m@ToE4^3+pz#ld0XzwyQsGX*+=)lkc4oYA$Fl`?%=(6XMKKR@c3qJ4%Lv<8D(U2w)B!P z=N^KMEf+JM=`Lc1@$M)!Sf)FgwN&jbt;S}UjqX{UC-wmuD3OfQD^$ZON!HeVQnPOD zUXP~VUg%}pWt;K1rPQ16oIMrE=d?!kuClGWlzKts{kS**wS`H$N^usoZ!nBe(=8-; zq@N3jhwkXllGSY!$JJZn`Ylw)r78}J3{3Nhy2ar4w^z9`*R(70Nf0}cB$vSK1$%;D zc9n{F>Wi!B$zSW0G}E_6n`BpFl1K>X0wd1KQM3pY0!oo;yUsPJ(JNghYZ31>kesGW zcv3zM*H?->oo2a>TQ_XJw$#b&VQOvK+T4N#qaZk;tKBrpjjiYf>wu}6-OT^#i_e>s z(Dlyx^Gobm3I@9ed3C$Y^gQi;qgmx}XTl+OvyZ?)9VLb~Ke3EJ;Ztv)=q!21Hu<@9 zm3_vUb{$)ey-{FJ4mc#GO&p2wlP8DNqn$I(uS9Go)*1v5u>E* zX_R~W(yezrsD{$@vu_LZZmu%(^>3qWsKx7WpSJF28D_Po&PQmMflFu|r8B{Tuq}-e z%VOM#ip-AuA_sSd!6+~)6D%BuJmZ8!7nhT$z@m^phMZYd3xPVa_Vrsb!V#w}U7NOS zWII>m5DQG}nhQE+s&g4gdJ();!zqpAi8r%TV&bd) zz_^WpKJu!!mR5^H&Y4EzIoTp*Luq`dm9az;03CV>1K^T<9^;#>spSwu)o>z%uE~*p z8&ksCtYo~?EJnduu%v49;-+k;G1)BB9%Oh>&&pj=j2PCMMjTTdeRhveOfvLLQ#YmC zV>yjQR8-4v<-L+8jnf>h-akH3;vCiVU_RWT0rpX@LBV52Bx$a=LMO+jE3u}Sc6iKL z9R>*7F6DgI#_mcy%0>N7yGM-T`}gG*g7qnwU_9=7J7aBD9d_sXd@uZX6~>0559sO8Jb+Id5oikNC+W%D|Y()i&JcK^{=&{0OM0t6uu<`Qp*M5L*n zt-=*&@ES-7f_2qS9$CHauD88M_r0+|qTLzAO zN9;;winsx%dtapr(W^X4vj^LY+J#Ds^vd!rGJ%;+#A71G?F2%k+>0^cMbQq6G<22+ zGac04GzFdMF=4ur@|AAl@g8OC?J&odyUBkHA_v)RFr3Fy&+X=MB$}O>HEWi291a-vxO8QFObqa>S<`7@W`2+5 zH7wEA9t~rx%hJ0s@{eibM>&Yvj58CV8~bn?w_Rl`$3xa{)VVf>I^9hqlANf~ZP?KV z-FPdZjb`biVH@)ywm}KvL&9HmZP<|VS9-_}9l47(XX-}H5>1XMYQXLIL4)uz7=#+* z2yawNb77+1ZWc{L*x$6G%#70Jbt{%~*u8u`%_HM*Mki3N@7=%K2>Z5tw7A3Sj)h&h zB$E?r5+8V&@6>=+5&57vLM3`eEYuQCSH0EG{cA*WsYP-)YudPrSY&6;NEWNM{amjo zdCAUUlG_BTY=XL87-_ax%fNBA~x3II5 z4K8LI7j}7$dKqIDVHfpDWSRZ22xpvBrA^ltnd7OSQ`vL`$z)x@two>W<|r+B=smTh_U1#RwC>t}IBn zY*|S2wUA5SwIVVO11`f@Fy}Hhq8G^Iq;$&Cvt7Mx+4AM9mbEWm*}0-))v6Vp?W@!y zsSw+#l(1I21JeTxV_9-GNYTlYRkTL#l8vzPnVwXruP{%F6V?`cmGh(n8#JW%%A_Pc z*yr7#Tg-%rQbl^{p{>EMdPGQYdNx$fdt(WLT_I+?ACUpG{I6lIp6K75shT#~V z+Su8b9gwBa>18u9s#X**ys2^MxF3?;Usj*1Y(inyL`o|QGIWq($A@;e1-WL5!F*I~Fom zgz9_Dh0rAI8R*`C?CrYKMsqP$L9A4|Qr{=zozxY=C4BZRrEB}dQfyHAK|sZsV?NcT z(i=()H2a39`>D5Jae7_(Iy641cso33Xz5Wz>-zR( zwyW=xNzQVRi5q4OHNH$N6{nmz_>ZL<^mgcd+V(~fJJ|E>>)48^ls;o9lEnio+_ok=A(S_;jgEDMZ9C+wWb7y9Uub zWV$03=707V*6q*&z=}gh-+C>(Fe+N`8{^i)F?KH3%^azdeV=L1Tul{?S)&{yF`Ei4 zH6}?kY_Xmx^v(k#TyGH~z-7+Y4Cq`!?f@c@ntK4@dkL*%$3LlU_R+OD8JD+a)r`hX zws)h7)W+2-yEfU>pfd=pqmVqS33_R1m{@(4)1FQ5CU7DWL}+NCkQ-WO$32oZu;k@i(K&uoV`nwNAy~SLHe~Q?ya@tI?zE9Qgf^9iG4o6jb&xo|0grhT zligCIV92*^0A;9~wxDV@KuxbE-K8(JrknJ+TYGep02;V%+8YE|2GJWcx6TH-_iJljPyNu~nt)FD>g>wmfK70Sh<1}S z_FZhe_on000M*Kw^hRdfRi9O-C(<%EGdA`%=1Vh91ysxo=pw1!G&5A`_Q{HcLxmEH zV=bndA&`wD z^(9&Q=u?yFXEPLpk(~{wpvM~{^7nD+)IF-hC5#p8xLW0UM4osw$Fo3Su)lWWHkox! z2Yox~jJ}5-dB%geOcR;Hp)AGZf6}A$F~Br!??%9sOjOpI-afMO&(@-S#+k z(t5#mj$j<5);*3oe?~tWCLlM}Xm2T4@?b&lR={j*$Y@#E+)LSHff?IXKG#yz^r{@4 z5YTI_a+V{SWfr>;{3=AXjH-hTl|9#8%Si>-STR#nrn@4a)#OIhS+}6Sz-@^V!pVd= zgR8Wf%#?%-kz04#ee*1LdUzm<;(^Nccq=(wUb<#hUG0bB{=4x?Hgm2ES3hL-c^Nya z=v%tEtspITH4u#%(=WZ@?KW)grV-T`kvU_Sb?YP4irx6=8z`m1M%0A3x|0T`fZUXe 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 diff --git a/Me_Lua/h13/socket/ftp.lua b/Me_Lua/h13/socket/ftp.lua deleted file mode 100644 index ea1145b..0000000 --- a/Me_Lua/h13/socket/ftp.lua +++ /dev/null @@ -1,285 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h13/socket/headers.lua b/Me_Lua/h13/socket/headers.lua deleted file mode 100644 index 1eb8223..0000000 --- a/Me_Lua/h13/socket/headers.lua +++ /dev/null @@ -1,104 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h13/socket/http.lua b/Me_Lua/h13/socket/http.lua deleted file mode 100644 index 4f8c1c8..0000000 --- a/Me_Lua/h13/socket/http.lua +++ /dev/null @@ -1,356 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h13/socket/smtp.lua b/Me_Lua/h13/socket/smtp.lua deleted file mode 100644 index b113d00..0000000 --- a/Me_Lua/h13/socket/smtp.lua +++ /dev/null @@ -1,256 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h13/socket/tp.lua b/Me_Lua/h13/socket/tp.lua deleted file mode 100644 index cbeff56..0000000 --- a/Me_Lua/h13/socket/tp.lua +++ /dev/null @@ -1,126 +0,0 @@ ------------------------------------------------------------------------------ --- 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 \ No newline at end of file diff --git a/Me_Lua/h13/socket/url.lua b/Me_Lua/h13/socket/url.lua deleted file mode 100644 index 92ba7fd..0000000 --- a/Me_Lua/h13/socket/url.lua +++ /dev/null @@ -1,307 +0,0 @@ ------------------------------------------------------------------------------ --- 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 --- ::= :///;?# --- ::= @: --- ::= [:] --- :: = {/} --- 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 {/} is considered part of ------------------------------------------------------------------------------ -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 diff --git a/Me_Lua/h13/ssl.lua b/Me_Lua/h13/ssl.lua deleted file mode 100644 index 1cf2e39..0000000 --- a/Me_Lua/h13/ssl.lua +++ /dev/null @@ -1,168 +0,0 @@ ------------------------------------------------------------------------------- --- 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) - diff --git a/Me_Lua/h13/ssl.so b/Me_Lua/h13/ssl.so deleted file mode 100644 index 40b37c57d73309f9c16cdcb45996f671c7f7d952..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67881 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 xrN|v*U