mirror of
https://github.com/lxsang/antd-lua-plugin
synced 2025-07-16 13:59:46 +02:00
Compare commits
80 Commits
multiple_p
...
master
Author | SHA1 | Date | |
---|---|---|---|
1ed346bcfc | |||
b0812d1e14 | |||
22f62fcf77 | |||
243e778ac7 | |||
b69d98d205 | |||
f19bd01847 | |||
869f13129a | |||
7a1c58009b | |||
e6004d8ccd | |||
b83beb5a16 | |||
c7ea2af3f1 | |||
7814611008 | |||
4259ec7eef | |||
6276b0aa1e | |||
1cc681c7e8 | |||
dfb550308d | |||
ae5dbf081e | |||
ef888164b7 | |||
c5e2de08ca | |||
8dc0c7e133 | |||
e370f3f7fe | |||
deaebf1c01 | |||
45fcfe8726 | |||
8b8a79bf90 | |||
88a5354588 | |||
ad98d1f666 | |||
faca12a02b | |||
3069f0dff2 | |||
3c602dabd0 | |||
1396fe3d41 | |||
2ad3b4dfb4 | |||
f575dd91a9 | |||
f995bd7f71 | |||
8a2cf714df | |||
8b22577c86 | |||
fbc5c1c4bb | |||
27d2cbfbfb | |||
36f4dd0941 | |||
fbb72201e2 | |||
83635bbddb | |||
ca57959c6d | |||
ba20d5c53d | |||
33df50753c | |||
c84594a490 | |||
daf0f641cf | |||
807e56e331 | |||
7bc0a89ef5 | |||
454217bea2 | |||
002151f1e2 | |||
0b6fc559b3 | |||
14f59390c6 | |||
a586901d44 | |||
5e5b76a267 | |||
f387ebdfaf | |||
8d7392bc71 | |||
c6f2a05164 | |||
3f33fa217f | |||
d9adec8869 | |||
24a681a962 | |||
f4976eeea8 | |||
3c1be8639a | |||
68c9177508 | |||
f176ddddac | |||
57c8c92872 | |||
a6984b020d | |||
38724476a2 | |||
2a89d5a441 | |||
22d16d0f9e | |||
19172d1e64 | |||
d321724ae9 | |||
0d28bf935a | |||
177787d07d | |||
23407703dd | |||
9844bdebd6 | |||
ac99eedc71 | |||
21f55f1000 | |||
00a35be0a5 | |||
8948eefb6a | |||
0acc227445 | |||
53a4022db5 |
28
.drone.yml
Normal file
28
.drone.yml
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: exec
|
||||
name: default
|
||||
platform:
|
||||
os: linux
|
||||
arch: amd64
|
||||
clone:
|
||||
disable: true
|
||||
steps:
|
||||
- name: clone
|
||||
commands:
|
||||
- pwd
|
||||
- git clone ssh://git@iohub.dev:2222/lxsang/antd-lua-plugin.git
|
||||
- cd ./antd-lua-plugin && git checkout master
|
||||
- name: build
|
||||
commands:
|
||||
- cd ./antd-lua-plugin
|
||||
- libtoolize
|
||||
- aclocal
|
||||
- autoconf
|
||||
- automake --add-missing
|
||||
- ./configure --prefix=/opt/cloud/artifacts/plugins
|
||||
- make
|
||||
- make install
|
||||
trigger:
|
||||
branch:
|
||||
- master
|
126
APIs/api.lua
126
APIs/api.lua
@ -1,10 +1,61 @@
|
||||
math.randomseed(os.clock())
|
||||
package.cpath = __api__.apiroot..'/?.so'
|
||||
require("antd")
|
||||
std = modules.std()
|
||||
local read_header =function()
|
||||
local l
|
||||
repeat
|
||||
l = std.antd_recv(HTTP_REQUEST.id)
|
||||
if l and l ~= '\r' then
|
||||
if l == "HTTP_REQUEST" or l == "request" or l == "COOKIE" or l == "REQUEST_HEADER" or l == "REQUEST_DATA" then
|
||||
coroutine.yield(l, "LUA_TABLE")
|
||||
else
|
||||
local l1 = std.antd_recv(HTTP_REQUEST.id)
|
||||
if l1 ~= '\r' then
|
||||
coroutine.yield(l, l1)
|
||||
end
|
||||
l = l1
|
||||
end
|
||||
end
|
||||
until not l or l == '\r'
|
||||
end
|
||||
|
||||
|
||||
local read_headers = function()
|
||||
local co = coroutine.create(function () read_header() end)
|
||||
return function () -- iterator
|
||||
local code, k, v = coroutine.resume(co)
|
||||
return k,v
|
||||
end
|
||||
end
|
||||
|
||||
local parse_headers =function()
|
||||
local lut = {
|
||||
HTTP_REQUEST = HTTP_REQUEST
|
||||
}
|
||||
local curr_tbl = "HTTP_REQUEST"
|
||||
for k,v in read_headers() do
|
||||
if v == "LUA_TABLE" then
|
||||
if not lut[k] then
|
||||
lut[k] = {}
|
||||
end
|
||||
curr_tbl = k
|
||||
else
|
||||
lut[curr_tbl][k] = v
|
||||
end
|
||||
end
|
||||
HTTP_REQUEST.request = lut.request
|
||||
HTTP_REQUEST.request.COOKIE = lut.COOKIE
|
||||
HTTP_REQUEST.request.REQUEST_HEADER = lut.REQUEST_HEADER
|
||||
HTTP_REQUEST.request.REQUEST_DATA = lut.REQUEST_DATA
|
||||
end
|
||||
|
||||
-- parsing the header
|
||||
parse_headers()
|
||||
-- root dir
|
||||
__ROOT__ = __api__.root
|
||||
__ROOT__ = HTTP_REQUEST.request.SERVER_WWW_ROOT
|
||||
-- set require path
|
||||
package.path = __ROOT__ .. '/?.lua;'..__api__.apiroot..'/?.lua'
|
||||
package.cpath = __api__.apiroot..'/?.so'
|
||||
|
||||
require("antd")
|
||||
require("std")
|
||||
require("utils")
|
||||
require("extra_mime")
|
||||
@ -24,6 +75,14 @@ if HEADER["User-Agent"] and HEADER["User-Agent"]:match("Mobi") then
|
||||
HEADER.mobile = true
|
||||
end
|
||||
|
||||
function LOG_INFO(fmt,...)
|
||||
ulib.syslog(5,string.format(fmt or "LOG",...))
|
||||
end
|
||||
|
||||
function LOG_ERROR(fmt,...)
|
||||
ulib.syslog(3,string.format(fmt or "ERROR",...))
|
||||
end
|
||||
|
||||
function has_module(m)
|
||||
if utils.file_exists(__ROOT__..'/'..m) then
|
||||
if m:find("%.ls$") then
|
||||
@ -102,7 +161,6 @@ function loadscript(file, args)
|
||||
end
|
||||
end
|
||||
pro = pro.."\""..utils.escape(tmp:gsub("%%","%%%%")).."\")\n"
|
||||
--print(pro)
|
||||
else
|
||||
html = html..std.trim(line," "):gsub("%%","%%%%").."\n"
|
||||
end
|
||||
@ -118,12 +176,63 @@ function loadscript(file, args)
|
||||
pro = pro.."echo(\""..utils.escape(html).."\")\n"
|
||||
end
|
||||
pro = pro.."\nend \n return fn"
|
||||
--print(pro)
|
||||
local r,e = load(pro)
|
||||
if r then return r(), e else return nil,e end
|
||||
end
|
||||
end
|
||||
|
||||
-- decode post data if any
|
||||
local decode_request_data = function()
|
||||
if (not REQUEST.method)
|
||||
or (REQUEST.method ~= "POST"
|
||||
and REQUEST.method ~= "PUT"
|
||||
and REQUEST.method ~= "PATCH")
|
||||
or (not REQUEST.HAS_RAW_BODY) then
|
||||
return 0
|
||||
end
|
||||
local ctype = HEADER['Content-Type']
|
||||
local clen = HEADER['Content-Length'] or -1
|
||||
if clen then
|
||||
clen = tonumber(clen)
|
||||
end
|
||||
if not ctype or clen == -1 then
|
||||
LOG_ERROR("Invalid content type %s or content length %d", ctype, clen)
|
||||
return 400, "Bad Request, missing content description"
|
||||
end
|
||||
local raw_data, len = std.antd_recv(HTTP_REQUEST.id, clen)
|
||||
if len ~= clen then
|
||||
LOG_ERROR("Unable to read all data: read %d expected %d", len, clen)
|
||||
return 400, "Bad Request, missing content data"
|
||||
end
|
||||
if ctype:find("application/json") then
|
||||
REQUEST.json = bytes.__tostring(raw_data)
|
||||
else
|
||||
REQUEST[ctype] = raw_data
|
||||
end
|
||||
REQUEST.HAS_RAW_BODY = nil
|
||||
return 0
|
||||
end
|
||||
|
||||
-- set compression level
|
||||
local accept_encoding = HEADER["Accept-Encoding"]
|
||||
if accept_encoding then
|
||||
if accept_encoding:find("gzip") then
|
||||
std.antd_set_zlevel(HTTP_REQUEST.id, "gzip")
|
||||
elseif accept_encoding:find("deflate") then
|
||||
std.antd_set_zlevel(HTTP_REQUEST.id, "deflate")
|
||||
end
|
||||
end
|
||||
|
||||
local code, error = decode_request_data()
|
||||
|
||||
if code ~= 0 then
|
||||
LOG_ERROR(error)
|
||||
std.error(code, error)
|
||||
return
|
||||
end
|
||||
|
||||
-- LOG_INFO(JSON.encode(REQUEST))
|
||||
|
||||
-- OOP support
|
||||
--require("OOP")
|
||||
-- load sqlite helper
|
||||
@ -133,17 +242,18 @@ end
|
||||
-- run the file
|
||||
|
||||
|
||||
local m, s, p = has_module(HTTP_REQUEST.request.RESOURCE_PATH)
|
||||
local m, s, p = has_module(HTTP_REQUEST.request.REQUEST_URI)
|
||||
if m then
|
||||
-- run the correct module
|
||||
if s then
|
||||
local r,e = loadscript(p)
|
||||
if r then r() else unknow(e) end
|
||||
else
|
||||
LOG_INFO("RUNNING MODULE %s", p)
|
||||
require(p)
|
||||
end
|
||||
else
|
||||
unknow("Resource not found for request "..HTTP_REQUEST.request.RESOURCE_PATH)
|
||||
unknow("Resource not found for request "..HTTP_REQUEST.request.REQUEST_URI)
|
||||
end
|
||||
|
||||
|
||||
|
@ -1,90 +0,0 @@
|
||||
local pibot = require("pibot")
|
||||
|
||||
local bugbot = {}
|
||||
local cmd = bytes.new(8)
|
||||
--1 IRL R
|
||||
--2 IRR R
|
||||
--3 SNL R
|
||||
--4 SNH R
|
||||
--5 ML RW
|
||||
--6 MR RW
|
||||
--7 MLS RW
|
||||
--8 MRL RW
|
||||
bugbot.init = function()
|
||||
return pibot.init()
|
||||
end
|
||||
|
||||
bugbot.scan = function()
|
||||
local raw = pibot.read(64)
|
||||
if raw then
|
||||
local data = {}
|
||||
data.leftIR = raw[0]
|
||||
data.rightIR = raw[1]
|
||||
data.sonar = raw[2] + bit32.lshift(raw[3], 8)
|
||||
data.motors = {}
|
||||
data.motors.left = {}
|
||||
data.motors.right = {}
|
||||
data.motors.left.status = raw[4]
|
||||
data.motors.left.speed = raw[5]
|
||||
data.motors.right.status = raw[6]
|
||||
data.motors.right.speed = raw[7]
|
||||
return data
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
bugbot.forward = function(sp)
|
||||
cmd[5] = 1 -- fw
|
||||
cmd[6] = sp -- fw
|
||||
cmd[7] = 1
|
||||
cmd[8] = sp
|
||||
pibot.write(cmd)
|
||||
end
|
||||
|
||||
bugbot.action = function(st1,sp1,st2,sp2)
|
||||
|
||||
cmd[5] = st1 -- bw
|
||||
cmd[6] = sp1
|
||||
cmd[7] = st2 -- bw
|
||||
cmd[8] = sp2
|
||||
|
||||
pibot.write(cmd)
|
||||
end
|
||||
|
||||
bugbot.backward = function(sp)
|
||||
cmd[5] = 2 -- bw
|
||||
cmd[6] = sp -- bw
|
||||
cmd[7] = 2
|
||||
cmd[8] = sp
|
||||
pibot.write(cmd)
|
||||
end
|
||||
|
||||
bugbot.stop = function()
|
||||
cmd[5] = 0 -- s
|
||||
cmd[6] = 0 -- s
|
||||
cmd[7] = 0
|
||||
cmd[8] = 0
|
||||
pibot.write(cmd)
|
||||
end
|
||||
|
||||
bugbot.rotateLeft = function(sp)
|
||||
cmd[5] = 2 -- bw
|
||||
cmd[6] = sp -- fw
|
||||
cmd[7] = 1
|
||||
cmd[8] = sp
|
||||
pibot.write(cmd)
|
||||
end
|
||||
|
||||
bugbot.rotateRight = function(sp)
|
||||
cmd[5] = 1 -- fw
|
||||
cmd[6] = sp -- bw
|
||||
cmd[7] = 2
|
||||
cmd[8] = sp
|
||||
pibot.write(cmd)
|
||||
end
|
||||
|
||||
bugbot.release = function()
|
||||
return pibot.release()
|
||||
end
|
||||
return bugbot
|
@ -1,5 +1,5 @@
|
||||
function std.extra_mime(name)
|
||||
local ext = std.ext(name);
|
||||
local ext = std.ext(name)
|
||||
local mpath = __ROOT__.."/".."mimes.json"
|
||||
local xmimes = {}
|
||||
if utils.file_exists(mpath) then
|
||||
@ -15,7 +15,7 @@ function std.extra_mime(name)
|
||||
elseif ext == "cpp" or ext == "hpp" then return "text/cpp",false
|
||||
elseif ext == "md" then return "text/markdown",false
|
||||
elseif ext == "lua" then return "text/lua",false
|
||||
elseif ext == "yaml" then return "application/x-yaml", false
|
||||
elseif ext == "yml" then return "application/x-yaml", false
|
||||
elseif xmimes[ext] then return xmimes[ext].mime, xmimes[ext].binary
|
||||
--elseif ext == "pgm" then return "image/x-portable-graymap", true
|
||||
else
|
||||
@ -60,12 +60,20 @@ function std.sendFile(m)
|
||||
std.header("Content-Transfer-Encoding", "binary")
|
||||
std.header("Cache-Control", "no-cache, no-store")
|
||||
std.header("Connection", "Keep-Alive")
|
||||
std.header("Etag", "a404b-c3f-47c3a14937c80")
|
||||
std.header_flush()
|
||||
std.f(m)
|
||||
else
|
||||
std.status(200)
|
||||
std.header("Content-Type", mime)
|
||||
std.header("Content-Length", len)
|
||||
if HEADER['If-Modified-Since'] and HEADER['If-Modified-Since'] == finfo.ctime then
|
||||
std.status(304)
|
||||
std.header_flush()
|
||||
else
|
||||
std.status(200)
|
||||
std.header("Content-Type", mime)
|
||||
--std.header("Content-Length", len)
|
||||
std.header("Cache-Control", "no-cache")
|
||||
std.header("Last-Modified", finfo.ctime)
|
||||
std.header_flush()
|
||||
std.f(m)
|
||||
end
|
||||
end
|
||||
std.header_flush()
|
||||
std.f(m)
|
||||
end
|
||||
|
23
APIs/std.lua
23
APIs/std.lua
@ -1,12 +1,18 @@
|
||||
std = modules.std()
|
||||
bytes = modules.bytes()
|
||||
array = modules.array()
|
||||
|
||||
modules.sqlite = function()
|
||||
if not sqlite then
|
||||
sqlite = require("sqlitedb")
|
||||
sqlite.getdb = function(s)
|
||||
return sqlite._getdb(__api__.dbpath.."/"..s..".db")
|
||||
sqlite.getdb = function(name)
|
||||
if name:find("%.db$") then
|
||||
return sqlite._getdb(name)
|
||||
elseif name:find("/") then
|
||||
LOG_ERROR("Invalid database name %s", name)
|
||||
return nil
|
||||
else
|
||||
return sqlite._getdb(__api__.dbpath.."/"..name..".db")
|
||||
end
|
||||
end
|
||||
end
|
||||
return sqlite
|
||||
@ -38,14 +44,14 @@ function std.cjson(ck)
|
||||
for k,v in pairs(ck) do
|
||||
std.setCookie(k.."="..v.."; Path=/")
|
||||
end
|
||||
std.header("Content-Type","application/json")
|
||||
std.header("Content-Type","application/json; charset=utf-8")
|
||||
std.header_flush()
|
||||
end
|
||||
function std.chtml(ck)
|
||||
for k,v in pairs(ck) do
|
||||
std.setCookie(k.."="..v.."; Path=/")
|
||||
end
|
||||
std.header("Content-Type","text/html")
|
||||
std.header("Content-Type","text/html; charset=utf-8")
|
||||
std.header_flush()
|
||||
end
|
||||
function std.t(s)
|
||||
@ -62,6 +68,7 @@ function std.b(s)
|
||||
end
|
||||
function std.f(v)
|
||||
std._f(HTTP_REQUEST.id,v)
|
||||
--ulib.send_file(v, HTTP_REQUEST.socket)
|
||||
end
|
||||
|
||||
function std.setCookie(v)
|
||||
@ -83,16 +90,16 @@ end
|
||||
end ]]
|
||||
|
||||
function std.html()
|
||||
std.header("Content-Type","text/html")
|
||||
std.header("Content-Type","text/html; charset=utf-8")
|
||||
std.header_flush()
|
||||
end
|
||||
function std.text()
|
||||
std.header("Content-Type","text/plain")
|
||||
std.header("Content-Type","text/plain; charset=utf-8")
|
||||
std.header_flush()
|
||||
end
|
||||
|
||||
function std.json()
|
||||
std.header("Content-Type","application/json")
|
||||
std.header("Content-Type","application/json; charset=utf-8")
|
||||
std.header_flush()
|
||||
end
|
||||
function std.jpeg()
|
||||
|
@ -49,20 +49,31 @@ function utils.decodeURI(url)
|
||||
end
|
||||
|
||||
function utils.unescape(s)
|
||||
local replacements = {
|
||||
["\\\\"] = "\\" ,
|
||||
['\\"'] = '"' ,
|
||||
["\\n"] = "\n" ,
|
||||
["\\t"] = "\t" ,
|
||||
["\\b"] = "\b" ,
|
||||
["\\f"] = "\f" ,
|
||||
["\\r"] = "\r"
|
||||
}
|
||||
local out = s
|
||||
for k,v in pairs(replacements) do
|
||||
out = out:gsub(k,v)
|
||||
local str = ""
|
||||
local escape = false
|
||||
local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'}
|
||||
for c in s:gmatch"." do
|
||||
if c ~= '\\' then
|
||||
if escape then
|
||||
if esc_map[c] then
|
||||
str = str..esc_map[c]
|
||||
else
|
||||
str = str..c
|
||||
end
|
||||
else
|
||||
str = str..c
|
||||
end
|
||||
escape = false
|
||||
else
|
||||
if escape then
|
||||
str = str..c
|
||||
escape = false
|
||||
else
|
||||
escape = true
|
||||
end
|
||||
end
|
||||
end
|
||||
return out
|
||||
return str
|
||||
end
|
||||
|
||||
function utils.file_exists(name)
|
||||
@ -134,4 +145,17 @@ end
|
||||
|
||||
function firstToUpper(str)
|
||||
return (str:gsub("^%l", string.upper))
|
||||
end
|
||||
|
||||
|
||||
local charset = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
|
||||
|
||||
function utils.generate_salt(length)
|
||||
local ret = {}
|
||||
local r
|
||||
for i = 1, length do
|
||||
r = math.random(1, #charset)
|
||||
table.insert(ret, charset:sub(r, r))
|
||||
end
|
||||
return table.concat(ret)
|
||||
end
|
74
APIs/web.lua
74
APIs/web.lua
@ -1,74 +0,0 @@
|
||||
-- require the utils library to work
|
||||
--require("utils")
|
||||
-- require("std")
|
||||
local wurl = require("wurl")
|
||||
|
||||
local web = {}
|
||||
|
||||
web.understand = function(proto)
|
||||
if proto == "http" or proto == "https" then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
web.get = function(url)
|
||||
local obj = utils.url_parser(url)
|
||||
if web.understand(obj.protocol) then
|
||||
return wurl._get(obj.hostname,obj.port, obj.query)
|
||||
else
|
||||
return nil,"Protocol is unsupported: "..obj.protocol
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
web.post = function(url,data)
|
||||
local obj = utils.url_parser(url)
|
||||
if web.understand(obj.protocol) then
|
||||
if type(data) == "string" then
|
||||
return wurl._post(obj.hostname,
|
||||
obj.port,
|
||||
obj.query,
|
||||
"application/x-www-form-urlencoded",data)
|
||||
else
|
||||
return wurl._post(obj.hostname,
|
||||
obj.port,
|
||||
obj.query,
|
||||
data.contentType,data.value)
|
||||
end
|
||||
else
|
||||
return nil,"Protocol is unsupported: "..obj.protocol
|
||||
end
|
||||
end
|
||||
|
||||
web.download = function(url,to)
|
||||
local obj = utils.url_parser(url)
|
||||
if web.understand(obj.protocol) then
|
||||
local file
|
||||
if std.is_dir(to) then
|
||||
-- need to find file name here
|
||||
local pattern = "^[^%?]*/([%w.]*)%??.*$"
|
||||
local filename = string.gsub(obj.query,pattern,"%1")
|
||||
if filename == "" then filename = "index" end
|
||||
file = to.."/"..filename
|
||||
else
|
||||
file = to
|
||||
end
|
||||
local obj = utils.url_parser(url)
|
||||
return wurl._download(obj.hostname,obj.port,obj.query,file)
|
||||
else
|
||||
return false,"Protocol is unsupported: "..obj.protocol
|
||||
end
|
||||
end
|
||||
|
||||
web.upload = function(url,name,file)
|
||||
local obj = utils.url_parser(url)
|
||||
if web.understand(obj.protocol) then
|
||||
return wurl._upload(obj.hostname,obj.port,obj.query,name,file)
|
||||
else
|
||||
return nil,"Protocol is unsupported: "..obj.protocol
|
||||
end
|
||||
end
|
||||
|
||||
return web
|
107
Jenkinsfile
vendored
Normal file
107
Jenkinsfile
vendored
Normal file
@ -0,0 +1,107 @@
|
||||
def build_plugin()
|
||||
{
|
||||
sh '''
|
||||
set -e
|
||||
cd $WORKSPACE
|
||||
mkdir -p build/$arch/opt/www
|
||||
[ -f Makefile ] && make clean
|
||||
libtoolize
|
||||
aclocal
|
||||
autoconf
|
||||
automake --add-missing
|
||||
search_path=$(realpath antd/build/$arch/usr)
|
||||
CFLAGS="-I$search_path/include" LDFLAGS="-L$search_path/lib" ./configure --prefix=/opt/www
|
||||
CFLAGS="-I$search_path/include" LDFLAGS="-L$search_path/lib" make
|
||||
DESTDIR=$WORKSPACE/build/$arch make install
|
||||
'''
|
||||
}
|
||||
|
||||
pipeline{
|
||||
agent { node{ label'master' }}
|
||||
options {
|
||||
// Limit build history with buildDiscarder option:
|
||||
// daysToKeepStr: history is only kept up to this many days.
|
||||
// numToKeepStr: only this many build logs are kept.
|
||||
// artifactDaysToKeepStr: artifacts are only kept up to this many days.
|
||||
// artifactNumToKeepStr: only this many builds have their artifacts kept.
|
||||
buildDiscarder(logRotator(numToKeepStr: "1"))
|
||||
// Enable timestamps in build log console
|
||||
timestamps()
|
||||
// Maximum time to run the whole pipeline before canceling it
|
||||
timeout(time: 3, unit: 'HOURS')
|
||||
// Use Jenkins ANSI Color Plugin for log console
|
||||
ansiColor('xterm')
|
||||
// Limit build concurrency to 1 per branch
|
||||
disableConcurrentBuilds()
|
||||
}
|
||||
stages
|
||||
{
|
||||
stage('Prepare dependencies')
|
||||
{
|
||||
steps {
|
||||
copyArtifacts(projectName: 'gitea-sync/ant-http/master', target: 'antd');
|
||||
}
|
||||
}
|
||||
stage('Build AMD64') {
|
||||
agent {
|
||||
docker {
|
||||
image 'xsangle/ci-tools:bionic-amd64'
|
||||
// Run the container on the node specified at the
|
||||
// top-level of the Pipeline, in the same workspace,
|
||||
// rather than on a new node entirely:
|
||||
reuseNode true
|
||||
registryUrl 'http://workstation:5000/'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
script{
|
||||
env.arch = "amd64"
|
||||
}
|
||||
build_plugin()
|
||||
}
|
||||
}
|
||||
stage('Build ARM64') {
|
||||
agent {
|
||||
docker {
|
||||
image 'xsangle/ci-tools:bionic-arm64'
|
||||
// Run the container on the node specified at the
|
||||
// top-level of the Pipeline, in the same workspace,
|
||||
// rather than on a new node entirely:
|
||||
reuseNode true
|
||||
registryUrl 'http://workstation:5000/'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
script{
|
||||
env.arch = "arm64"
|
||||
}
|
||||
build_plugin()
|
||||
}
|
||||
}
|
||||
stage('Build ARM') {
|
||||
agent {
|
||||
docker {
|
||||
image 'xsangle/ci-tools:bionic-arm'
|
||||
// Run the container on the node specified at the
|
||||
// top-level of the Pipeline, in the same workspace,
|
||||
// rather than on a new node entirely:
|
||||
reuseNode true
|
||||
registryUrl 'http://workstation:5000/'
|
||||
}
|
||||
}
|
||||
steps {
|
||||
script{
|
||||
env.arch = "arm"
|
||||
}
|
||||
build_plugin()
|
||||
}
|
||||
}
|
||||
stage('Archive') {
|
||||
steps {
|
||||
script {
|
||||
archiveArtifacts artifacts: 'build/', fingerprint: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Xuan Sang LE
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -24,6 +24,6 @@ SUBDIRS = . lib
|
||||
EXTRA_DIST = README.md APIs
|
||||
|
||||
install-data-local:
|
||||
mkdir -p $(prefix)/lib/lua
|
||||
cp -v APIs/* $(prefix)/lib/lua
|
||||
cp -v lib/core/lua-5.3.4/core.so $(prefix)/lib/lua
|
||||
-mkdir -p $(DESTDIR)/$(prefix)/lib/lua
|
||||
-cp -v APIs/* $(DESTDIR)/$(prefix)/lib/lua
|
||||
-cp -v lib/core/lua-5.3.4/core.so $(DESTDIR)/$(prefix)/lib/lua
|
||||
|
@ -128,12 +128,13 @@ AC_CONFIG_FILES([
|
||||
lib/Makefile
|
||||
lib/core/Makefile
|
||||
lib/asl/Makefile
|
||||
lib/md/Makefile
|
||||
])
|
||||
|
||||
if test x"${has_cmake}" == x"yes" ; then
|
||||
AC_CONFIG_FILES([lib/ann/Makefile lib/ann/fann/Makefile])
|
||||
fi
|
||||
#if test x"${has_cmake}" == x"yes" ; then
|
||||
# AC_CONFIG_FILES([lib/ann/Makefile lib/ann/fann/Makefile])
|
||||
#fi
|
||||
|
||||
# AC_SUBST([my_CPPFLAGS]) pass my_CPPFLAGS to the makefile.am
|
||||
# output the script:
|
||||
AC_OUTPUT
|
||||
AC_OUTPUT
|
||||
|
BIN
dist/lua-0.5.2b.tar.gz
vendored
BIN
dist/lua-0.5.2b.tar.gz
vendored
Binary file not shown.
@ -1,18 +0,0 @@
|
||||
{
|
||||
"viz": {
|
||||
"mime": "text/vnd.graphviz",
|
||||
"binary": false
|
||||
},
|
||||
"py": {
|
||||
"mime": "text/x-python",
|
||||
"binary": false
|
||||
},
|
||||
"coffee":{
|
||||
"mime": "text/vnd.coffeescript",
|
||||
"binary": false
|
||||
},
|
||||
"apj": {
|
||||
"mime": "text/antos-project",
|
||||
"binary": false
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
local use_ws = false
|
||||
if REQUEST.query and REQUEST.query.ws == "1" then
|
||||
-- override the global echo command
|
||||
echo = std.ws.swrite
|
||||
use_ws = true
|
||||
else
|
||||
std.json()
|
||||
end
|
||||
local exec_with_user_priv = function(data)
|
||||
local uid = unix.uid(SESSION.iotos_user)
|
||||
if not unix.setgid(uid.gid) or not unix.setuid(uid.id) then
|
||||
echo("Cannot set permission to execute the code")
|
||||
return
|
||||
end
|
||||
local r,e
|
||||
e = "{'error': 'Unknow function'}"
|
||||
if data.code then
|
||||
r,e = load(data.code)
|
||||
if r then
|
||||
local status,result = pcall(r)
|
||||
if(status) then
|
||||
echo(JSON.encode(result))
|
||||
else
|
||||
echo(result)
|
||||
end
|
||||
else
|
||||
echo(e)
|
||||
end
|
||||
elseif data.path then
|
||||
r,e = loadfile(data.path)
|
||||
if r then
|
||||
local status,result = pcall(r, data.parameters)
|
||||
if(status) then
|
||||
echo(JSON.encode(result))
|
||||
else
|
||||
echo(result)
|
||||
end
|
||||
else
|
||||
echo(e)
|
||||
end
|
||||
else
|
||||
echo(e)
|
||||
end
|
||||
end
|
||||
|
||||
if(is_auth()) then
|
||||
local pid = unix.fork()
|
||||
if(pid == -1) then
|
||||
echo("{'error':'Cannot create process'}")
|
||||
elseif pid > 0 then -- parent
|
||||
-- wait for the child exit
|
||||
unix.waitpid(pid)
|
||||
print("Parent exit")
|
||||
else -- child
|
||||
if use_ws then
|
||||
if std.ws.enable() then
|
||||
-- read header
|
||||
local header = std.ws.header()
|
||||
if header then
|
||||
if header.mask == 0 then
|
||||
print("Data is not masked")
|
||||
std.ws.close(1012)
|
||||
elseif header.opcode == std.ws.CLOSE then
|
||||
print("Connection closed")
|
||||
std.ws.close(1000)
|
||||
elseif header.opcode == std.ws.TEXT then
|
||||
-- read the file
|
||||
local data = std.ws.read(header)
|
||||
if data then
|
||||
data = (JSON.decodeString(data))
|
||||
exec_with_user_priv(data)
|
||||
std.ws.close(1011)
|
||||
else
|
||||
echo("Error: Invalid request")
|
||||
std.ws.close(1011)
|
||||
end
|
||||
end
|
||||
else
|
||||
std.ws.close(1011)
|
||||
end
|
||||
else
|
||||
print("Web socket is not available.")
|
||||
end
|
||||
else
|
||||
if REQUEST.query.json then
|
||||
data = JSON.decodeString(REQUEST.query.json)
|
||||
std.json()
|
||||
exec_with_user_priv(data)
|
||||
else
|
||||
fail("Unkown request")
|
||||
end
|
||||
end
|
||||
print("Child exit")
|
||||
end
|
||||
else
|
||||
echo('{"error":"User unauthorized. Please login"}')
|
||||
end
|
@ -1,29 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
if(rq ~= nil and rq.table ~= nil) then
|
||||
local model = require("db.model").get(SESSION.iotos_user, rq.table, nil)
|
||||
local ret
|
||||
if model == nil then
|
||||
fail("Cannot get table metadata:"..rq.table)
|
||||
else
|
||||
if(rq.id == nil ) then
|
||||
if(rq.cond) then
|
||||
ret = model:delete(rq.cond)
|
||||
model:close()
|
||||
else
|
||||
model:close()
|
||||
return fail("Unknow element to delete")
|
||||
end
|
||||
else
|
||||
ret = model:deleteByID(rq.id)
|
||||
model:close()
|
||||
end
|
||||
if ret then
|
||||
result(ret)
|
||||
else
|
||||
fail("Querry error or database is locked")
|
||||
end
|
||||
end
|
||||
else
|
||||
fail("Unknown database request")
|
||||
end
|
@ -1,19 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
if(rq ~= nil and rq.table ~= nil) then
|
||||
local model = require("db.model").get(SESSION.iotos_user, rq.table, nil)
|
||||
local ret
|
||||
if model == nil then
|
||||
fail("Cannot get table metadata:"..rq.table)
|
||||
else
|
||||
if(rq.id == nil ) then
|
||||
ret = model:getAll()
|
||||
else
|
||||
ret = model:get(rq.id)
|
||||
end
|
||||
model:close()
|
||||
result(ret)
|
||||
end
|
||||
else
|
||||
fail("Unknown database request")
|
||||
end
|
@ -1,20 +0,0 @@
|
||||
local model = {}
|
||||
|
||||
model.get = function(name, tbl, data)
|
||||
local db = DBModel:new{db = name, name=tbl}
|
||||
db:open()
|
||||
if db:available() then return db end
|
||||
if data == nil then return nil end
|
||||
local meta = {}
|
||||
--print(JSON.encode(data))
|
||||
for k,v in pairs(data) do
|
||||
if type(v) == "number" then
|
||||
meta[k] = "NUMERIC"
|
||||
else
|
||||
meta[k] = "TEXT"
|
||||
end
|
||||
end
|
||||
db:createTable(meta)
|
||||
return db
|
||||
end
|
||||
return model
|
@ -1,24 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
if(rq ~= nil and rq.table ~= nil) then
|
||||
local model = require("db.model").get(SESSION.iotos_user,rq.table, rq.data)
|
||||
local ret
|
||||
if model == nil then
|
||||
fail("Cannot get table metadata:"..rq.table)
|
||||
else
|
||||
if(rq.data.id ~= nil ) then
|
||||
rq.data.id = tonumber(rq.data.id)
|
||||
ret = model:update(rq.data)
|
||||
else
|
||||
ret = model:insert(rq.data)
|
||||
end
|
||||
model:close()
|
||||
if ret == true then
|
||||
result(ret)
|
||||
else
|
||||
fail("Cannot modify/update table "..rq.table)
|
||||
end
|
||||
end
|
||||
else
|
||||
fail("Unknown database request")
|
||||
end
|
@ -1,20 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
if(rq ~= nil and rq.table ~= nil) then
|
||||
local model = require("db.model").get(SESSION.iotos_user,rq.table, nil)
|
||||
local ret
|
||||
if model == nil then
|
||||
fail("Cannot get table metadata:"..rq.table)
|
||||
else
|
||||
if(rq.cond == nil ) then
|
||||
model:close()
|
||||
return fail("Unknow condition")
|
||||
else
|
||||
ret = model:find(rq.cond)
|
||||
end
|
||||
model:close()
|
||||
result(ret)
|
||||
end
|
||||
else
|
||||
fail("Unknown database request")
|
||||
end
|
@ -1,15 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
|
||||
local vfs = require("fs.vfs")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
|
||||
if rq ~= nil then
|
||||
local r,e = vfs.delete(rq.path)
|
||||
if r then
|
||||
result(r)
|
||||
else
|
||||
fail(e)
|
||||
end
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
@ -1,10 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
|
||||
local vfs = require("fs.vfs")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
|
||||
if rq ~= nil then
|
||||
result(vfs.exists(rq.path))
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
@ -1,8 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local vfspath = (JSON.decodeString(REQUEST.query.json)).path
|
||||
local r,m = require("fs.vfs").fileinfo(vfspath)
|
||||
if r then
|
||||
result(m)
|
||||
else
|
||||
fail(m)
|
||||
end
|
@ -1,6 +0,0 @@
|
||||
|
||||
local conf = {
|
||||
home="/Users/%s/tmp/",
|
||||
shared="/Users/%s/tmp/Public/"
|
||||
}
|
||||
return conf
|
@ -1,14 +0,0 @@
|
||||
local handler
|
||||
|
||||
handler = function(str)
|
||||
local func = str:match("^%a+/")
|
||||
if func == "get/" then
|
||||
require("fs.get")(str:gsub(func,""))
|
||||
elseif func == "shared/" then
|
||||
require("fs.shared").get(str:gsub(func,""))
|
||||
else
|
||||
fail("Action is not supported: "..func)
|
||||
end
|
||||
end
|
||||
|
||||
return handler
|
@ -1,40 +0,0 @@
|
||||
local get
|
||||
get = function(uri)
|
||||
vfsfile = utils.decodeURI(uri)
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local r,m = require("fs.vfs").checkperm(vfsfile,'read')
|
||||
if r then
|
||||
local mime = std.mimeOf(m)
|
||||
if mime == "audio/mpeg" then
|
||||
local finfo = unix.file_stat(m)
|
||||
local len = tostring(math.floor(finfo.size))
|
||||
local len1 = tostring(math.floor(finfo.size-1))
|
||||
std.status(200, "OK")
|
||||
std.custom_header("Pragma","public")
|
||||
std.custom_header("Expires","0")
|
||||
std.custom_header("Content-Type",mime)
|
||||
std.custom_header("Content-Length",len)
|
||||
std.custom_header("Content-Disposition","inline; filename="..std.basename(m))
|
||||
std.custom_header("Content-Range:","bytes 0-"..len1.."/"..len)
|
||||
std.custom_header("Accept-Ranges","bytes")
|
||||
std.custom_header("X-Pad", "avoid browser bug")
|
||||
std.custom_header("Content-Transfer-Encoding", "binary")
|
||||
std.custom_header("Cache-Control","no-cache, no-store")
|
||||
std.custom_header("Connection", "Keep-Alive")
|
||||
std.custom_header("Etag","a404b-c3f-47c3a14937c80")
|
||||
std.header_flush()
|
||||
else
|
||||
std.header(mime)
|
||||
end
|
||||
|
||||
if std.is_bin(m) then
|
||||
std.fb(m)
|
||||
else
|
||||
std.f(m)
|
||||
end
|
||||
else
|
||||
fail(m)
|
||||
end
|
||||
end
|
||||
|
||||
return get;
|
@ -1,11 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
|
||||
if rq ~= nil then
|
||||
local r,m = require("fs.vfs").mkdir(rq.path)
|
||||
if r then result(r) else fail(m) end
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
||||
|
@ -1,13 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
|
||||
if rq ~= nil then
|
||||
local r,m = require("fs.vfs").move(rq.src,rq.dest)
|
||||
if r then result(r) else fail(m) end
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
||||
|
||||
|
||||
|
@ -1,36 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
|
||||
if rq ~= nil then
|
||||
local p = nil
|
||||
if rq.publish then
|
||||
p = require("fs.vfs").ospath(rq.path)
|
||||
else
|
||||
p = require("fs.shared").ospath(rq.path)
|
||||
end
|
||||
local user = SESSION.iotos_user
|
||||
local uid = unix.uid(user)
|
||||
local st = unix.file_stat(p)
|
||||
if uid.id ~= st.uid then die("Only the owner can share or unshare this file") end
|
||||
local entry = { sid = std.sha1(p), user = SESSION.iotos_user, path = p, uid = uid.id }
|
||||
local db = require("db.model").get("sysdb", "shared", entry)
|
||||
if db == nil then die("Cannot get system database") end
|
||||
local cond = nil
|
||||
if rq.publish then
|
||||
cond = { exp = { ["="] = { path = p } } }
|
||||
local data = db:find(cond)
|
||||
if data == nil or data[0] == nil then
|
||||
-- insert entry
|
||||
db:insert(entry)
|
||||
end
|
||||
else
|
||||
cond = { ["="] = { sid = rq.path } }
|
||||
db:delete(cond)
|
||||
end
|
||||
db:close()
|
||||
result(entry.sid)
|
||||
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
@ -1,10 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local vfspath = (JSON.decodeString(REQUEST.query.json)).path
|
||||
local r = require("fs.vfs").readDir(vfspath)
|
||||
if r == nil then
|
||||
fail("Resource not found")
|
||||
else
|
||||
--print(JSON.encode(readDir(ospath, vfspath)))
|
||||
result(r)
|
||||
end
|
||||
|
@ -1,52 +0,0 @@
|
||||
local shared = {}
|
||||
shared.get = function(sharedid)
|
||||
if sharedid == "all" then
|
||||
-- get all shared files
|
||||
local db = require("db.model").get("sysdb", "shared", nil)
|
||||
if db == nil then die("Cannot get shared database") end
|
||||
local data = db:getAll()
|
||||
if data == nil then die("No file found") end
|
||||
local i = 1
|
||||
local ret = {}
|
||||
for k,v in pairs(data) do
|
||||
if(unix.exists(v.path)) then
|
||||
local r = unix.file_stat(v.path)
|
||||
if(r.error == nil) then
|
||||
r.path = "shared://"..v.sid
|
||||
r.filename = std.basename(v.path)
|
||||
if r.mime == "application/octet-stream" then
|
||||
r.mime = std.extra_mime(r.filename)
|
||||
end
|
||||
ret[i] = r
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
local cond = { ["="] = { sid = v.sid } }
|
||||
db:delete(cond)
|
||||
end
|
||||
end
|
||||
db:close()
|
||||
--std.json()
|
||||
result(ret)
|
||||
else
|
||||
|
||||
local p = shared.ospath(sharedid)
|
||||
std.header(std.mimeOf(p))
|
||||
if std.is_bin(p) then
|
||||
std.fb(p)
|
||||
else
|
||||
std.f(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
shared.ospath = function(sharedid)
|
||||
local db = require("db.model").get("sysdb", "shared", nil)
|
||||
if db == nil then die("Cannot get shared database") end
|
||||
local cond = { exp = { ["="] = { sid = sharedid } } }
|
||||
local data = db:find(cond)
|
||||
db:close()
|
||||
if data == nil or data[1] == nil then die("Cannot get shared file with: "..sharedid) end
|
||||
return data[1].path
|
||||
end
|
||||
return shared;
|
@ -1,8 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local vfs = require("fs.vfs")
|
||||
if REQUEST.query then
|
||||
local r,m = require("fs.vfs").upload(REQUEST.query.path)
|
||||
if r then result(r) else fail(m) end
|
||||
else
|
||||
fail("Query not found")
|
||||
end
|
@ -1,203 +0,0 @@
|
||||
local vfs = {}
|
||||
|
||||
vfs.ospath = function(path)
|
||||
local user = SESSION.iotos_user
|
||||
local conf = require("fs.fsconf")
|
||||
local prefix = string.match(path, "%a+://")
|
||||
if(prefix ~= nil) then
|
||||
local suffix = string.gsub(path,prefix,"")
|
||||
if prefix == "home://" then
|
||||
return string.format(conf.home,user)..'/'..suffix
|
||||
elseif prefix == "desktop://" then
|
||||
return string.format(conf.home,user).."/.desktop/"..suffix
|
||||
elseif prefix == "shared://" then
|
||||
return require("fs.shared").ospath(std.trim(suffix,"/"))
|
||||
elseif prefix == "os://" then
|
||||
return OSROOT.."/"..suffix
|
||||
else
|
||||
return nil
|
||||
end
|
||||
else
|
||||
return nil;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
vfs.delete = function(path)
|
||||
local r,m = vfs.checkperm(path,"write")
|
||||
if r then
|
||||
if unix.delete(m) then
|
||||
-- change permission
|
||||
return true,nil
|
||||
else
|
||||
return false,"Cant not delete the file"
|
||||
end
|
||||
else
|
||||
return r,m
|
||||
end
|
||||
end
|
||||
|
||||
vfs.exists = function(path)
|
||||
local osfile = vfs.ospath(path)
|
||||
return unix.exists(osfile)
|
||||
end
|
||||
|
||||
vfs.fileinfo = function(vfspath)
|
||||
local ospath = vfs.ospath(vfspath)
|
||||
if ospath then
|
||||
if(unix.exists(ospath) == false) then return false,"File not found" end
|
||||
local r = unix.file_stat(ospath)
|
||||
if(r.error ~= nil) then return false,r.error end
|
||||
r.path = vfspath
|
||||
r.name = std.basename(vfspath)
|
||||
if r.mime == "application/octet-stream" then
|
||||
r.mime = std.extra_mime(r.name)
|
||||
end
|
||||
return true,r
|
||||
else
|
||||
return false,"Resource not found"
|
||||
end
|
||||
end
|
||||
|
||||
vfs.mkdir = function(path)
|
||||
local file = std.basename(path)
|
||||
local folder = string.gsub(path, utils.escape_pattern(file),"")
|
||||
local r,m = vfs.checkperm(folder,"write")
|
||||
|
||||
if r then
|
||||
local osfile = m.."/"..file
|
||||
local uid = unix.uid(SESSION.iotos_user)
|
||||
unix.mkdir(osfile)
|
||||
-- change permission
|
||||
unix.chown(osfile, uid.id, uid.gid)
|
||||
return true,nil
|
||||
else
|
||||
return r,m
|
||||
end
|
||||
end
|
||||
|
||||
vfs.move = function(src,dest)
|
||||
local file = std.basename(dest)
|
||||
local folder = string.gsub(dest, utils.escape_pattern(file),"")
|
||||
|
||||
local sp,sm = vfs.checkperm(src,"write")
|
||||
if sp then
|
||||
local dp,dm = vfs.checkperm(folder,"write")
|
||||
if dp then
|
||||
unix.move(sm,dm.."/"..file)
|
||||
-- change permission
|
||||
return true,nil
|
||||
else
|
||||
return dp,dm
|
||||
end
|
||||
else
|
||||
return sp,sm
|
||||
end
|
||||
end
|
||||
|
||||
vfs.write = function(path,data)
|
||||
local file = std.basename(path)
|
||||
local folder = string.gsub(path, utils.escape_pattern(file),"")
|
||||
|
||||
local r,m = vfs.checkperm(folder,"write")
|
||||
if r then
|
||||
local osfile = m.."/"..file
|
||||
local uid = unix.uid(SESSION.iotos_user)
|
||||
--
|
||||
if data ~= "" then
|
||||
local header = string.match(data, "^data%:%w+%/%w+;base64,")
|
||||
if header ~= nil then
|
||||
local b64data = string.gsub(data, header,"")
|
||||
local barr = std.b64decode(b64data)
|
||||
if std.isBinary(osfile) then
|
||||
bytes.write(barr,osfile)
|
||||
else
|
||||
local f = io.open(osfile, "w")
|
||||
f:write(bytes.__tostring(barr))
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
else
|
||||
bytes.write(bytes.new(0),osfile)
|
||||
end
|
||||
--f:close()
|
||||
-- change permission
|
||||
unix.chown(osfile, uid.id, uid.gid)
|
||||
return true,nil
|
||||
else
|
||||
return r,m
|
||||
end
|
||||
end
|
||||
|
||||
vfs.upload = function(path)
|
||||
local r,m = vfs.checkperm(path,"write")
|
||||
if(r) then
|
||||
local uid = unix.uid(SESSION.iotos_user)
|
||||
local file = m.."/"..REQUEST.query["upload.file"]
|
||||
unix.move(REQUEST.query["upload.tmp"], file)
|
||||
unix.chown(file, uid.id, uid.gid)
|
||||
return true, nil
|
||||
else
|
||||
return r,m
|
||||
end
|
||||
end
|
||||
|
||||
vfs.checkperm = function(path, right)
|
||||
local osfile = vfs.ospath(path)
|
||||
local perm = vfs.perm(osfile)
|
||||
print(osfile)
|
||||
-- check if user own the file
|
||||
if perm ~= nil then
|
||||
if perm[right] == true then
|
||||
print("Permission granted")
|
||||
return true,osfile
|
||||
else
|
||||
print("Permission denie")
|
||||
return false,"You dont have "..right.." permission on this file"
|
||||
end
|
||||
else
|
||||
return false,"User is unrecognized"
|
||||
end
|
||||
end
|
||||
|
||||
vfs.perm = function(file)
|
||||
local user = SESSION.iotos_user
|
||||
local uid = unix.uid(user)
|
||||
local st = unix.file_stat(file)
|
||||
-- check if user own the file
|
||||
if uid ~= nil and st ~= nil and st.perm ~= nil then
|
||||
--print(JSON.encode({uid, st}))
|
||||
if(uid.id == st.uid) then -- the user owned the file
|
||||
print("file belong to user")
|
||||
return st.perm.owner
|
||||
elseif uid.groups and uid.groups[st.gid] then
|
||||
print("User belong to this group")
|
||||
return st.perm.group
|
||||
else
|
||||
print("User belong to other")
|
||||
return st.perm.other
|
||||
end
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
vfs.readDir = function(vfspath)
|
||||
if(string.sub(vfspath,-1) == "/") then
|
||||
prefix = string.sub(vfspath,1,-2)
|
||||
else
|
||||
prefix = vfspath
|
||||
end
|
||||
local ospath = vfs.ospath(vfspath,SESSION.iotos_user)
|
||||
local r = unix.read_dir(ospath, prefix)
|
||||
if(r.error ~= nil) then return nil end
|
||||
-- add extra mime type
|
||||
for k,v in pairs(r) do
|
||||
if v.mime == "application/octet-stream" then
|
||||
v.mime = std.extra_mime(v.filename)
|
||||
end
|
||||
end
|
||||
return r
|
||||
end
|
||||
|
||||
return vfs
|
@ -1,13 +0,0 @@
|
||||
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
|
||||
if rq ~= nil then
|
||||
local r,m = require("fs.vfs").write(rq.path, rq.data)
|
||||
sqlite.dbclose()
|
||||
if r then result(r) else fail(m) end
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
result({r = "Welcome to antOS" })
|
@ -1,10 +0,0 @@
|
||||
local handle = function(p)
|
||||
local hstr = p:match("^%a+/")
|
||||
if hstr == "fs/" then
|
||||
--print("require module")
|
||||
require("fs.fsh")(p:gsub(hstr,"",1))
|
||||
else
|
||||
fail("Resource not found for request "..p)
|
||||
end
|
||||
end
|
||||
return handle
|
@ -1,24 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local rq = nil
|
||||
if REQUEST.query.json ~= nil then
|
||||
rq = (JSON.decodeString(REQUEST.query.json))
|
||||
else
|
||||
rq = REQUEST.query
|
||||
end
|
||||
|
||||
if rq.path ~= nil then
|
||||
local pkg = require("fs.vfs").ospath(rq.path)
|
||||
if pkg == nil then
|
||||
pkg = OSROOT..'/packages/'..rq.path
|
||||
--die("unkown request path:"..rq.path)
|
||||
end
|
||||
pkg = pkg.."/api.lua"
|
||||
if unix.exists(pkg) then
|
||||
dofile(pkg).exec(rq.method,rq.arguments)
|
||||
else
|
||||
fail("Uknown application handler: "..pkg)
|
||||
end
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
||||
|
@ -1,3 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local user = require("system.uman").userinfo(SESSION.iotos_user)
|
||||
result(user)
|
@ -1,17 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
|
||||
if rq ~= nil then
|
||||
local r,m = require("web").get(rq.url)
|
||||
if r then
|
||||
if r.binary then
|
||||
result({body="data:"..r.contentType..";base64,"..r.data})
|
||||
else
|
||||
result({body=r.data})
|
||||
end
|
||||
else
|
||||
fail(m)
|
||||
end
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
@ -1,39 +0,0 @@
|
||||
if REQUEST.query.json ~= nil then
|
||||
local request = JSON.decodeString(REQUEST.query.json)
|
||||
local r = unix.auth(request.username,request.password)
|
||||
if r == true then
|
||||
local cookie = {sessionid=std.sha1(request.username..request.password)} -- iotos_user = request.username
|
||||
local db = sysdb();
|
||||
if db == nil then return fail("Cannot setup session") end
|
||||
local cond = {exp= {["="] = { sessionid = cookie.sessionid }}}
|
||||
local data = db:find(cond)
|
||||
--print(data)
|
||||
if data == nil or data[1] == nil then
|
||||
--print("insert new data")
|
||||
data = {sessionid = cookie.sessionid, username=request.username, stamp=os.time(os.date("!*t"))}
|
||||
else
|
||||
data = data[1]
|
||||
--print("Update old data")
|
||||
data.stamp = os.time(os.date("!*t"))
|
||||
end
|
||||
if data.id == nil then
|
||||
db:insert(data)
|
||||
else
|
||||
db:update(data)
|
||||
end
|
||||
db:close()
|
||||
std.cjson(cookie)
|
||||
SESSION.iotos_user = request.username
|
||||
local user = {
|
||||
result = require("system.uman").userinfo(request.username),
|
||||
error = false
|
||||
}
|
||||
std.t(JSON.encode(user))
|
||||
else
|
||||
fail("Invalid login")
|
||||
end
|
||||
else
|
||||
fail("Invalid request")
|
||||
end
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
if SESSION.sessionid ~= nil and SESSION.sessionid ~= '0' then
|
||||
local cookie = {sessionid='0'}
|
||||
local db = sysdb()
|
||||
if db ~= nil then
|
||||
--local data = db:find("sessionid ='"..SESSION.sessionid.."'")
|
||||
--if data and data[0] ~= nil then
|
||||
-- db:delete(data[0].id)
|
||||
--end
|
||||
local cond = {["="] = { sessionid = SESSION.sessionid }}
|
||||
db:delete(cond)
|
||||
db:close()
|
||||
end
|
||||
std.cjson(cookie)
|
||||
else
|
||||
std.json()
|
||||
end
|
||||
std.t(JSON.encode({error=false,result=true}))
|
@ -1,21 +0,0 @@
|
||||
[
|
||||
{
|
||||
"className": "NotePad",
|
||||
"name": "Source editor",
|
||||
"description": "Advance text editor",
|
||||
"category": "development",
|
||||
"author": "xsang.le@gmail.com",
|
||||
"version": "0.1",
|
||||
"download": "http://192.168.1.49:9191/repo/AceEditor.zip"
|
||||
},
|
||||
{
|
||||
"className": "DummyApp",
|
||||
"name": "Antos features",
|
||||
"description": "Antos features show case",
|
||||
"category": "utilities",
|
||||
"author": "xsang.le@gmail.com",
|
||||
"version": "1.0",
|
||||
"download": "https://os.localhost:9195/repo/DummyApp.zip"
|
||||
}
|
||||
]
|
||||
|
@ -1,588 +0,0 @@
|
||||
"default/About": {
|
||||
"className": "ApplicationAbout",
|
||||
"name": "About OS.js",
|
||||
"description": "About OS.js",
|
||||
"names": {
|
||||
"bg_BG": " За OS.js",
|
||||
"de_DE": "Über OS.js",
|
||||
"fr_FR": "À propos d'OS.js",
|
||||
"it_IT": "Informazioni su OS.js",
|
||||
"ko_KR": "OS.js에 대하여",
|
||||
"nl_NL": "Over OS.js",
|
||||
"no_NO": "Om OS.js",
|
||||
"pl_PL": "o OS.js",
|
||||
"ru_RU": "Об OS.js",
|
||||
"sk_SK": "o OS.js",
|
||||
"tr_TR": "hakkında OS.js",
|
||||
"vi_VN": "Thông tin về OS.js"
|
||||
},
|
||||
"descriptions": {
|
||||
"bg_BG": "За OS.js",
|
||||
"de_DE": "Über OS.js",
|
||||
"fr_FR": "À propos d'OS.js",
|
||||
"it_IT": "Informazioni su OS.js",
|
||||
"ko_KR": "OS.js에 대하여",
|
||||
"nl_NL": "Over OS.js",
|
||||
"no_NO": "Om OS.js",
|
||||
"pl_PL": "o OS.js",
|
||||
"ru_RU": "Об OS.js",
|
||||
"sk_SK": "o OS.js",
|
||||
"tr_TR": "hakkında OS.js",
|
||||
"vi_VN": "Thông tin về OS.js"
|
||||
},
|
||||
"singular": true,
|
||||
"category": "system",
|
||||
"icon": "apps/help-browser.png",
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/About",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/AceEditor": {
|
||||
"className": "ApplicationAceEditor",
|
||||
"name": "Source Editor",
|
||||
"icon": "apps/accessories-text-editor.png",
|
||||
"category": "development",
|
||||
"mime": [
|
||||
"^text",
|
||||
"inode\\/x\\-empty",
|
||||
"application\\/x\\-empty",
|
||||
"application\\/x\\-python",
|
||||
"application\\/x\\-php",
|
||||
"application\\/javascript"
|
||||
],
|
||||
"build": {
|
||||
"copy": [
|
||||
"metadata.json",
|
||||
"scheme.html",
|
||||
"main.css",
|
||||
"main.js",
|
||||
"vendor/ace"
|
||||
]
|
||||
},
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/AceEditor",
|
||||
"repo": "default"
|
||||
},
|
||||
"default/Archiver": {
|
||||
"className": "ApplicationArchiver",
|
||||
"name": "Archiver",
|
||||
"mime": [
|
||||
"application/zip"
|
||||
],
|
||||
"icon": "apps/system-software-install.png",
|
||||
"category": "utilities",
|
||||
"compability": [
|
||||
"file",
|
||||
"blob"
|
||||
],
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/Archiver",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/Calculator": {
|
||||
"className": "ApplicationCalculator",
|
||||
"name": "Calculator",
|
||||
"names": {
|
||||
"bg_Bg": "Клакулатор",
|
||||
"fr_FR": "Calculatrice",
|
||||
"it_IT": "Calcolatrice",
|
||||
"ko_KR": "계산기",
|
||||
"nl_NL": "Rekenmachine",
|
||||
"no_NO": "Kalkulator",
|
||||
"pl_PL": "Kalkulator",
|
||||
"ru_RU": "Калькулятор",
|
||||
"sk_SK": "Kalkulačka",
|
||||
"tr_TR": "Hesap Makinesi",
|
||||
"vi_VN": "Máy tính"
|
||||
},
|
||||
"icon": "apps/calc.png",
|
||||
"category": "office",
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/Calculator",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/CoreWM": {
|
||||
"className": "CoreWM",
|
||||
"name": "OS.js Window Manager",
|
||||
"names": {
|
||||
"bg_BG": "Мениджър на прозорци на OS.js",
|
||||
"de_DE": "OS.js Fenster-Manager",
|
||||
"es_ES": "OS.js Window Manager",
|
||||
"fr_FR": "Gestionnaire de fenêtre OS.js",
|
||||
"it_IT": "OS.js Gestore Finestre",
|
||||
"ko_KR": "OS.js 윈도우 관리자",
|
||||
"nl_NL": "OS.js venster beheer",
|
||||
"no_NO": "OS.js Vinduhåndterer",
|
||||
"pl_PL": "Menedżer Okien OS.js",
|
||||
"ru_RU": "OS.js Оконный менеджер",
|
||||
"sk_SK": "Správca Okien OS.js",
|
||||
"tr_TR": "OS.js Pencere Yöneticisi",
|
||||
"vi_VN": "Quản lí cửa sổ OS.js"
|
||||
},
|
||||
"singular": true,
|
||||
"type": "windowmanager",
|
||||
"icon": "apps/gnome-window-manager.png",
|
||||
"splash": false,
|
||||
"preload": [{
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}, {
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}],
|
||||
"panelItems": {
|
||||
"AppMenu": {
|
||||
"Name": "AppMenu",
|
||||
"Description": "Application Menu",
|
||||
"Icon": "actions/stock_about.png",
|
||||
"HasOptions": false
|
||||
},
|
||||
"Buttons": {
|
||||
"Name": "Buttons",
|
||||
"Description": "Button Bar",
|
||||
"Icon": "actions/stock_about.png"
|
||||
},
|
||||
"Clock": {
|
||||
"Name": "Clock",
|
||||
"Description": "View the time",
|
||||
"Icon": "status/appointment-soon.png",
|
||||
"HasOptions": true
|
||||
},
|
||||
"NotificationArea": {
|
||||
"Name": "NotificationArea",
|
||||
"Description": "View notifications",
|
||||
"Icon": "apps/gnome-panel-notification-area.png"
|
||||
},
|
||||
"Search": {
|
||||
"Name": "Search",
|
||||
"Description": "Perform searches",
|
||||
"Icon": "actions/find.png",
|
||||
"HasOptions": true
|
||||
},
|
||||
"Weather": {
|
||||
"Name": "Weather",
|
||||
"Description": "Weather notification",
|
||||
"Icon": "status/weather-few-clouds.png"
|
||||
},
|
||||
"WindowList": {
|
||||
"Name": "Window List",
|
||||
"Description": "Toggle between open windows",
|
||||
"Icon": "apps/xfwm4.png"
|
||||
}
|
||||
},
|
||||
"path": "default/CoreWM",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/FileManager": {
|
||||
"className": "ApplicationFileManager",
|
||||
"name": "File Manager",
|
||||
"description": "The default file manager",
|
||||
"names": {
|
||||
"bg_BG": "Файлов мениджър",
|
||||
"de_DE": "Dateimanager",
|
||||
"fr_FR": "Explorateur de fichier",
|
||||
"it_IT": "Gestore File",
|
||||
"nl_NL": "bestands beheer",
|
||||
"no_NO": "Fil-håndtering",
|
||||
"pl_PL": "Menedżer Plików",
|
||||
"ko_KR": "파일 탐색기",
|
||||
"sk_SK": "Správca súborov",
|
||||
"ru_RU": "Файловый менеджер",
|
||||
"tr_TR": "Dosya Yöneticisi",
|
||||
"vi_VN": "Quản lí file"
|
||||
},
|
||||
"descriptions": {
|
||||
"bg_BG": "Стандартния файлов мениджър",
|
||||
"de_DE": "Standardmäßiger Dateimanager",
|
||||
"fr_FR": "Gestionnaire de fichier par défaut",
|
||||
"it_IT": "Il gestore file predefinito",
|
||||
"nl_NL": "Standaard bestands beheerder",
|
||||
"no_NO": "Standard Fil-håndtering program",
|
||||
"pl_PL": "Domyślny Menedżer Plików",
|
||||
"ko_KR": "기본 파일 관리자",
|
||||
"sk_SK": "Štandardný správca súborov",
|
||||
"ru_RU": "Стандартный файловый менеджер",
|
||||
"tr_TR": "Varsayılan dosya yöneticisi",
|
||||
"vi_VN": "Trình quản lí file mặc định"
|
||||
},
|
||||
"category": "utilities",
|
||||
"icon": "apps/file-manager.png",
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/FileManager",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/MarkOn": {
|
||||
"className": "ApplicationMarkOn",
|
||||
"name": "MarkOn",
|
||||
"mime": [
|
||||
"^text",
|
||||
"inode\\/x\\-empty",
|
||||
"application\\/x\\-empty"
|
||||
],
|
||||
"category": "office",
|
||||
"icon": "apps/libreoffice34-writer.png",
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/MarkOn",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/PDFjs": {
|
||||
"className": "ApplicationPDFjs",
|
||||
"name": "PDF Viewer",
|
||||
"description": "PDF Viewer",
|
||||
"mime": [
|
||||
"application/pdf"
|
||||
],
|
||||
"category": "office",
|
||||
"icon": "mimetypes/gnome-mime-application-pdf.png",
|
||||
"build": {
|
||||
"copy": [
|
||||
"metadata.json",
|
||||
"scheme.html",
|
||||
"main.css",
|
||||
"main.js",
|
||||
"vendor/pdf.js"
|
||||
]
|
||||
},
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/PDFjs",
|
||||
"repo": "default"
|
||||
},
|
||||
"default/Preview": {
|
||||
"className": "ApplicationPreview",
|
||||
"name": "Preview",
|
||||
"description": "Preview image files",
|
||||
"names": {
|
||||
"bg_BG": "Преглед на изображения",
|
||||
"de_DE": "Vorschau",
|
||||
"fr_FR": "Visionneuse",
|
||||
"it_IT": "Anteprima Immagini",
|
||||
"ko_KR": "미리보기",
|
||||
"nl_NL": "Foto viewer",
|
||||
"no_NO": "Forhåndsviser",
|
||||
"pl_PL": "Podgląd",
|
||||
"ru_RU": "Просмотрщик",
|
||||
"sk_SK": "Prehliadač obrázkov",
|
||||
"tr_TR": "Önizle",
|
||||
"vi_VN": "Trình xem ảnh"
|
||||
},
|
||||
"descriptions": {
|
||||
"bg_BG": "Преглед на изображения",
|
||||
"de_DE": "Bildervorschau",
|
||||
"fr_FR": "Visionneuse de photos",
|
||||
"it_IT": "Anteprima Immagini",
|
||||
"ko_KR": "이미지 파일을 미리 봅니다",
|
||||
"nl_NL": "Foto viewer",
|
||||
"no_NO": "Forhåndsvisning av bilde-filer",
|
||||
"pl_PL": "Podgląd zdjęć",
|
||||
"ru_RU": "Просмотрщик изображений",
|
||||
"sk_SK": "Prehliadač obrázkov",
|
||||
"tr_TR": "resim dosyalarını önizle",
|
||||
"vi_VN": "Trình xem ảnh"
|
||||
},
|
||||
"mime": [
|
||||
"^image",
|
||||
"^video"
|
||||
],
|
||||
"category": "multimedia",
|
||||
"icon": "mimetypes/image.png",
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/Preview",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/ProcessViewer": {
|
||||
"className": "ApplicationProcessViewer",
|
||||
"name": "Process Viewer",
|
||||
"description": "View running processes",
|
||||
"names": {
|
||||
"bg_BG": "Процеси",
|
||||
"de_DE": "Prozess-Manager",
|
||||
"fr_FR": "Gestionnaire de processus",
|
||||
"it_IT": "Gestore Attività",
|
||||
"ko_KR": "프로세스 관리자",
|
||||
"nl_NL": "Proces manager",
|
||||
"no_NO": "Prosess oversikt",
|
||||
"pl_PL": "Procesy",
|
||||
"ru_RU": "Менеджер процессов",
|
||||
"sk_SK": "Správca procesov",
|
||||
"tr_TR": "İşlemleri Görüntüle",
|
||||
"vi_VN": "Xem tiến trình"
|
||||
},
|
||||
"descriptions": {
|
||||
"bg_BG": "Преглед на процеси",
|
||||
"de_DE": "Laufende Prozesse verwalten",
|
||||
"fr_FR": "Visualiser les processus en cours",
|
||||
"it_IT": "Mostri processi attivi",
|
||||
"ko_KR": "실행 중인 프로세스를 관리합니다",
|
||||
"nl_NL": "Bekijk de lopende processen",
|
||||
"no_NO": "Se oversikt over kjørende prosesser",
|
||||
"pl_PL": "Zobacz działające procesy",
|
||||
"ru_RU": "Менеджер запущенных процессов",
|
||||
"sk_SK": "Spravovanie bežiacich procesov",
|
||||
"tr_TR": "çalışan işlemleri görüntüle",
|
||||
"vi_VN": "Xem các tiến trình đang chạy"
|
||||
},
|
||||
"singular": true,
|
||||
"category": "system",
|
||||
"icon": "apps/gnome-monitor.png",
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/ProcessViewer",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/Settings": {
|
||||
"className": "ApplicationSettings",
|
||||
"preloadParallel": true,
|
||||
"name": "Settings",
|
||||
"mime": null,
|
||||
"icon": "categories/applications-system.png",
|
||||
"category": "system",
|
||||
"singular": true,
|
||||
"names": {
|
||||
"bg_BG": "Настройки",
|
||||
"de_DE": "Einstellungen",
|
||||
"es_ES": "Settings",
|
||||
"fr_FR": "Paramètres",
|
||||
"it_IT": "Settaggi",
|
||||
"ko_KR": "환경설정",
|
||||
"nl_NL": "Instellingen",
|
||||
"no_NO": "Instillinger",
|
||||
"pl_PL": "Ustawienia",
|
||||
"ru_RU": "Настройки",
|
||||
"sk_SK": "Nastavenia",
|
||||
"tr_TR": "Ayarlar",
|
||||
"vi_VN": "Cài đặt"
|
||||
},
|
||||
"descriptions": {
|
||||
"bg_BG": "Настройки",
|
||||
"de_DE": "Einstellungen",
|
||||
"es_ES": "Settings",
|
||||
"fr_FR": "Paramètres",
|
||||
"it_IT": "Settaggi",
|
||||
"ko_KR": "환경설정",
|
||||
"nl_NL": "Instellingen",
|
||||
"no_NO": "Instillinger",
|
||||
"pl_PL": "Ustawienia",
|
||||
"ru_RU": "Настройки",
|
||||
"sk_SK": "Nastavenia",
|
||||
"tr_TR": "Program Ayarlarını düzenle",
|
||||
"vi_VN": "Cài đặt"
|
||||
},
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/Settings",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/Textpad": {
|
||||
"className": "ApplicationTextpad",
|
||||
"name": "Textpad",
|
||||
"description": "Simple text editor",
|
||||
"names": {
|
||||
"bg_BG": "Текстов редактор",
|
||||
"de_DE": "Texteditor",
|
||||
"fr_FR": "Éditeur de texte",
|
||||
"it_IT": "Editor Testi",
|
||||
"ko_KR": "텍스트패드",
|
||||
"nl_NL": "Notities",
|
||||
"no_NO": "Tekstblokk",
|
||||
"pl_PL": "Notatnik",
|
||||
"ru_RU": "Редактор текста",
|
||||
"sk_SK": "Poznámkový blok",
|
||||
"tr_TR": "Basit Bir Metin Düzenleyicisi",
|
||||
"vi_VN": "Trình sửa văn bản"
|
||||
},
|
||||
"descriptions": {
|
||||
"bg_BG": "Стандартен текстов редактор",
|
||||
"de_DE": "Einfacher Texteditor",
|
||||
"fr_FR": "Éditeur de texte simple",
|
||||
"it_IT": "Semplice editor di testi",
|
||||
"ko_KR": "간단한 텍스트 편집기",
|
||||
"nl_NL": "Eenvoudige Tekstverwerker",
|
||||
"no_NO": "Simpel tekst redigering",
|
||||
"pl_PL": "Prosty edytor tekstu",
|
||||
"ru_RU": "Простой текстовый редактор",
|
||||
"sk_SK": "Jednoduchý textový editor",
|
||||
"tr_TR": "Basit Bir Metin Düzenleyicisi",
|
||||
"vi_VN": "Trình sửa văn bản đơn giản"
|
||||
},
|
||||
"mime": [
|
||||
"^text",
|
||||
"inode\\/x\\-empty",
|
||||
"application\\/x\\-empty",
|
||||
"application\\/x\\-lua",
|
||||
"application\\/x\\-python",
|
||||
"application\\/javascript",
|
||||
"application\\/json"
|
||||
],
|
||||
"category": "utilities",
|
||||
"icon": "apps/accessories-text-editor.png",
|
||||
"preload": [{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/Textpad",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/wTerm": {
|
||||
"className": "ApplicationwTerm",
|
||||
"name": "wTerm",
|
||||
"mime": null,
|
||||
"icon": "apps/terminal.png",
|
||||
"category": "system",
|
||||
"preload": [{
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
}, {
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
}, {
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}],
|
||||
"type": "application",
|
||||
"path": "default/wTerm",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
},
|
||||
"default/LuaPlayground": {
|
||||
"className": "ApplicationLuaPlayground",
|
||||
"name": "Lua Playground",
|
||||
"mime": null,
|
||||
"icon": "categories/preferences-other.png",
|
||||
"category": "development",
|
||||
"preload": [
|
||||
{
|
||||
"type": "javascript",
|
||||
"src": "combined.js"
|
||||
},
|
||||
{
|
||||
"type": "stylesheet",
|
||||
"src": "combined.css"
|
||||
},
|
||||
{
|
||||
"src": "scheme.html",
|
||||
"type": "scheme"
|
||||
}
|
||||
],
|
||||
"type": "application",
|
||||
"path": "default/LuaPlayground",
|
||||
"build": {},
|
||||
"repo": "default"
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
|
||||
local packages={}
|
||||
local vfs = require("fs.vfs")
|
||||
local uid = unix.uid(SESSION.iotos_user)
|
||||
|
||||
packages._cache = function(y)
|
||||
local p = vfs.ospath(y)
|
||||
local f = io.open(p.."/packages.json", "w")
|
||||
local has_cache = false
|
||||
local i = 1
|
||||
local meta = {}
|
||||
if f then
|
||||
local files = vfs.readDir(y)
|
||||
for k,v in pairs(files) do
|
||||
if v.type == "dir" then
|
||||
local f1 = io.open(vfs.ospath(v.path.."/package.json"))
|
||||
if f1 then
|
||||
|
||||
local name = std.basename(v.path)
|
||||
local mt = JSON.decodeString(f1:read("*all"))
|
||||
mt.path = v.path
|
||||
meta[i] ='"'..name..'":'..JSON.encode(mt)
|
||||
i = i+1
|
||||
f1:close()
|
||||
has_cache = true;
|
||||
end
|
||||
end
|
||||
end
|
||||
f:write(table.concat(meta, ","))
|
||||
f:close()
|
||||
if has_cache == false then
|
||||
unix.delete(p.."/packages.json");
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- we will change this later
|
||||
packages.list = function(paths)
|
||||
std.json()
|
||||
std.t("{\"result\" : { ")
|
||||
local first = true
|
||||
--std.f(__ROOT__.."/system/packages.json")
|
||||
for k,v in pairs(paths) do
|
||||
local osp = vfs.ospath(v.."/packages.json")
|
||||
if unix.exists(osp) == false then
|
||||
packages._cache(v)
|
||||
end
|
||||
if unix.exists(osp) then
|
||||
if first == false then
|
||||
std.t(",")
|
||||
else
|
||||
first = false
|
||||
end
|
||||
std.f(osp)
|
||||
end
|
||||
end
|
||||
std.t("}, \"error\":false}")
|
||||
end
|
||||
|
||||
-- generate the packages caches
|
||||
packages.cache = function(args)
|
||||
-- perform a packages caches
|
||||
for x,y in pairs(args.paths) do
|
||||
packages._cache(y)
|
||||
end
|
||||
result(true)
|
||||
end
|
||||
-- install a function from zip file
|
||||
packages.install = function(args)
|
||||
local path = vfs.ospath(args.dest)
|
||||
local zip = vfs.ospath(args.zip)
|
||||
if(unix.exists(path) == false) then
|
||||
-- create directory if not exist
|
||||
unix.mkdir(path)
|
||||
-- change permission
|
||||
unix.chown(path, uid.id, uid.gid)
|
||||
end
|
||||
-- extract the zip file to it
|
||||
if(unix.unzip(zip, path)) then
|
||||
-- read metadata
|
||||
local meta = JSON.decodeFile(path.."/metadata.json")
|
||||
meta.path = args.dest
|
||||
meta.scope = "user"
|
||||
local f=io.open(path.."/package.json","w")
|
||||
if f then
|
||||
f:write(JSON.encode(meta))
|
||||
f:close()
|
||||
end
|
||||
result(true)
|
||||
else
|
||||
fail("Problem extracting zip file")
|
||||
end
|
||||
|
||||
end
|
||||
-- uninstall the package
|
||||
packages.uninstall = function(path)
|
||||
local osf = vfs.ospath(path)
|
||||
if(osf and unix.exists(osf) ) then
|
||||
--remove it
|
||||
unix.delete(osf)
|
||||
result(true)
|
||||
else
|
||||
fail("Cannot find package")
|
||||
end
|
||||
end
|
||||
-- set user packages environment
|
||||
packages.init = function(paths)
|
||||
if(paths) then
|
||||
for k,v in pairs(paths) do
|
||||
local p = vfs.ospath(v)
|
||||
if p and (unix.exists(p) == false) then
|
||||
unix.mkdir(p)
|
||||
-- change permission
|
||||
unix.chown(p, uid.id, uid.gid)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- main()
|
||||
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
packages.init(rq.args.paths)
|
||||
if rq ~= nil then
|
||||
-- check user command here
|
||||
if(rq.command == "install") then
|
||||
packages.install(rq.args)
|
||||
elseif rq.command == "cache" then
|
||||
packages.cache(rq.args)
|
||||
elseif rq.command == "list" then
|
||||
packages.list(rq.args.paths)
|
||||
elseif rq.command == "uninstall" then
|
||||
packages.uninstall(rq.args.path)
|
||||
else
|
||||
fail("Uknown packages command")
|
||||
end
|
||||
else
|
||||
fail("Uknown request")
|
||||
end
|
@ -1,19 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local user = SESSION.iotos_user
|
||||
if user then
|
||||
local ospath = require('fs.vfs').ospath("home:///",user)
|
||||
if REQUEST.query and REQUEST.query.json then
|
||||
local f = io.open(ospath.."/"..".settings.json", "w")
|
||||
if f then
|
||||
f:write(REQUEST.query.json)
|
||||
f:close()
|
||||
result(true)
|
||||
else
|
||||
fail("Cannot save setting")
|
||||
end
|
||||
else
|
||||
fail("No setting founds")
|
||||
end
|
||||
else
|
||||
fail("User not found")
|
||||
end
|
@ -1,27 +0,0 @@
|
||||
local uman={}
|
||||
|
||||
uman.userinfo = function(user)
|
||||
local info = {}
|
||||
local uid = unix.uid(user)
|
||||
if uid then
|
||||
-- read the setting
|
||||
-- use the decodeFile function of JSON instead
|
||||
local file = require('fs.vfs').ospath("home:///").."/.settings.json"
|
||||
local st = JSON.decodeFile(file)
|
||||
if(st) then
|
||||
info = st
|
||||
end
|
||||
info.user = {
|
||||
username = user,
|
||||
id = uid.id,
|
||||
name = user,
|
||||
groups = uid.groups
|
||||
}
|
||||
--print(JSON.encode(info))
|
||||
return info
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end
|
||||
|
||||
return uman
|
@ -1,23 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
local rq = (JSON.decodeString(REQUEST.query.json))
|
||||
if rq then
|
||||
if rq.command == "list" then
|
||||
users = {}
|
||||
local uid = unix.uid(SESSION.iotos_user)
|
||||
if uid then
|
||||
users[0] = {
|
||||
username = SESSION.iotos_user,
|
||||
id = uid.id,
|
||||
name = SESSION.iotos_user,
|
||||
groups = {"admin"}
|
||||
}
|
||||
result(users)
|
||||
else
|
||||
fail("Problem when retreive users")
|
||||
end
|
||||
else
|
||||
fail("command "..rq.command.." is not supported yet")
|
||||
end
|
||||
else
|
||||
fail("Unknow request")
|
||||
end
|
@ -1,28 +0,0 @@
|
||||
<?lua
|
||||
std.html()
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Page Title</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>This is a Heading</h1>
|
||||
<p>This is a paragraph.</p>
|
||||
<ul>
|
||||
<?lua
|
||||
|
||||
local data = {k1 = "One", k2 = "two", k3 = "three"}
|
||||
for k,v in pairs(data) do
|
||||
?>
|
||||
<li class = "<?=k..'1'?>" id = "<?=k..'2'?>" >
|
||||
<?lua echo(v) ?>
|
||||
</li>
|
||||
<?lua
|
||||
end
|
||||
echo("end of \" %> lua")
|
||||
?>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
@ -1,62 +0,0 @@
|
||||
auth_or_die("User unauthorized. Please login")
|
||||
if std.ws.enable() then
|
||||
-- read header
|
||||
local streaming = true
|
||||
while streaming do
|
||||
local header = std.ws.header()
|
||||
if header then
|
||||
if header.mask == 0 then
|
||||
print("Data is not masked")
|
||||
std.ws.close(1012)
|
||||
streaming = false
|
||||
elseif header.opcode == std.ws.CLOSE then
|
||||
print("Connection closed")
|
||||
std.ws.close(1000)
|
||||
streaming = false
|
||||
elseif header.opcode == std.ws.BIN then
|
||||
-- read the file
|
||||
local data = std.ws.read(header)
|
||||
local cmd = nil
|
||||
if data then
|
||||
local str = bytes.__tostring(data)
|
||||
local b,e = str:find("^%d+")
|
||||
if(b) then
|
||||
local size = tonumber(str:sub(b,e))
|
||||
local path = require("fs.vfs").ospath(str:sub(e+1))
|
||||
local file = io.open(path, "rb")
|
||||
if file then
|
||||
local sum, len = 0,0
|
||||
repeat
|
||||
local buffer = file:read(size)
|
||||
if buffer then
|
||||
len = len + #buffer
|
||||
cmd = bytes.new(#buffer)
|
||||
for i = 1, #buffer do
|
||||
cmd[i] = buffer:byte(i)
|
||||
end
|
||||
std.ws.write_bytes(cmd)
|
||||
end
|
||||
until not buffer
|
||||
file:close()
|
||||
print("ospath is : "..path)
|
||||
print("length:",len)
|
||||
else
|
||||
print(path.." is not found")
|
||||
std.ws.close(1011)
|
||||
end
|
||||
else
|
||||
std.ws.close(1011)
|
||||
end
|
||||
else
|
||||
std.ws.close(1011)
|
||||
streaming = false
|
||||
end
|
||||
end
|
||||
else
|
||||
streaming = false
|
||||
end
|
||||
end
|
||||
else
|
||||
print("Web socket is not available.")
|
||||
end
|
||||
print("Quit streaming")
|
@ -1,33 +0,0 @@
|
||||
if std.ws.enable() then
|
||||
-- read header
|
||||
local streaming = true
|
||||
while streaming do
|
||||
local header = std.ws.header()
|
||||
if header then
|
||||
if header.mask == 0 then
|
||||
print("Data is not masked")
|
||||
std.ws.close(1012)
|
||||
streaming = false
|
||||
elseif header.opcode == std.ws.CLOSE then
|
||||
print("Connection closed")
|
||||
std.ws.close(1000)
|
||||
streaming = false
|
||||
elseif header.opcode == std.ws.BIN then
|
||||
local data = std.ws.read(header)
|
||||
if data then
|
||||
local path = (__ROOT__.."/ws/img%d.jpg"):format(data[0])
|
||||
print("writing : "..path)
|
||||
std.ws.fwrite(path)
|
||||
else
|
||||
std.ws.close(1011)
|
||||
streaming = false
|
||||
end
|
||||
end
|
||||
else
|
||||
streaming = false
|
||||
end
|
||||
end
|
||||
else
|
||||
print("Web socket is not available.")
|
||||
end
|
||||
print("Quit streaming")
|
@ -1,17 +0,0 @@
|
||||
std.html()
|
||||
local pid = unix.fork()
|
||||
if pid == -1 then
|
||||
echo("Fail to fork")
|
||||
elseif pid > 0 then
|
||||
for i = 1,10 do
|
||||
print("parent "..i)
|
||||
end
|
||||
unix.waitpid(pid)
|
||||
print("Child finish")
|
||||
else
|
||||
for i = 1,20 do
|
||||
print("child "..i)
|
||||
end
|
||||
end
|
||||
|
||||
print "reach for both"
|
@ -1,82 +0,0 @@
|
||||
OSROOT = __ROOT__.."/os"
|
||||
package.path = package.path..";"..__ROOT__ .. '/os/?.lua'
|
||||
|
||||
unix = require("ulib")
|
||||
require("sqlite")
|
||||
|
||||
if HEADER["User-Agent"] and HEADER["User-Agent"]:match("Mobi") then
|
||||
HEADER.mobile = true
|
||||
end
|
||||
|
||||
|
||||
function fail(msg)
|
||||
std.json()
|
||||
std.t(JSON.encode({error=msg}))
|
||||
end
|
||||
|
||||
function result(obj)
|
||||
std.json()
|
||||
std.t(JSON.encode({result=obj, error=false}))
|
||||
end
|
||||
|
||||
function die (msg)
|
||||
fail(msg)
|
||||
debug.traceback=nil
|
||||
error("Permission denied")
|
||||
end
|
||||
|
||||
-- test only
|
||||
if REQUEST.path:match("^%/*router%.lua$") or REQUEST.path:match("^%/*router$") then
|
||||
die("Recursive call to index.lua is not allown")
|
||||
end
|
||||
|
||||
-- check if the sysdb is create, otherwise create the table
|
||||
function sysdb()
|
||||
local meta = {}
|
||||
meta.sessionid = ""
|
||||
meta.username = ""
|
||||
meta.stamp = 0
|
||||
return require("db.model").get("sysdb", "sessions", meta)
|
||||
end
|
||||
|
||||
function is_auth()
|
||||
if SESSION.sessionid == nil or SESSION.sessionid == '0' then return false end
|
||||
-- query session id from database
|
||||
local db = sysdb()
|
||||
if db == nil then return false end
|
||||
local cond = {exp= {["="] = { sessionid = SESSION.sessionid }}}
|
||||
local data = db:find(cond)
|
||||
--print(JSON.encode(data))
|
||||
db:close()
|
||||
if data == nil or data[1] == nil then die(msg) end
|
||||
-- next time check the stamp
|
||||
SESSION.iotos_user = data[1].username
|
||||
return true
|
||||
end
|
||||
|
||||
function auth_or_die(msg)
|
||||
if(is_auth() == false) then
|
||||
die(msg)
|
||||
end
|
||||
end
|
||||
|
||||
local m, s, p = has_module(REQUEST.path)
|
||||
if m then
|
||||
-- run the correct module
|
||||
if s then
|
||||
local r,e = loadscript(p)
|
||||
if r then r() else fail(e) end
|
||||
else
|
||||
require(p)
|
||||
end
|
||||
else
|
||||
local hstr = REQUEST.path:match("^%a+/")
|
||||
if hstr == "os/" then
|
||||
--print("require module")
|
||||
require("os.router")(REQUEST.path:gsub(hstr,"",1))
|
||||
elseif hstr == "blog/" then
|
||||
require("blog.router")(REQUEST.path:gsub(hstr,"",1))
|
||||
else
|
||||
fail("Resource not found for request "..REQUEST.path)
|
||||
end
|
||||
end
|
@ -1,5 +1,5 @@
|
||||
SUBDIRS = core asl
|
||||
if HAS_CMAKE
|
||||
SUBDIRS += ann
|
||||
endif
|
||||
EXTRA_DIST = lualib.h
|
||||
SUBDIRS = core asl md
|
||||
#if HAS_CMAKE
|
||||
# SUBDIRS += ann
|
||||
#endif
|
||||
EXTRA_DIST = lualib.h
|
||||
|
769
lib/ann/Makefile
769
lib/ann/Makefile
@ -1,769 +0,0 @@
|
||||
# Makefile.in generated by automake 1.15.1 from Makefile.am.
|
||||
# lib/ann/Makefile. Generated from Makefile.in by configure.
|
||||
|
||||
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
|
||||
|
||||
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
*) echo "am__make_running_with_option: internal error: invalid" \
|
||||
"target option '$${target_option-}' specified" >&2; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
has_opt=no; \
|
||||
sane_makeflags=$$MAKEFLAGS; \
|
||||
if $(am__is_gnu_make); then \
|
||||
sane_makeflags=$$MFLAGS; \
|
||||
else \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
bs=\\; \
|
||||
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
|
||||
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
|
||||
esac; \
|
||||
fi; \
|
||||
skip_next=no; \
|
||||
strip_trailopt () \
|
||||
{ \
|
||||
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
|
||||
}; \
|
||||
for flg in $$sane_makeflags; do \
|
||||
test $$skip_next = yes && { skip_next=no; continue; }; \
|
||||
case $$flg in \
|
||||
*=*|--*) continue;; \
|
||||
-*I) strip_trailopt 'I'; skip_next=yes;; \
|
||||
-*I?*) strip_trailopt 'I';; \
|
||||
-*O) strip_trailopt 'O'; skip_next=yes;; \
|
||||
-*O?*) strip_trailopt 'O';; \
|
||||
-*l) strip_trailopt 'l'; skip_next=yes;; \
|
||||
-*l?*) strip_trailopt 'l';; \
|
||||
-[dEDm]) skip_next=yes;; \
|
||||
-[JT]) skip_next=yes;; \
|
||||
esac; \
|
||||
case $$flg in \
|
||||
*$$target_option*) has_opt=yes; break;; \
|
||||
esac; \
|
||||
done; \
|
||||
test $$has_opt = yes
|
||||
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
|
||||
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
|
||||
pkgdatadir = $(datadir)/lua
|
||||
pkgincludedir = $(includedir)/lua
|
||||
pkglibdir = $(libdir)/lua
|
||||
pkglibexecdir = $(libexecdir)/lua
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = x86_64-pc-linux-gnu
|
||||
host_triplet = x86_64-pc-linux-gnu
|
||||
subdir = lib/ann
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(libdir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
ann_la_DEPENDENCIES = ./fann/build/src/libdoublefann.a
|
||||
am_ann_la_OBJECTS = ann_la-ann.lo
|
||||
ann_la_OBJECTS = $(am_ann_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_$(V))
|
||||
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_lt_0 = --silent
|
||||
am__v_lt_1 =
|
||||
ann_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(ann_la_CFLAGS) $(CFLAGS) \
|
||||
$(ann_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_P = $(am__v_P_$(V))
|
||||
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_P_0 = false
|
||||
am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_$(V))
|
||||
am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_$(V))
|
||||
am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CFLAGS) $(CFLAGS)
|
||||
AM_V_CC = $(am__v_CC_$(V))
|
||||
am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CC_1 =
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CCLD = $(am__v_CCLD_$(V))
|
||||
am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_CCLD_1 =
|
||||
SOURCES = $(ann_la_SOURCES)
|
||||
DIST_SOURCES = $(ann_la_SOURCES)
|
||||
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
|
||||
ctags-recursive dvi-recursive html-recursive info-recursive \
|
||||
install-data-recursive install-dvi-recursive \
|
||||
install-exec-recursive install-html-recursive \
|
||||
install-info-recursive install-pdf-recursive \
|
||||
install-ps-recursive install-recursive installcheck-recursive \
|
||||
installdirs-recursive pdf-recursive ps-recursive \
|
||||
tags-recursive uninstall-recursive
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
|
||||
distclean-recursive maintainer-clean-recursive
|
||||
am__recursive_targets = \
|
||||
$(RECURSIVE_TARGETS) \
|
||||
$(RECURSIVE_CLEAN_TARGETS) \
|
||||
$(am__extra_recursive_targets)
|
||||
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
|
||||
distdir
|
||||
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
|
||||
# Read a list of newline-separated strings from the standard input,
|
||||
# and print each of them once, without duplicates. Input order is
|
||||
# *not* preserved.
|
||||
am__uniquify_input = $(AWK) '\
|
||||
BEGIN { nonempty = 0; } \
|
||||
{ items[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in items) print i; }; } \
|
||||
'
|
||||
# Make sure the list of sources is unique. This is necessary because,
|
||||
# e.g., the same source file might be shared among _SOURCES variables
|
||||
# for different programs/libraries.
|
||||
am__define_uniq_tagged_files = \
|
||||
list='$(am__tagged_files)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DIST_SUBDIRS = $(SUBDIRS)
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
am__relativize = \
|
||||
dir0=`pwd`; \
|
||||
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
|
||||
sed_rest='s,^[^/]*/*,,'; \
|
||||
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
|
||||
sed_butlast='s,/*[^/]*$$,,'; \
|
||||
while test -n "$$dir1"; do \
|
||||
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
|
||||
if test "$$first" != "."; then \
|
||||
if test "$$first" = ".."; then \
|
||||
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
|
||||
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
|
||||
else \
|
||||
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
|
||||
if test "$$first2" = "$$first"; then \
|
||||
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
|
||||
else \
|
||||
dir2="../$$dir2"; \
|
||||
fi; \
|
||||
dir0="$$dir0"/"$$first"; \
|
||||
fi; \
|
||||
fi; \
|
||||
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
|
||||
done; \
|
||||
reldir="$$dir2"
|
||||
ACLOCAL = ${SHELL} /home/mrsang/build/antd-lua-plugin/missing aclocal-1.15
|
||||
AMTAR = $${TAR-tar}
|
||||
AM_DEFAULT_VERBOSITY = 1
|
||||
AR = ar
|
||||
AUTOCONF = ${SHELL} /home/mrsang/build/antd-lua-plugin/missing autoconf
|
||||
AUTOHEADER = ${SHELL} /home/mrsang/build/antd-lua-plugin/missing autoheader
|
||||
AUTOMAKE = ${SHELL} /home/mrsang/build/antd-lua-plugin/missing automake-1.15
|
||||
AWK = gawk
|
||||
CC = gcc
|
||||
CCDEPMODE = depmode=gcc3
|
||||
CFLAGS = -g -O2
|
||||
CPP = gcc -E
|
||||
CPPFLAGS =
|
||||
CYGPATH_W = echo
|
||||
DEFS = -DPACKAGE_NAME=\"lua\" -DPACKAGE_TARNAME=\"lua\" -DPACKAGE_VERSION=\"0.5.2b\" -DPACKAGE_STRING=\"lua\ 0.5.2b\" -DPACKAGE_BUGREPORT=\"xsang.le@gmail.com\" -DPACKAGE_URL=\"\" -DPACKAGE=\"lua\" -DVERSION=\"0.5.2b\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_LIBANTD=1 -DUSE_DB=1 -DHAVE_LIBSQLITE3=1 -DHAVE_LIBPTHREAD=1 -DHAVE_LIBDL=1 -DHAVE_LIBM=1 -DHAVE_LIBREADLINE=1 -D_GNU_SOURCE=1 -DDEBUG=1 -DLINUX=1 -DHAVE_LIBCRYPT=1
|
||||
DEPDIR = .deps
|
||||
DLLTOOL = false
|
||||
DSYMUTIL =
|
||||
DUMPBIN =
|
||||
ECHO_C =
|
||||
ECHO_N = -n
|
||||
ECHO_T =
|
||||
EGREP = /bin/grep -E
|
||||
EXEEXT =
|
||||
FGREP = /bin/grep -F
|
||||
GREP = /bin/grep
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_DATA = ${INSTALL} -m 644
|
||||
INSTALL_PROGRAM = ${INSTALL}
|
||||
INSTALL_SCRIPT = ${INSTALL}
|
||||
INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
|
||||
LD = /usr/bin/ld -m elf_x86_64
|
||||
LDFLAGS =
|
||||
LIBOBJS =
|
||||
LIBS = -lcrypt -lreadline -lm -ldl -lpthread -lsqlite3 -lantd
|
||||
LIBTOOL = $(SHELL) $(top_builddir)/libtool
|
||||
LIPO =
|
||||
LN_S = ln -s
|
||||
LTLIBOBJS =
|
||||
LT_SYS_LIBRARY_PATH =
|
||||
MAKEINFO = ${SHELL} /home/mrsang/build/antd-lua-plugin/missing makeinfo
|
||||
MANIFEST_TOOL = :
|
||||
MKDIR_P = /bin/mkdir -p
|
||||
NM = /usr/bin/nm -B
|
||||
NMEDIT =
|
||||
OBJDUMP = objdump
|
||||
OBJEXT = o
|
||||
OTOOL =
|
||||
OTOOL64 =
|
||||
PACKAGE = lua
|
||||
PACKAGE_BUGREPORT = xsang.le@gmail.com
|
||||
PACKAGE_NAME = lua
|
||||
PACKAGE_STRING = lua 0.5.2b
|
||||
PACKAGE_TARNAME = lua
|
||||
PACKAGE_URL =
|
||||
PACKAGE_VERSION = 0.5.2b
|
||||
PATH_SEPARATOR = :
|
||||
RANLIB = ranlib
|
||||
SED = /bin/sed
|
||||
SET_MAKE =
|
||||
SHELL = /bin/bash
|
||||
STRIP = strip
|
||||
VERSION = 0.5.2b
|
||||
abs_builddir = /home/mrsang/build/antd-lua-plugin/lib/ann
|
||||
abs_srcdir = /home/mrsang/build/antd-lua-plugin/lib/ann
|
||||
abs_top_builddir = /home/mrsang/build/antd-lua-plugin
|
||||
abs_top_srcdir = /home/mrsang/build/antd-lua-plugin
|
||||
ac_ct_AR = ar
|
||||
ac_ct_CC = gcc
|
||||
ac_ct_DUMPBIN =
|
||||
am__include = include
|
||||
am__leading_dot = .
|
||||
am__quote =
|
||||
am__tar = $${TAR-tar} chof - "$$tardir"
|
||||
am__untar = $${TAR-tar} xf -
|
||||
bindir = ${exec_prefix}/bin
|
||||
build = x86_64-pc-linux-gnu
|
||||
build_alias =
|
||||
build_cpu = x86_64
|
||||
build_os = linux-gnu
|
||||
build_vendor = pc
|
||||
builddir = .
|
||||
datadir = ${datarootdir}
|
||||
datarootdir = ${prefix}/share
|
||||
docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
|
||||
dvidir = ${docdir}
|
||||
exec_prefix = ${prefix}
|
||||
has_cmake = yes
|
||||
host = x86_64-pc-linux-gnu
|
||||
host_alias =
|
||||
host_cpu = x86_64
|
||||
host_os = linux-gnu
|
||||
host_vendor = pc
|
||||
htmldir = ${docdir}
|
||||
includedir = ${prefix}/include
|
||||
infodir = ${datarootdir}/info
|
||||
install_sh = ${SHELL} /home/mrsang/build/antd-lua-plugin/install-sh
|
||||
libdir = $(prefix)/lib/lua/
|
||||
libexecdir = ${exec_prefix}/libexec
|
||||
localedir = ${datarootdir}/locale
|
||||
localstatedir = ${prefix}/var
|
||||
mandir = ${datarootdir}/man
|
||||
mkdir_p = $(MKDIR_P)
|
||||
oldincludedir = /usr/include
|
||||
pdfdir = ${docdir}
|
||||
prefix = /opt/www
|
||||
program_transform_name = s,x,x,
|
||||
psdir = ${docdir}
|
||||
runstatedir = ${localstatedir}/run
|
||||
sbindir = ${exec_prefix}/sbin
|
||||
sharedstatedir = ${prefix}/com
|
||||
srcdir = .
|
||||
sysconfdir = ${prefix}/etc
|
||||
target_alias =
|
||||
top_build_prefix = ../../
|
||||
top_builddir = ../..
|
||||
top_srcdir = ../..
|
||||
lib_LTLIBRARIES = ann.la
|
||||
ann_la_LDFLAGS = -module -avoid-version -shared
|
||||
ann_la_SOURCES = ann.c
|
||||
ann_la_CFLAGS = -I./fann/src/include/
|
||||
ann_la_LIBADD = ./fann/build/src/libdoublefann.a
|
||||
EXTRA_DIST = data.c extension.c lfann.h net.c fann
|
||||
SUBDIRS = fann
|
||||
all: all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/ann/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu lib/ann/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
|
||||
}
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; \
|
||||
locs=`for p in $$list; do echo $$p; done | \
|
||||
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
|
||||
sort -u`; \
|
||||
test -z "$$locs" || { \
|
||||
echo rm -f $${locs}; \
|
||||
rm -f $${locs}; \
|
||||
}
|
||||
|
||||
ann.la: $(ann_la_OBJECTS) $(ann_la_DEPENDENCIES) $(EXTRA_ann_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(ann_la_LINK) -rpath $(libdir) $(ann_la_OBJECTS) $(ann_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
include ./$(DEPDIR)/ann_la-ann.Plo
|
||||
|
||||
.c.o:
|
||||
$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||
$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||
$(am__mv) $$depbase.Tpo $$depbase.Po
|
||||
# $(AM_V_CC)source='$<' object='$@' libtool=no \
|
||||
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
|
||||
# $(AM_V_CC_no)$(COMPILE) -c -o $@ $<
|
||||
|
||||
.c.obj:
|
||||
$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
|
||||
$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
|
||||
$(am__mv) $$depbase.Tpo $$depbase.Po
|
||||
# $(AM_V_CC)source='$<' object='$@' libtool=no \
|
||||
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
|
||||
# $(AM_V_CC_no)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
|
||||
$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||
$(am__mv) $$depbase.Tpo $$depbase.Plo
|
||||
# $(AM_V_CC)source='$<' object='$@' libtool=yes \
|
||||
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
|
||||
# $(AM_V_CC_no)$(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
ann_la-ann.lo: ann.c
|
||||
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ann_la_CFLAGS) $(CFLAGS) -MT ann_la-ann.lo -MD -MP -MF $(DEPDIR)/ann_la-ann.Tpo -c -o ann_la-ann.lo `test -f 'ann.c' || echo '$(srcdir)/'`ann.c
|
||||
$(AM_V_at)$(am__mv) $(DEPDIR)/ann_la-ann.Tpo $(DEPDIR)/ann_la-ann.Plo
|
||||
# $(AM_V_CC)source='ann.c' object='ann_la-ann.lo' libtool=yes \
|
||||
# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \
|
||||
# $(AM_V_CC_no)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ann_la_CFLAGS) $(CFLAGS) -c -o ann_la-ann.lo `test -f 'ann.c' || echo '$(srcdir)/'`ann.c
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run 'make' without going through this Makefile.
|
||||
# To change the values of 'make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in 'config.status', edit 'config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run 'make');
|
||||
# (2) otherwise, pass the desired values on the 'make' command line.
|
||||
$(am__recursive_targets):
|
||||
@fail=; \
|
||||
if $(am__make_keepgoing); then \
|
||||
failcom='fail=yes'; \
|
||||
else \
|
||||
failcom='exit 1'; \
|
||||
fi; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
case "$@" in \
|
||||
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||
*) list='$(SUBDIRS)' ;; \
|
||||
esac; \
|
||||
for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| eval $$failcom; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
ID: $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); mkid -fID $$unique
|
||||
tags: tags-recursive
|
||||
TAGS: tags
|
||||
|
||||
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||
include_option=--etags-include; \
|
||||
empty_fix=.; \
|
||||
else \
|
||||
include_option=--include; \
|
||||
empty_fix=; \
|
||||
fi; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test ! -f $$subdir/TAGS || \
|
||||
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
$(am__define_uniq_tagged_files); \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: ctags-recursive
|
||||
|
||||
CTAGS: ctags
|
||||
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
|
||||
$(am__define_uniq_tagged_files); \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
cscopelist: cscopelist-recursive
|
||||
|
||||
cscopelist-am: $(am__tagged_files)
|
||||
list='$(am__tagged_files)'; \
|
||||
case "$(srcdir)" in \
|
||||
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
|
||||
*) sdir=$(subdir)/$(srcdir) ;; \
|
||||
esac; \
|
||||
for i in $$list; do \
|
||||
if test -f "$$i"; then \
|
||||
echo "$(subdir)/$$i"; \
|
||||
else \
|
||||
echo "$$sdir/$$i"; \
|
||||
fi; \
|
||||
done >> $(top_builddir)/cscope.files
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
$(am__make_dryrun) \
|
||||
|| test -d "$(distdir)/$$subdir" \
|
||||
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|
||||
|| exit 1; \
|
||||
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
|
||||
$(am__relativize); \
|
||||
new_distdir=$$reldir; \
|
||||
dir1=$$subdir; dir2="$(top_distdir)"; \
|
||||
$(am__relativize); \
|
||||
new_top_distdir=$$reldir; \
|
||||
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
|
||||
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
|
||||
($(am__cd) $$subdir && \
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$$new_top_distdir" \
|
||||
distdir="$$new_distdir" \
|
||||
am__remove_distdir=: \
|
||||
am__skip_length_check=: \
|
||||
am__skip_mode_fix=: \
|
||||
distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
all-am: Makefile $(LTLIBRARIES)
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
for dir in "$(DESTDIR)$(libdir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-recursive
|
||||
install-exec: install-exec-recursive
|
||||
install-data: install-data-recursive
|
||||
uninstall: uninstall-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-recursive
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-recursive
|
||||
|
||||
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-recursive
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-recursive
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-recursive
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-recursive
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-libLTLIBRARIES
|
||||
|
||||
install-html: install-html-recursive
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-recursive
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-recursive
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-recursive
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-recursive
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-recursive
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-libLTLIBRARIES
|
||||
|
||||
.MAKE: $(am__recursive_targets) install-am install-strip
|
||||
|
||||
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
|
||||
check-am clean clean-generic clean-libLTLIBRARIES \
|
||||
clean-libtool cscopelist-am ctags ctags-am distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am \
|
||||
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
|
||||
install-ps install-ps-am install-strip installcheck \
|
||||
installcheck-am installdirs installdirs-am maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -1,6 +1,6 @@
|
||||
all:
|
||||
all: clean-local
|
||||
-mkdir build
|
||||
cd build && cmake .. && make
|
||||
|
||||
clean-local:
|
||||
-rm -rf build
|
||||
-rm -rf build
|
||||
|
@ -2,6 +2,10 @@ lib_LTLIBRARIES = ulib.la
|
||||
ulib_la_LDFLAGS = -module -avoid-version -shared
|
||||
ulib_la_SOURCES = 3rd/zip/zip.c ulib.c
|
||||
|
||||
lib_LTLIBRARIES += handle.la
|
||||
handle_la_LDFLAGS = -module -avoid-version -shared
|
||||
handle_la_SOURCES = handle.c
|
||||
|
||||
lib_LTLIBRARIES += antd.la
|
||||
antd_la_LDFLAGS = -module -avoid-version -shared
|
||||
antd_la_SOURCES = antd.c
|
||||
@ -15,10 +19,6 @@ json_la_LDFLAGS = -module -avoid-version -shared
|
||||
json_la_SOURCES = 3rd/jsmn/jsmn.c json.c
|
||||
|
||||
|
||||
lib_LTLIBRARIES += wurl.la
|
||||
wurl_la_LDFLAGS = -module -avoid-version -shared
|
||||
wurl_la_SOURCES = wurl.c
|
||||
|
||||
if HAS_FFI
|
||||
lib_LTLIBRARIES += ffi.la
|
||||
ffi_la_LDFLAGS = -module -avoid-version -shared -lffi
|
||||
@ -35,4 +35,4 @@ endif
|
||||
|
||||
libdir=$(prefix)/lib/lua/
|
||||
|
||||
EXTRA_DIST = 3rd/zip/miniz.c 3rd/zip/zip.h 3rd/jsmn/jsmn.h
|
||||
EXTRA_DIST = 3rd/zip/miniz.c 3rd/zip/zip.h 3rd/jsmn/jsmn.h
|
||||
|
1402
lib/asl/antd.c
1402
lib/asl/antd.c
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@
|
||||
#define MAX_FN_ARGC 32
|
||||
|
||||
// define atomic type
|
||||
typedef enum ffi_atomic_t {
|
||||
typedef enum {
|
||||
L_FFI_TYPE_VOID,
|
||||
L_FFI_TYPE_UINT8,
|
||||
L_FFI_TYPE_SINT8,
|
||||
@ -45,7 +45,7 @@ typedef enum ffi_atomic_t {
|
||||
L_FFI_TYPE_SLONG,
|
||||
L_FFI_TYPE_LONGDOUBLE,
|
||||
L_FFI_TYPE_POINTER
|
||||
};
|
||||
} ffi_atomic_t;
|
||||
|
||||
static const ffi_type* ffi_atomic_type_ptrs[] =
|
||||
{
|
||||
@ -400,7 +400,7 @@ static int l_ffi_atomic_type(lua_State* L)
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
type = ffi_atomic_type_ptrs[etype];
|
||||
type = (ffi_type*)ffi_atomic_type_ptrs[etype];
|
||||
lua_pushlightuserdata(L,type);
|
||||
return 1;
|
||||
}
|
||||
|
105
lib/asl/handle.c
Normal file
105
lib/asl/handle.c
Normal file
@ -0,0 +1,105 @@
|
||||
#include <antd/plugin.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include "../lualib.h"
|
||||
|
||||
typedef struct {
|
||||
plugin_header_t* __plugin__;
|
||||
int fd;
|
||||
} lua_thread_data_t;
|
||||
|
||||
void* lua_handle(void* ptr)
|
||||
{
|
||||
lua_thread_data_t* data = (lua_thread_data_t*)ptr;
|
||||
lua_State* L = NULL;
|
||||
antd_client_t* cl = (antd_client_t*) malloc(sizeof(antd_client_t));
|
||||
cl->sock = data->fd;
|
||||
time(&cl->last_io);
|
||||
cl->ssl = NULL;
|
||||
cl->state = ANTD_CLIENT_PLUGIN_EXEC;
|
||||
cl->z_status = 0;
|
||||
cl->z_level = ANTD_CNONE;
|
||||
cl->zstream = NULL;
|
||||
//char * index = __s("%s/%s",__plugin__->htdocs,"router.lua");
|
||||
char* cnf = __s("%s%s%s", data->__plugin__->pdir,DIR_SEP, data->__plugin__->name);
|
||||
char * apis = __s("%s/%s",cnf,"api.lua");
|
||||
L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
//module loader
|
||||
//luaL_newlib(L, modules);
|
||||
//lua_setglobal(L, "modules");
|
||||
// set up global variable
|
||||
// API header
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"name");
|
||||
lua_pushstring(L, data->__plugin__->name);
|
||||
lua_settable(L,-3);
|
||||
|
||||
//lua_pushstring(L,"root");
|
||||
//htdocs(rq, buf);
|
||||
//lua_pushstring(L, data->__plugin__->htdocs);
|
||||
//lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"apiroot");
|
||||
lua_pushstring(L, cnf);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"tmpdir");
|
||||
lua_pushstring(L, data->__plugin__->tmpdir);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"dbpath");
|
||||
lua_pushstring(L, data->__plugin__->dbpath);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_setglobal(L, "__api__");
|
||||
|
||||
// Request
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"id");
|
||||
lua_pushlightuserdata(L, cl);
|
||||
//lua_pushnumber(L,client);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L,"socket");
|
||||
lua_pushnumber(L, cl->sock);
|
||||
//lua_pushnumber(L,client);
|
||||
lua_settable(L, -3);
|
||||
|
||||
//lua_pushstring(L,"request");
|
||||
//push_dict_to_lua(L,rq->request);
|
||||
//lua_settable(L, -3);
|
||||
lua_setglobal(L, "HTTP_REQUEST");
|
||||
free(ptr);
|
||||
// load major apis
|
||||
if(is_file(apis))
|
||||
if (luaL_loadfile(L, apis) || lua_pcall(L, 0, 0, 0))
|
||||
{
|
||||
ERROR("cannot start API file: [%s] %s\n", apis, lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
/*if (luaL_loadfile(L, index) || lua_pcall(L, 0, 0, 0))
|
||||
{
|
||||
text(client);
|
||||
__t(client, "Cannot run router: %s", lua_tostring(L, -1));
|
||||
}
|
||||
free(index);*/
|
||||
LOG("LUA handle exit on %d", cl->sock);
|
||||
// clear request
|
||||
if(L)
|
||||
lua_close(L);
|
||||
if(cnf)
|
||||
free(cnf);
|
||||
if(apis)
|
||||
free(apis);
|
||||
(void) antd_close(cl);
|
||||
return 0;
|
||||
//lua_close(L);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#include "../lualib.h"
|
||||
#include "3rd/jsmn/jsmn.h"
|
||||
|
||||
#define MAXTOKEN 1024
|
||||
#define MAXTOKEN 8192
|
||||
|
||||
// define unescape sequence
|
||||
|
||||
@ -29,7 +29,7 @@ static int l_json_decode_f (lua_State *L) {
|
||||
buffer = malloc (length+1);
|
||||
if (buffer)
|
||||
{
|
||||
fread (buffer, 1, length, f);
|
||||
UNUSED(fread(buffer, 1, length, f));
|
||||
}
|
||||
fclose (f);
|
||||
}
|
||||
@ -108,23 +108,77 @@ static void stackDump (lua_State *L) {
|
||||
*/
|
||||
static int process_token_string(lua_State* L, jsmntok_t* t, const char* s, int cid)
|
||||
{
|
||||
// unescape a string
|
||||
//const char* search_token[8] = {"\\\\","\\\"","\\n","\\t","\\b","\\f","\\r","\\/"};
|
||||
//const char* replace_token[8] = {"\\","\"","\n","\t","\b","\f","\r","/"};
|
||||
char * str = strndup(s+t[cid].start, t[cid].end-t[cid].start);
|
||||
// un escape the string
|
||||
lua_getglobal(L, "utils");
|
||||
char * str = (char*) malloc(t[cid].end-t[cid].start + 1);
|
||||
int index = 0;
|
||||
char c;
|
||||
uint8_t escape = 0;
|
||||
|
||||
for (int i = t[cid].start; i < t[cid].end; i++)
|
||||
{
|
||||
c = *(s+i);
|
||||
if(c == '\\')
|
||||
{
|
||||
if(escape)
|
||||
{
|
||||
str[index] = c;
|
||||
escape = 0;
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
escape = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(escape)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'b':
|
||||
str[index] = '\b';
|
||||
break;
|
||||
case 'f':
|
||||
str[index] = '\f';
|
||||
break;
|
||||
case 'n':
|
||||
str[index] = '\n';
|
||||
break;
|
||||
case 'r':
|
||||
str[index] = '\r';
|
||||
break;
|
||||
case 't':
|
||||
str[index] = '\t';
|
||||
break;
|
||||
default:
|
||||
str[index] = c;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
str[index] = c;
|
||||
}
|
||||
index++;
|
||||
escape = 0;
|
||||
}
|
||||
}
|
||||
str[index] = '\0';
|
||||
//strndup(s+t[cid].start, t[cid].end-t[cid].start);
|
||||
// un escape the string
|
||||
/*lua_getglobal(L, "utils");
|
||||
lua_getfield(L, -1, "unescape");
|
||||
lua_pushstring(L,str);
|
||||
if (lua_pcall(L, 1, 1, 0) != 0)
|
||||
printf("Error running function `unescape': %s\n",lua_tostring(L, -1));
|
||||
if(str) free(str);
|
||||
str = (char*)luaL_checkstring(L,-1);
|
||||
lua_settop(L, -3);
|
||||
lua_settop(L, -3);*/
|
||||
lua_pushstring(L,str);
|
||||
//stackDump(L);
|
||||
//lua_pushstring(L, str);
|
||||
//printf("%s\n",strndup(s+t[cid].start, t[cid].end-t[cid].start) );
|
||||
if(str) free(str);
|
||||
return cid+1;
|
||||
}
|
||||
static int process_token_primitive(lua_State* L, jsmntok_t* t, const char* s, int cid)
|
||||
@ -177,6 +231,7 @@ static int token_to_object(lua_State *L, jsmntok_t* t, const char* s, int cid)
|
||||
break;
|
||||
|
||||
default:
|
||||
lua_pushnil(L);
|
||||
return cid + t[cid].size; break;
|
||||
|
||||
}
|
||||
@ -191,6 +246,7 @@ static int l_json_parser(lua_State *L, const char* s)
|
||||
int r = jsmn_parse(&p, s, strlen(s), t, sizeof(t)/sizeof(t[0]));
|
||||
if (r < 0) {
|
||||
LOG("Failed to parse JSON: %d\n", r);
|
||||
lua_pushnil(L);
|
||||
return 0;
|
||||
}
|
||||
token_to_object(L,t,s,0);
|
||||
|
200
lib/asl/ulib.c
200
lib/asl/ulib.c
@ -3,11 +3,14 @@
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <shadow.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/sendfile.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
@ -34,7 +37,7 @@ static int l_check_login (lua_State *L) {
|
||||
if (pwd == NULL)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("Cannot find pwd record of %s\n", username );
|
||||
ERROR("Cannot find pwd record of %s", username );
|
||||
return 1;
|
||||
}
|
||||
spwd = getspnam(username);
|
||||
@ -60,25 +63,23 @@ static int l_check_login (lua_State *L) {
|
||||
if (encrypted == NULL)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("Cant crypt \n" );
|
||||
ERROR("Cant crypt %s", strerror(errno) );
|
||||
return 1;
|
||||
}
|
||||
if(strcmp(encrypted, pwd->pw_passwd) == 0)
|
||||
{
|
||||
lua_pushboolean(L,1);
|
||||
printf("%s\n","Successful login" );
|
||||
return 1;
|
||||
} else
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
printf("Password incorrect \n" );
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
// macos
|
||||
// just pass the check, for test only
|
||||
lua_pushboolean(L,1);
|
||||
printf("%s\n","Successful login" );
|
||||
lua_pushboolean(L,0);
|
||||
ERROR("Login by shadow passd is not supported on this system");
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
@ -114,6 +115,7 @@ static int l_fork(lua_State* L)
|
||||
lua_pushnumber(L, pid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_waitpid(lua_State* L)
|
||||
{
|
||||
int pid = luaL_checknumber(L,1);
|
||||
@ -135,7 +137,7 @@ static int l_kill(lua_State* L)
|
||||
{
|
||||
int pid = luaL_checknumber(L,1);
|
||||
if(pid == -1) pid = getpid();
|
||||
int status = kill(pid, SIGKILL);
|
||||
int status = kill(pid, SIGHUP);
|
||||
lua_pushnumber(L, status);
|
||||
return 1;
|
||||
}
|
||||
@ -144,9 +146,9 @@ static int l_setuid(lua_State* L)
|
||||
uid_t uid = (uid_t) luaL_checknumber(L,1);
|
||||
if((int)uid != -1)
|
||||
{
|
||||
if(seteuid(uid) < 0)
|
||||
if(setuid(uid) < 0)
|
||||
{
|
||||
printf("UID set problem: %s\n", strerror(errno));
|
||||
ERROR("UID set problem: %s", strerror(errno));
|
||||
lua_pushboolean(L,0);
|
||||
}
|
||||
else
|
||||
@ -164,9 +166,9 @@ static int l_setgid(lua_State* L)
|
||||
uid_t gid = (uid_t) luaL_checknumber(L,1);
|
||||
if((int)gid != -1)
|
||||
{
|
||||
if(setegid(gid) < 0)
|
||||
if(setgid(gid) < 0)
|
||||
{
|
||||
printf("GID set problem: %s\n", strerror(errno));
|
||||
ERROR("GID set problem: %s", strerror(errno));
|
||||
lua_pushboolean(L,0);
|
||||
}
|
||||
else
|
||||
@ -179,6 +181,13 @@ static int l_setgid(lua_State* L)
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
static int l_syslog(lua_State* L)
|
||||
{
|
||||
const int prio = luaL_checknumber(L,1);
|
||||
const char* msg = luaL_checkstring(L,2);
|
||||
syslog(prio, "%s", msg);
|
||||
return 1;
|
||||
}
|
||||
static int l_getuid(lua_State* L)
|
||||
{
|
||||
const char* name = luaL_checkstring(L,1);
|
||||
@ -204,12 +213,12 @@ static int l_getuid(lua_State* L)
|
||||
/* Retrieve group list */
|
||||
groups = malloc(ngroups * sizeof (gid_t));
|
||||
if (groups == NULL) {
|
||||
LOG("malloc eror \n");
|
||||
LOG("malloc eror");
|
||||
return 1;
|
||||
}
|
||||
if (getgrouplist(name, gid, groups, &ngroups) == -1) {
|
||||
free(groups);
|
||||
LOG("getgrouplist() returned -1; ngroups = %d\n", ngroups);
|
||||
LOG("getgrouplist() returned -1; ngroups = %d", ngroups);
|
||||
return 1;
|
||||
}
|
||||
/* retrieved groups, along with group names */
|
||||
@ -255,13 +264,13 @@ static int l_file_stat(lua_State* L, const char* path)
|
||||
|
||||
//ctime
|
||||
lua_pushstring(L,"ctime");
|
||||
strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S", localtime(&(st.st_ctime)));
|
||||
timestr(st.st_ctime,date,sizeof(date),"%a, %d %b %Y %H:%M:%S GMT",1);
|
||||
lua_pushstring(L,date);
|
||||
lua_settable(L,-3);
|
||||
//mtime
|
||||
|
||||
lua_pushstring(L,"mtime");
|
||||
strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S", localtime(&(st.st_mtime)));
|
||||
timestr(st.st_mtime,date,sizeof(date),"%a, %d %b %Y %H:%M:%S GMT",1);
|
||||
lua_pushstring(L,date);
|
||||
lua_settable(L,-3);
|
||||
|
||||
@ -369,6 +378,87 @@ static int l_file_move(lua_State* L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_send_file(lua_State* L)
|
||||
{
|
||||
int fromfd, tofd, ret;
|
||||
size_t sz = 0;
|
||||
char* old = NULL;
|
||||
char* new = NULL;
|
||||
if(lua_isnumber(L,1))
|
||||
{
|
||||
fromfd = (int)luaL_checknumber(L,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
old = (char*)luaL_checkstring(L,1);
|
||||
if((fromfd = open(old, O_RDONLY)) < 0)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
goto end_send_file;
|
||||
}
|
||||
struct stat st;
|
||||
if(stat(old, &st)!=0)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
goto end_send_file;
|
||||
}
|
||||
sz = st.st_size;
|
||||
}
|
||||
if(lua_isnumber(L,2))
|
||||
{
|
||||
tofd = (int) luaL_checknumber(L,2);
|
||||
}
|
||||
else
|
||||
{
|
||||
new = (char*)luaL_checkstring(L,2);
|
||||
if (unlink(new) < 0 && errno != ENOENT) {
|
||||
lua_pushboolean(L,0);
|
||||
goto end_send_file;
|
||||
}
|
||||
if((tofd = open(new, O_WRONLY | O_CREAT, 0600)) < 0)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
goto end_send_file;
|
||||
}
|
||||
}
|
||||
|
||||
if(lua_isnumber(L,3))
|
||||
{
|
||||
sz = (size_t) luaL_checknumber(L,3);
|
||||
}
|
||||
|
||||
off_t off = 0;
|
||||
int read = 0;
|
||||
while (
|
||||
sz > 0 &&
|
||||
read != sz &&
|
||||
(
|
||||
((ret = sendfile(tofd, fromfd, &off, sz - read)) >= 0) ||
|
||||
(errno == EAGAIN)
|
||||
)
|
||||
)
|
||||
{
|
||||
if(ret < 0) ret = 0;
|
||||
read += ret;
|
||||
}
|
||||
if(read != sz)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
goto end_send_file;
|
||||
}
|
||||
lua_pushboolean(L,1);
|
||||
end_send_file:
|
||||
if(fromfd >= 0 && old)
|
||||
{
|
||||
(void) close(fromfd);
|
||||
}
|
||||
if(tofd >= 0 && new)
|
||||
{
|
||||
(void) close(tofd);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_read_dir(lua_State* L)
|
||||
{
|
||||
const char* path = luaL_checkstring(L,1);
|
||||
@ -621,6 +711,80 @@ static int l_zip(lua_State* L)
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
static int l_getenv(lua_State* L)
|
||||
{
|
||||
const char* name = luaL_checkstring(L,1);
|
||||
if(!name)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
char * value = getenv(name);
|
||||
lua_pushstring(L, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_setenv(lua_State* L)
|
||||
{
|
||||
const char* name = luaL_checkstring(L,1);
|
||||
const char* value = luaL_checkstring(L,2);
|
||||
const int force = luaL_checknumber(L,3);
|
||||
if(!name)
|
||||
{
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
if(!value)
|
||||
{
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
int ret = setenv(name, value, force);
|
||||
if(ret != 0)
|
||||
{
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_unsetenv(lua_State* L)
|
||||
{
|
||||
const char* name = luaL_checkstring(L,1);
|
||||
if(!name)
|
||||
{
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
int ret = unsetenv(name);
|
||||
if(ret != 0)
|
||||
{
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_gethomedir(lua_State* L)
|
||||
{
|
||||
uid_t uid = (uid_t) luaL_checknumber(L,1);
|
||||
if(uid < 0)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
|
||||
if (pw == NULL) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushstring(L, pw->pw_dir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg _lib [] = {
|
||||
{"auth", l_check_login},
|
||||
@ -642,6 +806,12 @@ static const struct luaL_Reg _lib [] = {
|
||||
{"move",l_file_move},
|
||||
{"unzip",l_unzip},
|
||||
{"zip",l_zip},
|
||||
{"getenv",l_getenv},
|
||||
{"setenv",l_setenv},
|
||||
{"unsetenv",l_unsetenv},
|
||||
{"home_dir",l_gethomedir},
|
||||
{"send_file", l_send_file},
|
||||
{"syslog", l_syslog},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
|
617
lib/asl/wurl.c
617
lib/asl/wurl.c
@ -1,617 +0,0 @@
|
||||
#include<stdio.h> //printf
|
||||
#include<string.h> //memset
|
||||
#include<stdlib.h> //for exit(0);
|
||||
#include<errno.h> //For errno - the error number
|
||||
#include<netdb.h> //hostent
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
//#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <resolv.h>
|
||||
#include <errno.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "../lualib.h"
|
||||
//#include "../../lua-api.h"
|
||||
#include <antd/utils.h>
|
||||
|
||||
#define CLIENT_NAME "wurl"
|
||||
#define CLIENT_HOST "192.168.9.249"
|
||||
#define CONN_TIME_OUT_S 3
|
||||
#define MAX_BUFF 1024
|
||||
#define REQUEST_BOUNDARY "------wURLFormBoundaryVo4QYVaSVseFNpeK"
|
||||
#define GET 0
|
||||
#define POST 1
|
||||
typedef struct{
|
||||
int type; // POST(1) or GET(0)
|
||||
char* resource; // path
|
||||
char* ctype; // content type, used by POST
|
||||
int clen; // content length, used by POST
|
||||
unsigned char* data ;
|
||||
} wurl_header_t;
|
||||
|
||||
/*get the ip by hostname*/
|
||||
int wurl_ip_from_hostname(const char * hostname , char* ip)
|
||||
{
|
||||
struct hostent *he;
|
||||
struct in_addr **addr_list;
|
||||
int i;
|
||||
if ( (he = gethostbyname( hostname ) ) == NULL)
|
||||
{
|
||||
// get the host info
|
||||
herror("gethostbyname");
|
||||
return -1;
|
||||
}
|
||||
addr_list = (struct in_addr **) he->h_addr_list;
|
||||
|
||||
for(i = 0; addr_list[i] != NULL; i++)
|
||||
{
|
||||
//Return the first one;
|
||||
strcpy(ip , inet_ntoa(*addr_list[i]) );
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
send a request
|
||||
*/
|
||||
int wurl_request_socket(const char* ip, int port)
|
||||
{
|
||||
int sockfd;
|
||||
struct sockaddr_in dest;
|
||||
|
||||
// time out setting
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = CONN_TIME_OUT_S;
|
||||
timeout.tv_usec = 0;
|
||||
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
|
||||
{
|
||||
perror("Socket");
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
|
||||
perror("setsockopt failed\n");
|
||||
|
||||
if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
|
||||
perror("setsockopt failed\n");
|
||||
|
||||
bzero(&dest, sizeof(dest));
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_port = htons(port);
|
||||
if ( inet_aton(ip, &dest.sin_addr) == 0 )
|
||||
{
|
||||
perror(ip);
|
||||
close(sockfd);
|
||||
return -1;
|
||||
}
|
||||
if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 )
|
||||
{
|
||||
close(sockfd);
|
||||
perror("Connect");
|
||||
return -1;
|
||||
}
|
||||
return sockfd;
|
||||
}
|
||||
/*
|
||||
POST %s HTTP/1.0\r\n
|
||||
Host: %s\r\n
|
||||
User-Agent: %s\r\n
|
||||
Content-Type: %s\r\n
|
||||
Content-Length: %d\r\n\r\n"
|
||||
|
||||
maybe cookie support? this can cause security problem
|
||||
|
||||
GET %s HTTP/1.0\r\n
|
||||
Host: %s\r\n
|
||||
User-Agent: %s\r\n\r\n"
|
||||
|
||||
multipart
|
||||
POST %s HTTP/1.1
|
||||
Host: %s
|
||||
User-Agent: %s
|
||||
Content-Type: multipart/form-data; boundary=----------287032381131322
|
||||
Content-Length: %d
|
||||
|
||||
------------287032381131322
|
||||
Content-Disposition: form-data; name="datafile1"; filename="r.gif"
|
||||
Content-Type: image/gif
|
||||
|
||||
GIF87a.............,...........D..;
|
||||
------------287032381131322
|
||||
Content-Disposition: form-data; name="datafile2"; filename="g.gif"
|
||||
Content-Type: image/gif
|
||||
|
||||
GIF87a.............,...........D..;
|
||||
------------287032381131322
|
||||
Content-Disposition: form-data; name="datafile3"; filename="b.gif"
|
||||
Content-Type: image/gif
|
||||
|
||||
GIF87a.............,...........D..;
|
||||
------------287032381131322--
|
||||
*/
|
||||
|
||||
int wurl_header(int sockfd, wurl_header_t rq)
|
||||
{
|
||||
char buff[MAX_BUFF];
|
||||
if(sockfd < 0) return -1;
|
||||
|
||||
if(rq.type == GET) // GET
|
||||
{
|
||||
send(sockfd,"GET ",4,0);
|
||||
send(sockfd,rq.resource, strlen(rq.resource),0);
|
||||
send(sockfd," HTTP/1.0\r\n",11,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
send(sockfd,"POST ",5, 0);
|
||||
send(sockfd,rq.resource, strlen(rq.resource),0);
|
||||
send(sockfd," HTTP/1.0\r\n",11,0);
|
||||
sprintf(buff,"Content-Type: %s\r\n", rq.ctype);
|
||||
send(sockfd,buff,strlen(buff),0);
|
||||
sprintf(buff,"Content-Length: %d\r\n", rq.clen);
|
||||
send(sockfd,buff,strlen(buff),0);
|
||||
}
|
||||
// host dont need to send the host
|
||||
//sprintf(buff,"Host: %s\r\n",CLIENT_HOST);
|
||||
//send(sockfd,buff,strlen(buff),0);
|
||||
// user agent
|
||||
sprintf(buff,"User-Agent: %s\r\n",CLIENT_NAME);
|
||||
send(sockfd,buff,strlen(buff),0);
|
||||
// terminate request
|
||||
send(sockfd,"\r\n",2,0);
|
||||
|
||||
// if there is data, send out
|
||||
if(rq.type == POST && rq.data)
|
||||
{
|
||||
send(sockfd,rq.data,rq.clen,0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
send multiple files to server
|
||||
using multipart/form-data
|
||||
*/
|
||||
|
||||
void wurl_send_files(int sockfd,char* resource, int n, char* name [], char* files[])
|
||||
{
|
||||
char buff[MAX_BUFF];
|
||||
wurl_header_t rq;
|
||||
rq.type = POST;
|
||||
rq.resource = resource;
|
||||
// get the total size of data
|
||||
int totalsize = 0;
|
||||
FILE* fd;
|
||||
struct stat st;
|
||||
for(int i = 0; i < n; ++i)
|
||||
{
|
||||
if(stat(files[i], &st) != 0) continue;
|
||||
totalsize += st.st_size;
|
||||
}
|
||||
rq.clen = totalsize;
|
||||
sprintf(buff,"%s; boundary=%s","multipart/form-data",REQUEST_BOUNDARY);
|
||||
rq.ctype = buff;
|
||||
|
||||
// now send the header
|
||||
wurl_header(sockfd,rq);
|
||||
// now send the files
|
||||
size_t size;
|
||||
for(int i = 0; i < n; ++i)
|
||||
{
|
||||
fd = fopen(files[i],"rb");
|
||||
if(!fd) continue;
|
||||
// first send the boundary
|
||||
//printf("sending file %s name:%s\n", files[i],name[i]);
|
||||
sprintf(buff,"%s\r\n",REQUEST_BOUNDARY);
|
||||
send(sockfd, buff, strlen(buff),0);
|
||||
// content disposition
|
||||
sprintf(buff,"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",
|
||||
name[i],basename(files[i]));
|
||||
send(sockfd,buff, strlen(buff),0);
|
||||
// content type
|
||||
sprintf(buff,"Content-Type: %s\r\n\r\n",mime(files[i]));
|
||||
send(sockfd,buff, strlen(buff),0);
|
||||
// now send the file
|
||||
while(!feof(fd))
|
||||
{
|
||||
size = fread(buff,1,MAX_BUFF,fd);
|
||||
send(sockfd,buff,size,0);
|
||||
//if(!__b(client,buffer,size)) return;
|
||||
}
|
||||
fclose(fd);
|
||||
send(sockfd,"\r\n",2,0);
|
||||
}
|
||||
//end the boudary
|
||||
sprintf(buff,"%s--\r\n",REQUEST_BOUNDARY);
|
||||
send(sockfd,buff,strlen(buff),0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the socket request in to a buffer or size
|
||||
* The data is read until the buffer is full or
|
||||
* there are a carrier return character
|
||||
* @param sock socket
|
||||
* @param buf buffer
|
||||
* @param size size of buffer
|
||||
* @return number of bytes read
|
||||
*/
|
||||
int wurl_read_buf(int sock, char*buf,int size)
|
||||
{
|
||||
int i = 0;
|
||||
char c = '\0';
|
||||
int n;
|
||||
while ((i < size - 1) && (c != '\n'))
|
||||
{
|
||||
n = recv(sock, &c, 1, 0);
|
||||
if (n > 0)
|
||||
{
|
||||
buf[i] = c;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
c = '\n';
|
||||
}
|
||||
buf[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
/*
|
||||
POST example
|
||||
wurl_header_t rq;
|
||||
rq.resource = path;
|
||||
rq.type = POST;
|
||||
rq.data = "s=a&q=b#test";//"{\"name\":\"sang\"}";
|
||||
rq.clen = strlen(rq.data);
|
||||
rq.ctype = "application/x-www-form-urlencoded";//"application/json";
|
||||
|
||||
if(wurl_request(hostname,port,&rq,1) == 0)
|
||||
{
|
||||
printf(rq.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot connect to host\n");
|
||||
}
|
||||
|
||||
DOWNLOAD
|
||||
wurl_header_t rq;
|
||||
rq.resource = path;
|
||||
rq.type = GET;
|
||||
|
||||
if(wurl_download(hostname,port,&rq,file) == 0)
|
||||
{
|
||||
printf("Download sucess ful\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot connect to host\n");
|
||||
}
|
||||
|
||||
|
||||
upload example
|
||||
// send files
|
||||
char * names[2];
|
||||
names[0] = "zip";
|
||||
names[1] = "text";
|
||||
char* files[2];
|
||||
files[0] = "/Users/mrsang/tmp/Archive.zip";
|
||||
files[1] = "/Users/mrsang/tmp/test.py";
|
||||
|
||||
wurl_send_files(sock,path,2,names, files);
|
||||
printf("RETURN:\n");
|
||||
size = wurl_read_buf(sock,buff, MAX_BUFF);
|
||||
while(size > 0)
|
||||
{
|
||||
printf("%s", buff);
|
||||
size = wurl_read_buf(sock,buff, MAX_BUFF);
|
||||
}
|
||||
close(sock);
|
||||
*/
|
||||
void wurl_response_header(int sock, wurl_header_t* header)
|
||||
{
|
||||
char buff[MAX_BUFF];
|
||||
int size = wurl_read_buf(sock,buff,MAX_BUFF);
|
||||
char* token;
|
||||
while (size > 0 && strcmp("\r\n",buff))
|
||||
{
|
||||
char* line = strdup(buff);
|
||||
//printf("LINE %s\n", line);
|
||||
token = strsep(&line,":");
|
||||
trim(token,' ');
|
||||
if(token != NULL &&strcasecmp(token,"Content-Type") == 0)
|
||||
{
|
||||
header->ctype = strsep(&line,":");
|
||||
trim(header->ctype,' ');
|
||||
trim(header->ctype,'\n');
|
||||
trim(header->ctype,'\r');
|
||||
} else if(token != NULL &&strcasecmp(token,"Content-Length") == 0)
|
||||
{
|
||||
token = strsep(&line,":");
|
||||
trim(token,' ');
|
||||
header->clen = atoi(token);
|
||||
}
|
||||
//if(line) free(line);
|
||||
size = wurl_read_buf(sock,buff,MAX_BUFF);
|
||||
}
|
||||
}
|
||||
int wurl_read_data(int sock,char** din)
|
||||
{
|
||||
// read line by line, ignore content length
|
||||
int total_length = 0;
|
||||
char* tmp = NULL;
|
||||
int CHUNK = 512;
|
||||
char buff[MAX_BUFF];
|
||||
char * data = ( char*) malloc(CHUNK);
|
||||
int cursize = CHUNK;
|
||||
int size = wurl_read_buf(sock,buff,MAX_BUFF);
|
||||
while(size > 0)
|
||||
{
|
||||
if(total_length+size > cursize)
|
||||
{
|
||||
tmp = (char*) realloc(data,total_length + size+ CHUNK );
|
||||
|
||||
if(!tmp)
|
||||
{
|
||||
if(data) free(data);
|
||||
break;
|
||||
}
|
||||
cursize = total_length + size+ CHUNK;
|
||||
data = tmp;
|
||||
}
|
||||
memcpy(data+total_length,buff,size);
|
||||
total_length += size;
|
||||
size = wurl_read_buf(sock,buff,MAX_BUFF);
|
||||
}
|
||||
data[total_length] = '\0';
|
||||
close(sock);
|
||||
*din = data;
|
||||
return total_length;
|
||||
}
|
||||
/*
|
||||
hostname
|
||||
port
|
||||
header for request and respond
|
||||
lazy : if 1, all data is read to the header
|
||||
if 0, user has the responsibility to handler it
|
||||
*/
|
||||
int wurl_request(const char* hostname, int port, wurl_header_t* header, int lazy)
|
||||
{
|
||||
char ip[100];
|
||||
wurl_ip_from_hostname(hostname ,ip);
|
||||
int sock = wurl_request_socket(ip, port);
|
||||
|
||||
if(sock <= 0) return -1;
|
||||
// send header
|
||||
wurl_header(sock,*header);
|
||||
// read respond header
|
||||
wurl_response_header(sock,header);
|
||||
|
||||
if(header->ctype == NULL || header->clen == -1)
|
||||
{
|
||||
LOG("Bad data\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// read data if lazy
|
||||
if(lazy)
|
||||
{
|
||||
// read line by line, ignore content length
|
||||
header->clen = wurl_read_data(sock,(char**)&header->data);
|
||||
return 0;
|
||||
}
|
||||
return sock;
|
||||
}
|
||||
|
||||
int wurl_download(const char* hostname, int port, wurl_header_t* h, const char* to)
|
||||
{
|
||||
// we will handler the data reading
|
||||
int sock = wurl_request(hostname, port,h,0);
|
||||
char buff[MAX_BUFF];
|
||||
if(sock < 0) return -1;
|
||||
|
||||
FILE* fp = fopen(to,"wb");
|
||||
int size;
|
||||
if(fp)
|
||||
{
|
||||
while((size = wurl_read_buf(sock,buff, MAX_BUFF)) > 0)
|
||||
{
|
||||
fwrite(buff, size, 1, fp);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
int main (int argc, char const *argv[])
|
||||
{
|
||||
if(argc < 4)
|
||||
{
|
||||
printf("wurl [host] [port] [path]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *hostname = argv[1];
|
||||
char* path = argv[3];
|
||||
int port = atoi(argv[2]);
|
||||
char*file = argv[4];
|
||||
wurl_header_t rq;
|
||||
rq.resource = path;
|
||||
rq.type = POST;
|
||||
rq.data = "s=a&q=b#test";//"{\"name\":\"sang\"}";
|
||||
rq.clen = strlen(rq.data);
|
||||
rq.ctype = "application/x-www-form-urlencoded";//"application/json";
|
||||
|
||||
if(wurl_download(hostname,port,&rq,file) == 0)
|
||||
{
|
||||
printf("Download sucess ful\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot connect to host\n");
|
||||
}
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
static int l_get(lua_State *L)
|
||||
{
|
||||
const char* host = luaL_checkstring(L,1);
|
||||
int port = luaL_checknumber(L,2);
|
||||
const char* resource = luaL_checkstring(L,3);
|
||||
|
||||
wurl_header_t rq;
|
||||
rq.resource = (char*)resource;
|
||||
rq.type = GET;
|
||||
|
||||
if(wurl_request(host,port,&rq,1) == 0)
|
||||
{
|
||||
//printf("Content type is %s\n", rq.ctype);
|
||||
//mime_t m = mime_from_type(rq.ctype);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"contentType");
|
||||
lua_pushstring(L,rq.ctype);
|
||||
lua_settable(L,-3);
|
||||
|
||||
/*
|
||||
lua_pushstring(L,"binary");
|
||||
lua_pushboolean(L,m.bin);
|
||||
lua_settable(L,-3);*/
|
||||
|
||||
lua_pushstring(L,"data");
|
||||
// byte array, that can be convert to string later
|
||||
lua_new_byte_array(L,rq.clen);
|
||||
byte_array_t* arr = l_check_barray(L,-1);
|
||||
memcpy(arr->data,rq.data,rq.clen);
|
||||
free(rq.data); // be careful
|
||||
lua_settable(L,-3);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
static int l_post(lua_State *L)
|
||||
{
|
||||
const char* host = luaL_checkstring(L,1); // host
|
||||
int port = luaL_checknumber(L,2); // port
|
||||
const char* res = luaL_checkstring(L,3); // resource
|
||||
const char* ctype = luaL_checkstring(L,4); // content type
|
||||
const char* data = luaL_checkstring(L,5); // post data
|
||||
wurl_header_t rq;
|
||||
rq.resource = (char*)res;
|
||||
rq.type = POST;
|
||||
rq.ctype = (char*)ctype;
|
||||
rq.clen = strlen(data);
|
||||
rq.data = (unsigned char*)data;
|
||||
|
||||
if(wurl_request(host,port,&rq,1) == 0)
|
||||
{
|
||||
|
||||
//printf("Content type is %s\n", rq.ctype);
|
||||
mime_t m = mime_from_type(rq.ctype);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"contentType");
|
||||
lua_pushstring(L,rq.ctype);
|
||||
lua_settable(L,-3);
|
||||
|
||||
/*lua_pushstring(L,"binary");
|
||||
lua_pushboolean(L,m.bin);
|
||||
lua_settable(L,-3);
|
||||
*/
|
||||
|
||||
lua_pushstring(L,"data");
|
||||
lua_new_byte_array(L,rq.clen);
|
||||
byte_array_t* arr = l_check_barray(L,-1);
|
||||
memcpy(arr->data,rq.data,rq.clen);
|
||||
free(rq.data); // be careful
|
||||
lua_settable(L,-3);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
static int l_download(lua_State* L)
|
||||
{
|
||||
// we user only GET for down load and POST for upload
|
||||
const char* host = luaL_checkstring(L,1); // host
|
||||
int port = luaL_checknumber(L,2); // port
|
||||
const char* res = luaL_checkstring(L,3); // resource
|
||||
const char* file = luaL_checkstring(L,4); // file
|
||||
wurl_header_t rq;
|
||||
rq.resource = (char*)res;
|
||||
rq.type = GET;
|
||||
if(wurl_download(host,port,&rq,file) == 0)
|
||||
lua_pushboolean(L, true);
|
||||
else
|
||||
lua_pushboolean(L,false);
|
||||
return 1;
|
||||
}
|
||||
static int l_upload(lua_State* L)
|
||||
{
|
||||
const char* host = luaL_checkstring(L,1);
|
||||
int port = luaL_checknumber(L,2);
|
||||
const char* resource = luaL_checkstring(L,3);
|
||||
const char* name = luaL_checkstring(L,4);
|
||||
const char* file = luaL_checkstring(L,5);
|
||||
|
||||
if(!_exist(file)) goto fail;
|
||||
|
||||
// request socket
|
||||
char ip[100];
|
||||
wurl_ip_from_hostname(host ,ip);
|
||||
int sock = wurl_request_socket(ip, port);
|
||||
|
||||
if(sock <= 0) goto fail;
|
||||
|
||||
char * names[2];
|
||||
names[0] = (char*)name;
|
||||
char* files[2];
|
||||
//files[0] = "/Users/mrsang/tmp/Archive.zip";
|
||||
files[0] = (char*)file;
|
||||
|
||||
//printf("SENDIND DILE\n");
|
||||
wurl_send_files(sock, (char*)resource,1,names,files);
|
||||
wurl_header_t header;
|
||||
//printf("READ HEADER\n");
|
||||
wurl_response_header(sock, &header);
|
||||
//printf("read data\n");
|
||||
wurl_read_data(sock,(char**)&header.data);
|
||||
if(header.ctype != NULL && header.data)
|
||||
{
|
||||
lua_pushstring(L,(const char*)header.data);
|
||||
free(header.data);
|
||||
return 1;
|
||||
}
|
||||
fail:
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
static const struct luaL_Reg _lib [] = {
|
||||
{"_get",l_get},
|
||||
{"_post",l_post},
|
||||
{"_download",l_download},
|
||||
{"_upload",l_upload},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
int luaopen_wurl(lua_State *L)
|
||||
{
|
||||
luaL_newlib(L, _lib);
|
||||
return 1;
|
||||
}
|
205
lib/core/lua-5.3.4/Makefile
Normal file
205
lib/core/lua-5.3.4/Makefile
Normal file
@ -0,0 +1,205 @@
|
||||
# Makefile for building Lua
|
||||
# See ../doc/readme.html for installation and customization instructions.
|
||||
|
||||
# == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT =======================
|
||||
|
||||
# Your platform. See PLATS for possible values.
|
||||
PLAT= none
|
||||
|
||||
CC?= gcc -std=gnu99
|
||||
CFLAGS= -O2 -g -Wall -Wextra -DLUA_COMPAT_5_2 -fPIC $(SYSCFLAGS) $(MYCFLAGS)
|
||||
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
|
||||
LIBS= -lm $(SYSLIBS) $(MYLIBS)
|
||||
|
||||
AR?= ar
|
||||
LAR= $(AR) rcu
|
||||
RANLIB?= ranlib
|
||||
RM= rm -f
|
||||
|
||||
SYSCFLAGS=
|
||||
SYSLDFLAGS=
|
||||
SYSLIBS=
|
||||
|
||||
MYCFLAGS=
|
||||
MYLDFLAGS=
|
||||
MYLIBS=
|
||||
MYOBJS=
|
||||
|
||||
# == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE =======
|
||||
|
||||
PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
|
||||
LUA_SO = core.so
|
||||
LUA_A= liblua.a
|
||||
CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
|
||||
lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
|
||||
ltm.o lundump.o lvm.o lzio.o
|
||||
LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
|
||||
lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
|
||||
BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
|
||||
|
||||
LUA_T= lua
|
||||
LUA_O= lua.o
|
||||
|
||||
LUAC_T= luac
|
||||
LUAC_O= luac.o
|
||||
|
||||
ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
|
||||
ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)
|
||||
ALL_A= $(LUA_A) $(LUA_SO)
|
||||
|
||||
# Targets start here.
|
||||
default: $(PLAT)
|
||||
|
||||
all: $(ALL_T)
|
||||
|
||||
o: $(ALL_O)
|
||||
|
||||
a: $(ALL_A)
|
||||
|
||||
$(LUA_A): $(BASE_O)
|
||||
$(LAR) $@ $(BASE_O)
|
||||
$(RANLIB) $@
|
||||
|
||||
$(LUA_SO): $(BASE_O)
|
||||
$(CC) -shared $(BASE_O) -o $@ -ldl -lm
|
||||
|
||||
$(LUA_T): $(LUA_O) $(LUA_A)
|
||||
$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
|
||||
|
||||
$(LUAC_T): $(LUAC_O) $(LUA_A)
|
||||
$(CC) -o $@ $(LDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
|
||||
|
||||
clean:
|
||||
$(RM) $(ALL_T) $(ALL_O)
|
||||
|
||||
depend:
|
||||
@$(CC) $(CFLAGS) -MM l*.c
|
||||
|
||||
distdir:
|
||||
|
||||
install:
|
||||
|
||||
echo:
|
||||
@echo "PLAT= $(PLAT)"
|
||||
@echo "CC= $(CC)"
|
||||
@echo "CFLAGS= $(CFLAGS)"
|
||||
@echo "LDFLAGS= $(SYSLDFLAGS)"
|
||||
@echo "LIBS= $(LIBS)"
|
||||
@echo "AR= $(LAR)"
|
||||
@echo "RANLIB= $(RANLIB)"
|
||||
@echo "RM= $(RM)"
|
||||
|
||||
# Convenience targets for popular platforms
|
||||
ALL= all
|
||||
|
||||
none:
|
||||
@echo "Please do 'make PLATFORM' where PLATFORM is one of these:"
|
||||
@echo " $(PLATS)"
|
||||
|
||||
aix:
|
||||
$(MAKE) $(ALL) CC="xlc" CFLAGS="-O2 -DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-ldl" SYSLDFLAGS="-brtl -bexpall"
|
||||
|
||||
bsd:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" SYSLIBS="-Wl,-E"
|
||||
|
||||
c89:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_C89" CC="gcc -std=c89"
|
||||
@echo ''
|
||||
@echo '*** C89 does not guarantee 64-bit integers for Lua.'
|
||||
@echo ''
|
||||
|
||||
|
||||
freebsd:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -lreadline"
|
||||
|
||||
generic: $(ALL)
|
||||
|
||||
linux:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
|
||||
|
||||
macosx:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc
|
||||
|
||||
mingw:
|
||||
$(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \
|
||||
"AR=$(CC) -shared -o" "RANLIB=strip --strip-unneeded" \
|
||||
"SYSCFLAGS=-DLUA_BUILD_AS_DLL" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe
|
||||
$(MAKE) "LUAC_T=luac.exe" luac.exe
|
||||
|
||||
posix:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX"
|
||||
|
||||
solaris:
|
||||
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN -D_REENTRANT" SYSLIBS="-ldl"
|
||||
|
||||
# list targets that do not create files (but not all makes understand .PHONY)
|
||||
.PHONY: all $(PLATS) default o a clean depend echo none
|
||||
|
||||
# DO NOT DELETE
|
||||
|
||||
lapi.o: lapi.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lstring.h \
|
||||
ltable.h lundump.h lvm.h
|
||||
lauxlib.o: lauxlib.c lprefix.h lua.h luaconf.h lauxlib.h
|
||||
lbaselib.o: lbaselib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
lbitlib.o: lbitlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
lcode.o: lcode.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
|
||||
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
|
||||
ldo.h lgc.h lstring.h ltable.h lvm.h
|
||||
lcorolib.o: lcorolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
lctype.o: lctype.c lprefix.h lctype.h lua.h luaconf.h llimits.h
|
||||
ldblib.o: ldblib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
ldebug.o: ldebug.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
lobject.h ltm.h lzio.h lmem.h lcode.h llex.h lopcodes.h lparser.h \
|
||||
ldebug.h ldo.h lfunc.h lstring.h lgc.h ltable.h lvm.h
|
||||
ldo.o: ldo.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h lopcodes.h \
|
||||
lparser.h lstring.h ltable.h lundump.h lvm.h
|
||||
ldump.o: ldump.c lprefix.h lua.h luaconf.h lobject.h llimits.h lstate.h \
|
||||
ltm.h lzio.h lmem.h lundump.h
|
||||
lfunc.o: lfunc.c lprefix.h lua.h luaconf.h lfunc.h lobject.h llimits.h \
|
||||
lgc.h lstate.h ltm.h lzio.h lmem.h
|
||||
lgc.o: lgc.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lstring.h ltable.h
|
||||
linit.o: linit.c lprefix.h lua.h luaconf.h lualib.h lauxlib.h
|
||||
liolib.o: liolib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
llex.o: llex.c lprefix.h lua.h luaconf.h lctype.h llimits.h ldebug.h \
|
||||
lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lgc.h llex.h lparser.h \
|
||||
lstring.h ltable.h
|
||||
lmathlib.o: lmathlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
lmem.o: lmem.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h
|
||||
loadlib.o: loadlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
lobject.o: lobject.c lprefix.h lua.h luaconf.h lctype.h llimits.h \
|
||||
ldebug.h lstate.h lobject.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h \
|
||||
lvm.h
|
||||
lopcodes.o: lopcodes.c lprefix.h lopcodes.h llimits.h lua.h luaconf.h
|
||||
loslib.o: loslib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
lparser.o: lparser.c lprefix.h lua.h luaconf.h lcode.h llex.h lobject.h \
|
||||
llimits.h lzio.h lmem.h lopcodes.h lparser.h ldebug.h lstate.h ltm.h \
|
||||
ldo.h lfunc.h lstring.h lgc.h ltable.h
|
||||
lstate.o: lstate.c lprefix.h lua.h luaconf.h lapi.h llimits.h lstate.h \
|
||||
lobject.h ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h \
|
||||
lstring.h ltable.h
|
||||
lstring.o: lstring.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
|
||||
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
|
||||
lstrlib.o: lstrlib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
ltable.o: ltable.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
llimits.h ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
|
||||
ltablib.o: ltablib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
ltm.o: ltm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
|
||||
lua.o: lua.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
luac.o: luac.c lprefix.h lua.h luaconf.h lauxlib.h lobject.h llimits.h \
|
||||
lstate.h ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
|
||||
lundump.o: lundump.c lprefix.h lua.h luaconf.h ldebug.h lstate.h \
|
||||
lobject.h llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h \
|
||||
lundump.h
|
||||
lutf8lib.o: lutf8lib.c lprefix.h lua.h luaconf.h lauxlib.h lualib.h
|
||||
lvm.o: lvm.c lprefix.h lua.h luaconf.h ldebug.h lstate.h lobject.h \
|
||||
llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h \
|
||||
ltable.h lvm.h
|
||||
lzio.o: lzio.c lprefix.h lua.h luaconf.h llimits.h lmem.h lstate.h \
|
||||
lobject.h ltm.h lzio.h
|
||||
|
||||
# (end of Makefile)
|
@ -20,7 +20,7 @@
|
||||
// add byte array support
|
||||
typedef struct{
|
||||
int size;
|
||||
unsigned char data[1];
|
||||
unsigned char * data;
|
||||
} byte_array_t;
|
||||
|
||||
typedef struct{
|
||||
|
9
lib/md/Makefile.am
Normal file
9
lib/md/Makefile.am
Normal file
@ -0,0 +1,9 @@
|
||||
lib_LTLIBRARIES = md.la
|
||||
md_la_LDFLAGS = -module -avoid-version -shared
|
||||
md_la_SOURCES = md.c md4c/entity.c md4c/md4c.c md4c/md4c-html.c
|
||||
|
||||
|
||||
|
||||
libdir=$(prefix)/lib/lua/
|
||||
|
||||
EXTRA_DIST = md4c/*.h
|
63
lib/md/md.c
Normal file
63
lib/md/md.c
Normal file
@ -0,0 +1,63 @@
|
||||
#include "../lualib.h"
|
||||
#include "md4c/md4c-html.h"
|
||||
|
||||
static void md_process_output(const MD_CHAR *buf, MD_SIZE len, void *udata)
|
||||
{
|
||||
lua_State *L = (lua_State *)udata;
|
||||
lua_pushlstring(L, buf, len);
|
||||
lua_call(L, 1, 0);
|
||||
lua_pushvalue(L, -1);
|
||||
}
|
||||
|
||||
static int l_md_to_html(lua_State *L)
|
||||
{
|
||||
const char *input = luaL_checkstring(L, 1);
|
||||
if (input == NULL)
|
||||
{
|
||||
ERROR("NULL markdown input string");
|
||||
return 0;
|
||||
}
|
||||
if (!lua_isfunction(L, -1))
|
||||
{
|
||||
ERROR("Invalid callback function");
|
||||
return 0;
|
||||
}
|
||||
// duplicate top of the stack
|
||||
lua_pushvalue(L, -1);
|
||||
reset_hd_cnt();
|
||||
if (md_html(input,
|
||||
strlen(input),
|
||||
md_process_output,
|
||||
L,
|
||||
MD_DIALECT_GITHUB |
|
||||
MD_HTML_FLAG_VERBATIM_ENTITIES |
|
||||
MD_FLAG_PERMISSIVEATXHEADERS |
|
||||
MD_FLAG_NOINDENTEDCODEBLOCKS |
|
||||
MD_FLAG_NOHTMLBLOCKS |
|
||||
MD_FLAG_NOHTMLSPANS |
|
||||
MD_FLAG_NOHTML |
|
||||
MD_FLAG_COLLAPSEWHITESPACE |
|
||||
MD_FLAG_PERMISSIVEURLAUTOLINKS |
|
||||
MD_FLAG_PERMISSIVEWWWAUTOLINKS |
|
||||
MD_FLAG_PERMISSIVEEMAILAUTOLINKS |
|
||||
MD_FLAG_PERMISSIVEAUTOLINKS |
|
||||
MD_FLAG_UNDERLINE,
|
||||
MD_HTML_FLAG_XHTML) == -1)
|
||||
{
|
||||
ERROR("Unable to parse markdown: md_parse() fails");
|
||||
lua_pop(L,1);
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg _lib[] = {
|
||||
{"to_html", l_md_to_html},
|
||||
{NULL, NULL}};
|
||||
|
||||
int luaopen_md(lua_State *L)
|
||||
{
|
||||
luaL_newlib(L, _lib);
|
||||
return 1;
|
||||
}
|
2190
lib/md/md4c/entity.c
Normal file
2190
lib/md/md4c/entity.c
Normal file
File diff suppressed because it is too large
Load Diff
42
lib/md/md4c/entity.h
Normal file
42
lib/md/md4c/entity.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MD4C: Markdown parser for C
|
||||
* (http://github.com/mity/md4c)
|
||||
*
|
||||
* Copyright (c) 2016-2019 Martin Mitas
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MD4C_ENTITY_H
|
||||
#define MD4C_ENTITY_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/* Most entities are formed by single Unicode codepoint, few by two codepoints.
|
||||
* Single-codepoint entities have codepoints[1] set to zero. */
|
||||
struct entity {
|
||||
const char* name;
|
||||
unsigned codepoints[2];
|
||||
};
|
||||
|
||||
const struct entity* entity_lookup(const char* name, size_t name_size);
|
||||
|
||||
|
||||
#endif /* MD4C_ENTITY_H */
|
750
lib/md/md4c/md4c-html.c
Normal file
750
lib/md/md4c/md4c-html.c
Normal file
@ -0,0 +1,750 @@
|
||||
/*
|
||||
* MD4C: Markdown parser for C
|
||||
* (http://github.com/mity/md4c)
|
||||
*
|
||||
* Copyright (c) 2016-2019 Martin Mitas
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "md4c-html.h"
|
||||
#include "entity.h"
|
||||
|
||||
static int hd_cnt[6] = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199409L
|
||||
/* C89/90 or old compilers in general may not understand "inline". */
|
||||
#if defined __GNUC__
|
||||
#define inline __inline__
|
||||
#elif defined _MSC_VER
|
||||
#define inline __inline
|
||||
#else
|
||||
#define inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
typedef struct MD_HTML_tag MD_HTML;
|
||||
struct MD_HTML_tag
|
||||
{
|
||||
void (*process_output)(const MD_CHAR *, MD_SIZE, void *);
|
||||
void *userdata;
|
||||
unsigned flags;
|
||||
int image_nesting_level;
|
||||
char escape_map[256];
|
||||
};
|
||||
|
||||
#define NEED_HTML_ESC_FLAG 0x1
|
||||
#define NEED_URL_ESC_FLAG 0x2
|
||||
|
||||
/*****************************************
|
||||
*** HTML rendering helper functions ***
|
||||
*****************************************/
|
||||
|
||||
#define ISDIGIT(ch) ('0' <= (ch) && (ch) <= '9')
|
||||
#define ISLOWER(ch) ('a' <= (ch) && (ch) <= 'z')
|
||||
#define ISUPPER(ch) ('A' <= (ch) && (ch) <= 'Z')
|
||||
#define ISALNUM(ch) (ISLOWER(ch) || ISUPPER(ch) || ISDIGIT(ch))
|
||||
|
||||
static inline void
|
||||
render_verbatim(MD_HTML *r, const MD_CHAR *text, MD_SIZE size)
|
||||
{
|
||||
r->process_output(text, size, r->userdata);
|
||||
}
|
||||
|
||||
/* Keep this as a macro. Most compiler should then be smart enough to replace
|
||||
* the strlen() call with a compile-time constant if the string is a C literal. */
|
||||
#define RENDER_VERBATIM(r, verbatim) \
|
||||
render_verbatim((r), (verbatim), (MD_SIZE)(strlen(verbatim)))
|
||||
|
||||
static void
|
||||
render_html_escaped(MD_HTML *r, const MD_CHAR *data, MD_SIZE size)
|
||||
{
|
||||
MD_OFFSET beg = 0;
|
||||
MD_OFFSET off = 0;
|
||||
|
||||
/* Some characters need to be escaped in normal HTML text. */
|
||||
#define NEED_HTML_ESC(ch) (r->escape_map[(unsigned char)(ch)] & NEED_HTML_ESC_FLAG)
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* Optimization: Use some loop unrolling. */
|
||||
while (off + 3 < size && !NEED_HTML_ESC(data[off + 0]) && !NEED_HTML_ESC(data[off + 1]) && !NEED_HTML_ESC(data[off + 2]) && !NEED_HTML_ESC(data[off + 3]))
|
||||
off += 4;
|
||||
while (off < size && !NEED_HTML_ESC(data[off]))
|
||||
off++;
|
||||
|
||||
if (off > beg)
|
||||
render_verbatim(r, data + beg, off - beg);
|
||||
|
||||
if (off < size)
|
||||
{
|
||||
switch (data[off])
|
||||
{
|
||||
case '&':
|
||||
RENDER_VERBATIM(r, "&");
|
||||
break;
|
||||
case '<':
|
||||
RENDER_VERBATIM(r, "<");
|
||||
break;
|
||||
case '>':
|
||||
RENDER_VERBATIM(r, ">");
|
||||
break;
|
||||
case '"':
|
||||
RENDER_VERBATIM(r, """);
|
||||
break;
|
||||
}
|
||||
off++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
beg = off;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
render_url_escaped(MD_HTML *r, const MD_CHAR *data, MD_SIZE size)
|
||||
{
|
||||
static const MD_CHAR hex_chars[] = "0123456789ABCDEF";
|
||||
MD_OFFSET beg = 0;
|
||||
MD_OFFSET off = 0;
|
||||
|
||||
/* Some characters need to be escaped in URL attributes. */
|
||||
#define NEED_URL_ESC(ch) (r->escape_map[(unsigned char)(ch)] & NEED_URL_ESC_FLAG)
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (off < size && !NEED_URL_ESC(data[off]))
|
||||
off++;
|
||||
if (off > beg)
|
||||
render_verbatim(r, data + beg, off - beg);
|
||||
|
||||
if (off < size)
|
||||
{
|
||||
char hex[3];
|
||||
|
||||
switch (data[off])
|
||||
{
|
||||
case '&':
|
||||
RENDER_VERBATIM(r, "&");
|
||||
break;
|
||||
default:
|
||||
hex[0] = '%';
|
||||
hex[1] = hex_chars[((unsigned)data[off] >> 4) & 0xf];
|
||||
hex[2] = hex_chars[((unsigned)data[off] >> 0) & 0xf];
|
||||
render_verbatim(r, hex, 3);
|
||||
break;
|
||||
}
|
||||
off++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
beg = off;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
hex_val(char ch)
|
||||
{
|
||||
if ('0' <= ch && ch <= '9')
|
||||
return ch - '0';
|
||||
if ('A' <= ch && ch <= 'Z')
|
||||
return ch - 'A' + 10;
|
||||
else
|
||||
return ch - 'a' + 10;
|
||||
}
|
||||
|
||||
static void
|
||||
render_utf8_codepoint(MD_HTML *r, unsigned codepoint,
|
||||
void (*fn_append)(MD_HTML *, const MD_CHAR *, MD_SIZE))
|
||||
{
|
||||
static const MD_CHAR utf8_replacement_char[] = {0xef, 0xbf, 0xbd};
|
||||
|
||||
unsigned char utf8[4];
|
||||
size_t n;
|
||||
|
||||
if (codepoint <= 0x7f)
|
||||
{
|
||||
n = 1;
|
||||
utf8[0] = codepoint;
|
||||
}
|
||||
else if (codepoint <= 0x7ff)
|
||||
{
|
||||
n = 2;
|
||||
utf8[0] = 0xc0 | ((codepoint >> 6) & 0x1f);
|
||||
utf8[1] = 0x80 + ((codepoint >> 0) & 0x3f);
|
||||
}
|
||||
else if (codepoint <= 0xffff)
|
||||
{
|
||||
n = 3;
|
||||
utf8[0] = 0xe0 | ((codepoint >> 12) & 0xf);
|
||||
utf8[1] = 0x80 + ((codepoint >> 6) & 0x3f);
|
||||
utf8[2] = 0x80 + ((codepoint >> 0) & 0x3f);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 4;
|
||||
utf8[0] = 0xf0 | ((codepoint >> 18) & 0x7);
|
||||
utf8[1] = 0x80 + ((codepoint >> 12) & 0x3f);
|
||||
utf8[2] = 0x80 + ((codepoint >> 6) & 0x3f);
|
||||
utf8[3] = 0x80 + ((codepoint >> 0) & 0x3f);
|
||||
}
|
||||
|
||||
if (0 < codepoint && codepoint <= 0x10ffff)
|
||||
fn_append(r, (char *)utf8, n);
|
||||
else
|
||||
fn_append(r, utf8_replacement_char, 3);
|
||||
}
|
||||
|
||||
/* Translate entity to its UTF-8 equivalent, or output the verbatim one
|
||||
* if such entity is unknown (or if the translation is disabled). */
|
||||
static void
|
||||
render_entity(MD_HTML *r, const MD_CHAR *text, MD_SIZE size,
|
||||
void (*fn_append)(MD_HTML *, const MD_CHAR *, MD_SIZE))
|
||||
{
|
||||
if (r->flags & MD_HTML_FLAG_VERBATIM_ENTITIES)
|
||||
{
|
||||
render_verbatim(r, text, size);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We assume UTF-8 output is what is desired. */
|
||||
if (size > 3 && text[1] == '#')
|
||||
{
|
||||
unsigned codepoint = 0;
|
||||
|
||||
if (text[2] == 'x' || text[2] == 'X')
|
||||
{
|
||||
/* Hexadecimal entity (e.g. "�")). */
|
||||
MD_SIZE i;
|
||||
for (i = 3; i < size - 1; i++)
|
||||
codepoint = 16 * codepoint + hex_val(text[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Decimal entity (e.g. "&1234;") */
|
||||
MD_SIZE i;
|
||||
for (i = 2; i < size - 1; i++)
|
||||
codepoint = 10 * codepoint + (text[i] - '0');
|
||||
}
|
||||
|
||||
render_utf8_codepoint(r, codepoint, fn_append);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Named entity (e.g. " "). */
|
||||
const struct entity *ent;
|
||||
|
||||
ent = entity_lookup(text, size);
|
||||
if (ent != NULL)
|
||||
{
|
||||
render_utf8_codepoint(r, ent->codepoints[0], fn_append);
|
||||
if (ent->codepoints[1])
|
||||
render_utf8_codepoint(r, ent->codepoints[1], fn_append);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fn_append(r, text, size);
|
||||
}
|
||||
|
||||
static void
|
||||
render_attribute(MD_HTML *r, const MD_ATTRIBUTE *attr,
|
||||
void (*fn_append)(MD_HTML *, const MD_CHAR *, MD_SIZE))
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; attr->substr_offsets[i] < attr->size; i++)
|
||||
{
|
||||
MD_TEXTTYPE type = attr->substr_types[i];
|
||||
MD_OFFSET off = attr->substr_offsets[i];
|
||||
MD_SIZE size = attr->substr_offsets[i + 1] - off;
|
||||
const MD_CHAR *text = attr->text + off;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MD_TEXT_NULLCHAR:
|
||||
render_utf8_codepoint(r, 0x0000, render_verbatim);
|
||||
break;
|
||||
case MD_TEXT_ENTITY:
|
||||
render_entity(r, text, size, fn_append);
|
||||
break;
|
||||
default:
|
||||
fn_append(r, text, size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
render_open_ol_block(MD_HTML *r, const MD_BLOCK_OL_DETAIL *det)
|
||||
{
|
||||
char buf[64];
|
||||
|
||||
if (det->start == 1)
|
||||
{
|
||||
RENDER_VERBATIM(r, "<ol>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "<ol start=\"%u\">\n", det->start);
|
||||
RENDER_VERBATIM(r, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
render_open_li_block(MD_HTML *r, const MD_BLOCK_LI_DETAIL *det)
|
||||
{
|
||||
if (det->is_task)
|
||||
{
|
||||
RENDER_VERBATIM(r, "<li class=\"task-list-item\">"
|
||||
"<input type=\"checkbox\" class=\"task-list-item-checkbox\" disabled");
|
||||
if (det->task_mark == 'x' || det->task_mark == 'X')
|
||||
RENDER_VERBATIM(r, " checked");
|
||||
RENDER_VERBATIM(r, ">");
|
||||
}
|
||||
else
|
||||
{
|
||||
RENDER_VERBATIM(r, "<li>");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
render_open_code_block(MD_HTML *r, const MD_BLOCK_CODE_DETAIL *det)
|
||||
{
|
||||
RENDER_VERBATIM(r, "<pre><code");
|
||||
|
||||
/* If known, output the HTML 5 attribute class="language-LANGNAME". */
|
||||
if (det->lang.text != NULL)
|
||||
{
|
||||
RENDER_VERBATIM(r, " class=\"language-");
|
||||
render_attribute(r, &det->lang, render_html_escaped);
|
||||
RENDER_VERBATIM(r, "\"");
|
||||
}
|
||||
|
||||
RENDER_VERBATIM(r, ">");
|
||||
}
|
||||
|
||||
static void
|
||||
render_open_td_block(MD_HTML *r, const MD_CHAR *cell_type, const MD_BLOCK_TD_DETAIL *det)
|
||||
{
|
||||
RENDER_VERBATIM(r, "<");
|
||||
RENDER_VERBATIM(r, cell_type);
|
||||
|
||||
switch (det->align)
|
||||
{
|
||||
case MD_ALIGN_LEFT:
|
||||
RENDER_VERBATIM(r, " align=\"left\">");
|
||||
break;
|
||||
case MD_ALIGN_CENTER:
|
||||
RENDER_VERBATIM(r, " align=\"center\">");
|
||||
break;
|
||||
case MD_ALIGN_RIGHT:
|
||||
RENDER_VERBATIM(r, " align=\"right\">");
|
||||
break;
|
||||
default:
|
||||
RENDER_VERBATIM(r, ">");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
render_open_a_span(MD_HTML *r, const MD_SPAN_A_DETAIL *det)
|
||||
{
|
||||
RENDER_VERBATIM(r, "<a href=\"");
|
||||
render_attribute(r, &det->href, render_url_escaped);
|
||||
|
||||
if (det->title.text != NULL)
|
||||
{
|
||||
RENDER_VERBATIM(r, "\" title=\"");
|
||||
render_attribute(r, &det->title, render_html_escaped);
|
||||
}
|
||||
|
||||
RENDER_VERBATIM(r, "\">");
|
||||
}
|
||||
|
||||
static void
|
||||
render_open_img_span(MD_HTML *r, const MD_SPAN_IMG_DETAIL *det)
|
||||
{
|
||||
RENDER_VERBATIM(r, "<img src=\"");
|
||||
render_attribute(r, &det->src, render_url_escaped);
|
||||
|
||||
RENDER_VERBATIM(r, "\" alt=\"");
|
||||
|
||||
r->image_nesting_level++;
|
||||
}
|
||||
|
||||
static void
|
||||
render_close_img_span(MD_HTML *r, const MD_SPAN_IMG_DETAIL *det)
|
||||
{
|
||||
if (det->title.text != NULL)
|
||||
{
|
||||
RENDER_VERBATIM(r, "\" title=\"");
|
||||
render_attribute(r, &det->title, render_html_escaped);
|
||||
}
|
||||
|
||||
RENDER_VERBATIM(r, (r->flags & MD_HTML_FLAG_XHTML) ? "\" />" : "\">");
|
||||
|
||||
r->image_nesting_level--;
|
||||
}
|
||||
|
||||
static void
|
||||
render_open_wikilink_span(MD_HTML *r, const MD_SPAN_WIKILINK_DETAIL *det)
|
||||
{
|
||||
RENDER_VERBATIM(r, "<x-wikilink data-target=\"");
|
||||
render_attribute(r, &det->target, render_html_escaped);
|
||||
|
||||
RENDER_VERBATIM(r, "\">");
|
||||
}
|
||||
|
||||
/**************************************
|
||||
*** HTML renderer implementation ***
|
||||
**************************************/
|
||||
|
||||
static int
|
||||
enter_block_callback(MD_BLOCKTYPE type, void *detail, void *userdata)
|
||||
{
|
||||
static const MD_CHAR *head[6] = {"<h1>", "<h2>", "<h3>", "<h4>", "<h5>", "<h6>"};
|
||||
MD_HTML *r = (MD_HTML *)userdata;
|
||||
char buf[32];
|
||||
switch (type)
|
||||
{
|
||||
case MD_BLOCK_DOC: /* noop */
|
||||
break;
|
||||
case MD_BLOCK_QUOTE:
|
||||
RENDER_VERBATIM(r, "<blockquote>\n");
|
||||
break;
|
||||
case MD_BLOCK_UL:
|
||||
RENDER_VERBATIM(r, "<ul>\n");
|
||||
break;
|
||||
case MD_BLOCK_OL:
|
||||
render_open_ol_block(r, (const MD_BLOCK_OL_DETAIL *)detail);
|
||||
break;
|
||||
case MD_BLOCK_LI:
|
||||
render_open_li_block(r, (const MD_BLOCK_LI_DETAIL *)detail);
|
||||
break;
|
||||
case MD_BLOCK_HR:
|
||||
RENDER_VERBATIM(r, (r->flags & MD_HTML_FLAG_XHTML) ? "<hr />\n" : "<hr>\n");
|
||||
break;
|
||||
case MD_BLOCK_H:
|
||||
hd_cnt[((MD_BLOCK_H_DETAIL *)detail)->level - 1]++;
|
||||
snprintf(buf, 32, "<a id=\"h%d_%d\"></a>", ((MD_BLOCK_H_DETAIL *)detail)->level, hd_cnt[((MD_BLOCK_H_DETAIL *)detail)->level - 1]);
|
||||
RENDER_VERBATIM(r, buf);
|
||||
RENDER_VERBATIM(r, head[((MD_BLOCK_H_DETAIL *)detail)->level - 1]);
|
||||
break;
|
||||
case MD_BLOCK_CODE:
|
||||
render_open_code_block(r, (const MD_BLOCK_CODE_DETAIL *)detail);
|
||||
break;
|
||||
case MD_BLOCK_HTML: /* noop */
|
||||
break;
|
||||
case MD_BLOCK_P:
|
||||
RENDER_VERBATIM(r, "<p>");
|
||||
break;
|
||||
case MD_BLOCK_TABLE:
|
||||
RENDER_VERBATIM(r, "<table>\n");
|
||||
break;
|
||||
case MD_BLOCK_THEAD:
|
||||
RENDER_VERBATIM(r, "<thead>\n");
|
||||
break;
|
||||
case MD_BLOCK_TBODY:
|
||||
RENDER_VERBATIM(r, "<tbody>\n");
|
||||
break;
|
||||
case MD_BLOCK_TR:
|
||||
RENDER_VERBATIM(r, "<tr>\n");
|
||||
break;
|
||||
case MD_BLOCK_TH:
|
||||
render_open_td_block(r, "th", (MD_BLOCK_TD_DETAIL *)detail);
|
||||
break;
|
||||
case MD_BLOCK_TD:
|
||||
render_open_td_block(r, "td", (MD_BLOCK_TD_DETAIL *)detail);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
leave_block_callback(MD_BLOCKTYPE type, void *detail, void *userdata)
|
||||
{
|
||||
static const MD_CHAR *head[6] = {"</h1>\n", "</h2>\n", "</h3>\n", "</h4>\n", "</h5>\n", "</h6>\n"};
|
||||
MD_HTML *r = (MD_HTML *)userdata;
|
||||
switch (type)
|
||||
{
|
||||
case MD_BLOCK_DOC: /*noop*/
|
||||
break;
|
||||
case MD_BLOCK_QUOTE:
|
||||
RENDER_VERBATIM(r, "</blockquote>\n");
|
||||
break;
|
||||
case MD_BLOCK_UL:
|
||||
RENDER_VERBATIM(r, "</ul>\n");
|
||||
break;
|
||||
case MD_BLOCK_OL:
|
||||
RENDER_VERBATIM(r, "</ol>\n");
|
||||
break;
|
||||
case MD_BLOCK_LI:
|
||||
RENDER_VERBATIM(r, "</li>\n");
|
||||
break;
|
||||
case MD_BLOCK_HR: /*noop*/
|
||||
break;
|
||||
case MD_BLOCK_H:
|
||||
RENDER_VERBATIM(r, head[((MD_BLOCK_H_DETAIL *)detail)->level - 1]);
|
||||
break;
|
||||
case MD_BLOCK_CODE:
|
||||
RENDER_VERBATIM(r, "</code></pre>\n");
|
||||
break;
|
||||
case MD_BLOCK_HTML: /* noop */
|
||||
break;
|
||||
case MD_BLOCK_P:
|
||||
RENDER_VERBATIM(r, "</p>\n");
|
||||
break;
|
||||
case MD_BLOCK_TABLE:
|
||||
RENDER_VERBATIM(r, "</table>\n");
|
||||
break;
|
||||
case MD_BLOCK_THEAD:
|
||||
RENDER_VERBATIM(r, "</thead>\n");
|
||||
break;
|
||||
case MD_BLOCK_TBODY:
|
||||
RENDER_VERBATIM(r, "</tbody>\n");
|
||||
break;
|
||||
case MD_BLOCK_TR:
|
||||
RENDER_VERBATIM(r, "</tr>\n");
|
||||
break;
|
||||
case MD_BLOCK_TH:
|
||||
RENDER_VERBATIM(r, "</th>\n");
|
||||
break;
|
||||
case MD_BLOCK_TD:
|
||||
RENDER_VERBATIM(r, "</td>\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
enter_span_callback(MD_SPANTYPE type, void *detail, void *userdata)
|
||||
{
|
||||
MD_HTML *r = (MD_HTML *)userdata;
|
||||
|
||||
if (r->image_nesting_level > 0)
|
||||
{
|
||||
/* We are inside a Markdown image label. Markdown allows to use any
|
||||
* emphasis and other rich contents in that context similarly as in
|
||||
* any link label.
|
||||
*
|
||||
* However, unlike in the case of links (where that contents becomes
|
||||
* contents of the <a>...</a> tag), in the case of images the contents
|
||||
* is supposed to fall into the attribute alt: <img alt="...">.
|
||||
*
|
||||
* In that context we naturally cannot output nested HTML tags. So lets
|
||||
* suppress them and only output the plain text (i.e. what falls into
|
||||
* text() callback).
|
||||
*
|
||||
* This make-it-a-plain-text approach is the recommended practice by
|
||||
* CommonMark specification (for HTML output).
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MD_SPAN_EM:
|
||||
RENDER_VERBATIM(r, "<em>");
|
||||
break;
|
||||
case MD_SPAN_STRONG:
|
||||
RENDER_VERBATIM(r, "<strong>");
|
||||
break;
|
||||
case MD_SPAN_U:
|
||||
RENDER_VERBATIM(r, "<u>");
|
||||
break;
|
||||
case MD_SPAN_A:
|
||||
render_open_a_span(r, (MD_SPAN_A_DETAIL *)detail);
|
||||
break;
|
||||
case MD_SPAN_IMG:
|
||||
render_open_img_span(r, (MD_SPAN_IMG_DETAIL *)detail);
|
||||
break;
|
||||
case MD_SPAN_CODE:
|
||||
RENDER_VERBATIM(r, "<code>");
|
||||
break;
|
||||
case MD_SPAN_DEL:
|
||||
RENDER_VERBATIM(r, "<del>");
|
||||
break;
|
||||
case MD_SPAN_LATEXMATH:
|
||||
RENDER_VERBATIM(r, "<x-equation>");
|
||||
break;
|
||||
case MD_SPAN_LATEXMATH_DISPLAY:
|
||||
RENDER_VERBATIM(r, "<x-equation type=\"display\">");
|
||||
break;
|
||||
case MD_SPAN_WIKILINK:
|
||||
render_open_wikilink_span(r, (MD_SPAN_WIKILINK_DETAIL *)detail);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
leave_span_callback(MD_SPANTYPE type, void *detail, void *userdata)
|
||||
{
|
||||
MD_HTML *r = (MD_HTML *)userdata;
|
||||
|
||||
if (r->image_nesting_level > 0)
|
||||
{
|
||||
/* Ditto as in enter_span_callback(), except we have to allow the
|
||||
* end of the <img> tag. */
|
||||
if (r->image_nesting_level == 1 && type == MD_SPAN_IMG)
|
||||
render_close_img_span(r, (MD_SPAN_IMG_DETAIL *)detail);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MD_SPAN_EM:
|
||||
RENDER_VERBATIM(r, "</em>");
|
||||
break;
|
||||
case MD_SPAN_STRONG:
|
||||
RENDER_VERBATIM(r, "</strong>");
|
||||
break;
|
||||
case MD_SPAN_U:
|
||||
RENDER_VERBATIM(r, "</u>");
|
||||
break;
|
||||
case MD_SPAN_A:
|
||||
RENDER_VERBATIM(r, "</a>");
|
||||
break;
|
||||
case MD_SPAN_IMG: /*noop, handled above*/
|
||||
break;
|
||||
case MD_SPAN_CODE:
|
||||
RENDER_VERBATIM(r, "</code>");
|
||||
break;
|
||||
case MD_SPAN_DEL:
|
||||
RENDER_VERBATIM(r, "</del>");
|
||||
break;
|
||||
case MD_SPAN_LATEXMATH: /*fall through*/
|
||||
case MD_SPAN_LATEXMATH_DISPLAY:
|
||||
RENDER_VERBATIM(r, "</x-equation>");
|
||||
break;
|
||||
case MD_SPAN_WIKILINK:
|
||||
RENDER_VERBATIM(r, "</x-wikilink>");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
text_callback(MD_TEXTTYPE type, const MD_CHAR *text, MD_SIZE size, void *userdata)
|
||||
{
|
||||
MD_HTML *r = (MD_HTML *)userdata;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case MD_TEXT_NULLCHAR:
|
||||
render_utf8_codepoint(r, 0x0000, render_verbatim);
|
||||
break;
|
||||
case MD_TEXT_BR:
|
||||
RENDER_VERBATIM(r, (r->image_nesting_level == 0
|
||||
? ((r->flags & MD_HTML_FLAG_XHTML) ? "<br />\n" : "<br>\n")
|
||||
: " "));
|
||||
break;
|
||||
case MD_TEXT_SOFTBR:
|
||||
RENDER_VERBATIM(r, (r->image_nesting_level == 0 ? "\n" : " "));
|
||||
break;
|
||||
case MD_TEXT_HTML:
|
||||
render_verbatim(r, text, size);
|
||||
break;
|
||||
case MD_TEXT_ENTITY:
|
||||
render_entity(r, text, size, render_html_escaped);
|
||||
break;
|
||||
default:
|
||||
render_html_escaped(r, text, size);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
debug_log_callback(const char *msg, void *userdata)
|
||||
{
|
||||
MD_HTML *r = (MD_HTML *)userdata;
|
||||
if (r->flags & MD_HTML_FLAG_DEBUG)
|
||||
fprintf(stderr, "MD4C: %s\n", msg);
|
||||
}
|
||||
|
||||
int md_html(const MD_CHAR *input, MD_SIZE input_size,
|
||||
void (*process_output)(const MD_CHAR *, MD_SIZE, void *),
|
||||
void *userdata, unsigned parser_flags, unsigned renderer_flags)
|
||||
{
|
||||
MD_HTML render = {process_output, userdata, renderer_flags, 0, {0}};
|
||||
int i;
|
||||
|
||||
MD_PARSER parser = {
|
||||
0,
|
||||
parser_flags,
|
||||
enter_block_callback,
|
||||
leave_block_callback,
|
||||
enter_span_callback,
|
||||
leave_span_callback,
|
||||
text_callback,
|
||||
debug_log_callback,
|
||||
NULL};
|
||||
|
||||
/* Build map of characters which need escaping. */
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
unsigned char ch = (unsigned char)i;
|
||||
|
||||
if (strchr("\"&<>", ch) != NULL)
|
||||
render.escape_map[i] |= NEED_HTML_ESC_FLAG;
|
||||
|
||||
if (!ISALNUM(ch) && strchr("-_.+!*(),%#@?=;:/,+$", ch) == NULL)
|
||||
render.escape_map[i] |= NEED_URL_ESC_FLAG;
|
||||
}
|
||||
|
||||
/* Consider skipping UTF-8 byte order mark (BOM). */
|
||||
if (renderer_flags & MD_HTML_FLAG_SKIP_UTF8_BOM && sizeof(MD_CHAR) == 1)
|
||||
{
|
||||
static const MD_CHAR bom[3] = {0xef, 0xbb, 0xbf};
|
||||
if (input_size >= sizeof(bom) && memcmp(input, bom, sizeof(bom)) == 0)
|
||||
{
|
||||
input += sizeof(bom);
|
||||
input_size -= sizeof(bom);
|
||||
}
|
||||
}
|
||||
|
||||
return md_parse(input, input_size, &parser, (void *)&render);
|
||||
}
|
||||
|
||||
void reset_hd_cnt()
|
||||
{
|
||||
for (size_t i = 0; i < 6; i++)
|
||||
{
|
||||
hd_cnt[i] = 0;
|
||||
}
|
||||
}
|
70
lib/md/md4c/md4c-html.h
Normal file
70
lib/md/md4c/md4c-html.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* MD4C: Markdown parser for C
|
||||
* (http://github.com/mity/md4c)
|
||||
*
|
||||
* Copyright (c) 2016-2017 Martin Mitas
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MD4C_HTML_H
|
||||
#define MD4C_HTML_H
|
||||
|
||||
#include "md4c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* If set, debug output from md_parse() is sent to stderr. */
|
||||
#define MD_HTML_FLAG_DEBUG 0x0001
|
||||
#define MD_HTML_FLAG_VERBATIM_ENTITIES 0x0002
|
||||
#define MD_HTML_FLAG_SKIP_UTF8_BOM 0x0004
|
||||
#define MD_HTML_FLAG_XHTML 0x0008
|
||||
|
||||
|
||||
/* Render Markdown into HTML.
|
||||
*
|
||||
* Note only contents of <body> tag is generated. Caller must generate
|
||||
* HTML header/footer manually before/after calling md_html().
|
||||
*
|
||||
* Params input and input_size specify the Markdown input.
|
||||
* Callback process_output() gets called with chunks of HTML output.
|
||||
* (Typical implementation may just output the bytes to a file or append to
|
||||
* some buffer).
|
||||
* Param userdata is just propgated back to process_output() callback.
|
||||
* Param parser_flags are flags from md4c.h propagated to md_parse().
|
||||
* Param render_flags is bitmask of MD_HTML_FLAG_xxxx.
|
||||
*
|
||||
* Returns -1 on error (if md_parse() fails.)
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int md_html(const MD_CHAR* input, MD_SIZE input_size,
|
||||
void (*process_output)(const MD_CHAR*, MD_SIZE, void*),
|
||||
void* userdata, unsigned parser_flags, unsigned renderer_flags);
|
||||
|
||||
|
||||
void reset_hd_cnt();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* MD4C_HTML_H */
|
6306
lib/md/md4c/md4c.c
Normal file
6306
lib/md/md4c/md4c.c
Normal file
File diff suppressed because it is too large
Load Diff
397
lib/md/md4c/md4c.h
Normal file
397
lib/md/md4c/md4c.h
Normal file
@ -0,0 +1,397 @@
|
||||
/*
|
||||
* MD4C: Markdown parser for C
|
||||
* (http://github.com/mity/md4c)
|
||||
*
|
||||
* Copyright (c) 2016-2020 Martin Mitas
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MD4C_H
|
||||
#define MD4C_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined MD4C_USE_UTF16
|
||||
/* Magic to support UTF-16. Note that in order to use it, you have to define
|
||||
* the macro MD4C_USE_UTF16 both when building MD4C as well as when
|
||||
* including this header in your code. */
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
typedef WCHAR MD_CHAR;
|
||||
#else
|
||||
#error MD4C_USE_UTF16 is only supported on Windows.
|
||||
#endif
|
||||
#else
|
||||
typedef char MD_CHAR;
|
||||
#endif
|
||||
|
||||
typedef unsigned MD_SIZE;
|
||||
typedef unsigned MD_OFFSET;
|
||||
|
||||
|
||||
/* Block represents a part of document hierarchy structure like a paragraph
|
||||
* or list item.
|
||||
*/
|
||||
typedef enum MD_BLOCKTYPE {
|
||||
/* <body>...</body> */
|
||||
MD_BLOCK_DOC = 0,
|
||||
|
||||
/* <blockquote>...</blockquote> */
|
||||
MD_BLOCK_QUOTE,
|
||||
|
||||
/* <ul>...</ul>
|
||||
* Detail: Structure MD_BLOCK_UL_DETAIL. */
|
||||
MD_BLOCK_UL,
|
||||
|
||||
/* <ol>...</ol>
|
||||
* Detail: Structure MD_BLOCK_OL_DETAIL. */
|
||||
MD_BLOCK_OL,
|
||||
|
||||
/* <li>...</li>
|
||||
* Detail: Structure MD_BLOCK_LI_DETAIL. */
|
||||
MD_BLOCK_LI,
|
||||
|
||||
/* <hr> */
|
||||
MD_BLOCK_HR,
|
||||
|
||||
/* <h1>...</h1> (for levels up to 6)
|
||||
* Detail: Structure MD_BLOCK_H_DETAIL. */
|
||||
MD_BLOCK_H,
|
||||
|
||||
/* <pre><code>...</code></pre>
|
||||
* Note the text lines within code blocks are terminated with '\n'
|
||||
* instead of explicit MD_TEXT_BR. */
|
||||
MD_BLOCK_CODE,
|
||||
|
||||
/* Raw HTML block. This itself does not correspond to any particular HTML
|
||||
* tag. The contents of it _is_ raw HTML source intended to be put
|
||||
* in verbatim form to the HTML output. */
|
||||
MD_BLOCK_HTML,
|
||||
|
||||
/* <p>...</p> */
|
||||
MD_BLOCK_P,
|
||||
|
||||
/* <table>...</table> and its contents.
|
||||
* Detail: Structure MD_BLOCK_TD_DETAIL (used with MD_BLOCK_TH and MD_BLOCK_TD)
|
||||
* Note all of these are used only if extension MD_FLAG_TABLES is enabled. */
|
||||
MD_BLOCK_TABLE,
|
||||
MD_BLOCK_THEAD,
|
||||
MD_BLOCK_TBODY,
|
||||
MD_BLOCK_TR,
|
||||
MD_BLOCK_TH,
|
||||
MD_BLOCK_TD
|
||||
} MD_BLOCKTYPE;
|
||||
|
||||
/* Span represents an in-line piece of a document which should be rendered with
|
||||
* the same font, color and other attributes. A sequence of spans forms a block
|
||||
* like paragraph or list item. */
|
||||
typedef enum MD_SPANTYPE {
|
||||
/* <em>...</em> */
|
||||
MD_SPAN_EM,
|
||||
|
||||
/* <strong>...</strong> */
|
||||
MD_SPAN_STRONG,
|
||||
|
||||
/* <a href="xxx">...</a>
|
||||
* Detail: Structure MD_SPAN_A_DETAIL. */
|
||||
MD_SPAN_A,
|
||||
|
||||
/* <img src="xxx">...</a>
|
||||
* Detail: Structure MD_SPAN_IMG_DETAIL.
|
||||
* Note: Image text can contain nested spans and even nested images.
|
||||
* If rendered into ALT attribute of HTML <IMG> tag, it's responsibility
|
||||
* of the parser to deal with it.
|
||||
*/
|
||||
MD_SPAN_IMG,
|
||||
|
||||
/* <code>...</code> */
|
||||
MD_SPAN_CODE,
|
||||
|
||||
/* <del>...</del>
|
||||
* Note: Recognized only when MD_FLAG_STRIKETHROUGH is enabled.
|
||||
*/
|
||||
MD_SPAN_DEL,
|
||||
|
||||
/* For recognizing inline ($) and display ($$) equations
|
||||
* Note: Recognized only when MD_FLAG_LATEXMATHSPANS is enabled.
|
||||
*/
|
||||
MD_SPAN_LATEXMATH,
|
||||
MD_SPAN_LATEXMATH_DISPLAY,
|
||||
|
||||
/* Wiki links
|
||||
* Note: Recognized only when MD_FLAG_WIKILINKS is enabled.
|
||||
*/
|
||||
MD_SPAN_WIKILINK,
|
||||
|
||||
/* <u>...</u>
|
||||
* Note: Recognized only when MD_FLAG_UNDERLINE is enabled. */
|
||||
MD_SPAN_U
|
||||
} MD_SPANTYPE;
|
||||
|
||||
/* Text is the actual textual contents of span. */
|
||||
typedef enum MD_TEXTTYPE {
|
||||
/* Normal text. */
|
||||
MD_TEXT_NORMAL = 0,
|
||||
|
||||
/* NULL character. CommonMark requires replacing NULL character with
|
||||
* the replacement char U+FFFD, so this allows caller to do that easily. */
|
||||
MD_TEXT_NULLCHAR,
|
||||
|
||||
/* Line breaks.
|
||||
* Note these are not sent from blocks with verbatim output (MD_BLOCK_CODE
|
||||
* or MD_BLOCK_HTML). In such cases, '\n' is part of the text itself. */
|
||||
MD_TEXT_BR, /* <br> (hard break) */
|
||||
MD_TEXT_SOFTBR, /* '\n' in source text where it is not semantically meaningful (soft break) */
|
||||
|
||||
/* Entity.
|
||||
* (a) Named entity, e.g.
|
||||
* (Note MD4C does not have a list of known entities.
|
||||
* Anything matching the regexp /&[A-Za-z][A-Za-z0-9]{1,47};/ is
|
||||
* treated as a named entity.)
|
||||
* (b) Numerical entity, e.g. Ӓ
|
||||
* (c) Hexadecimal entity, e.g. ካ
|
||||
*
|
||||
* As MD4C is mostly encoding agnostic, application gets the verbatim
|
||||
* entity text into the MD_PARSER::text_callback(). */
|
||||
MD_TEXT_ENTITY,
|
||||
|
||||
/* Text in a code block (inside MD_BLOCK_CODE) or inlined code (`code`).
|
||||
* If it is inside MD_BLOCK_CODE, it includes spaces for indentation and
|
||||
* '\n' for new lines. MD_TEXT_BR and MD_TEXT_SOFTBR are not sent for this
|
||||
* kind of text. */
|
||||
MD_TEXT_CODE,
|
||||
|
||||
/* Text is a raw HTML. If it is contents of a raw HTML block (i.e. not
|
||||
* an inline raw HTML), then MD_TEXT_BR and MD_TEXT_SOFTBR are not used.
|
||||
* The text contains verbatim '\n' for the new lines. */
|
||||
MD_TEXT_HTML,
|
||||
|
||||
/* Text is inside an equation. This is processed the same way as inlined code
|
||||
* spans (`code`). */
|
||||
MD_TEXT_LATEXMATH
|
||||
} MD_TEXTTYPE;
|
||||
|
||||
|
||||
/* Alignment enumeration. */
|
||||
typedef enum MD_ALIGN {
|
||||
MD_ALIGN_DEFAULT = 0, /* When unspecified. */
|
||||
MD_ALIGN_LEFT,
|
||||
MD_ALIGN_CENTER,
|
||||
MD_ALIGN_RIGHT
|
||||
} MD_ALIGN;
|
||||
|
||||
|
||||
/* String attribute.
|
||||
*
|
||||
* This wraps strings which are outside of a normal text flow and which are
|
||||
* propagated within various detailed structures, but which still may contain
|
||||
* string portions of different types like e.g. entities.
|
||||
*
|
||||
* So, for example, lets consider this image:
|
||||
*
|
||||
* 
|
||||
*
|
||||
* The image alt text is propagated as a normal text via the MD_PARSER::text()
|
||||
* callback. However, the image title ('foo " bar') is propagated as
|
||||
* MD_ATTRIBUTE in MD_SPAN_IMG_DETAIL::title.
|
||||
*
|
||||
* Then the attribute MD_SPAN_IMG_DETAIL::title shall provide the following:
|
||||
* -- [0]: "foo " (substr_types[0] == MD_TEXT_NORMAL; substr_offsets[0] == 0)
|
||||
* -- [1]: """ (substr_types[1] == MD_TEXT_ENTITY; substr_offsets[1] == 4)
|
||||
* -- [2]: " bar" (substr_types[2] == MD_TEXT_NORMAL; substr_offsets[2] == 10)
|
||||
* -- [3]: (n/a) (n/a ; substr_offsets[3] == 14)
|
||||
*
|
||||
* Note that these invariants are always guaranteed:
|
||||
* -- substr_offsets[0] == 0
|
||||
* -- substr_offsets[LAST+1] == size
|
||||
* -- Currently, only MD_TEXT_NORMAL, MD_TEXT_ENTITY, MD_TEXT_NULLCHAR
|
||||
* substrings can appear. This could change only of the specification
|
||||
* changes.
|
||||
*/
|
||||
typedef struct MD_ATTRIBUTE {
|
||||
const MD_CHAR* text;
|
||||
MD_SIZE size;
|
||||
const MD_TEXTTYPE* substr_types;
|
||||
const MD_OFFSET* substr_offsets;
|
||||
} MD_ATTRIBUTE;
|
||||
|
||||
|
||||
/* Detailed info for MD_BLOCK_UL. */
|
||||
typedef struct MD_BLOCK_UL_DETAIL {
|
||||
int is_tight; /* Non-zero if tight list, zero if loose. */
|
||||
MD_CHAR mark; /* Item bullet character in MarkDown source of the list, e.g. '-', '+', '*'. */
|
||||
} MD_BLOCK_UL_DETAIL;
|
||||
|
||||
/* Detailed info for MD_BLOCK_OL. */
|
||||
typedef struct MD_BLOCK_OL_DETAIL {
|
||||
unsigned start; /* Start index of the ordered list. */
|
||||
int is_tight; /* Non-zero if tight list, zero if loose. */
|
||||
MD_CHAR mark_delimiter; /* Character delimiting the item marks in MarkDown source, e.g. '.' or ')' */
|
||||
} MD_BLOCK_OL_DETAIL;
|
||||
|
||||
/* Detailed info for MD_BLOCK_LI. */
|
||||
typedef struct MD_BLOCK_LI_DETAIL {
|
||||
int is_task; /* Can be non-zero only with MD_FLAG_TASKLISTS */
|
||||
MD_CHAR task_mark; /* If is_task, then one of 'x', 'X' or ' '. Undefined otherwise. */
|
||||
MD_OFFSET task_mark_offset; /* If is_task, then offset in the input of the char between '[' and ']'. */
|
||||
} MD_BLOCK_LI_DETAIL;
|
||||
|
||||
/* Detailed info for MD_BLOCK_H. */
|
||||
typedef struct MD_BLOCK_H_DETAIL {
|
||||
unsigned level; /* Header level (1 - 6) */
|
||||
} MD_BLOCK_H_DETAIL;
|
||||
|
||||
/* Detailed info for MD_BLOCK_CODE. */
|
||||
typedef struct MD_BLOCK_CODE_DETAIL {
|
||||
MD_ATTRIBUTE info;
|
||||
MD_ATTRIBUTE lang;
|
||||
MD_CHAR fence_char; /* The character used for fenced code block; or zero for indented code block. */
|
||||
} MD_BLOCK_CODE_DETAIL;
|
||||
|
||||
/* Detailed info for MD_BLOCK_TH and MD_BLOCK_TD. */
|
||||
typedef struct MD_BLOCK_TD_DETAIL {
|
||||
MD_ALIGN align;
|
||||
} MD_BLOCK_TD_DETAIL;
|
||||
|
||||
/* Detailed info for MD_SPAN_A. */
|
||||
typedef struct MD_SPAN_A_DETAIL {
|
||||
MD_ATTRIBUTE href;
|
||||
MD_ATTRIBUTE title;
|
||||
} MD_SPAN_A_DETAIL;
|
||||
|
||||
/* Detailed info for MD_SPAN_IMG. */
|
||||
typedef struct MD_SPAN_IMG_DETAIL {
|
||||
MD_ATTRIBUTE src;
|
||||
MD_ATTRIBUTE title;
|
||||
} MD_SPAN_IMG_DETAIL;
|
||||
|
||||
/* Detailed info for MD_SPAN_WIKILINK. */
|
||||
typedef struct MD_SPAN_WIKILINK {
|
||||
MD_ATTRIBUTE target;
|
||||
} MD_SPAN_WIKILINK_DETAIL;
|
||||
|
||||
/* Flags specifying extensions/deviations from CommonMark specification.
|
||||
*
|
||||
* By default (when MD_PARSER::flags == 0), we follow CommonMark specification.
|
||||
* The following flags may allow some extensions or deviations from it.
|
||||
*/
|
||||
#define MD_FLAG_COLLAPSEWHITESPACE 0x0001 /* In MD_TEXT_NORMAL, collapse non-trivial whitespace into single ' ' */
|
||||
#define MD_FLAG_PERMISSIVEATXHEADERS 0x0002 /* Do not require space in ATX headers ( ###header ) */
|
||||
#define MD_FLAG_PERMISSIVEURLAUTOLINKS 0x0004 /* Recognize URLs as autolinks even without '<', '>' */
|
||||
#define MD_FLAG_PERMISSIVEEMAILAUTOLINKS 0x0008 /* Recognize e-mails as autolinks even without '<', '>' and 'mailto:' */
|
||||
#define MD_FLAG_NOINDENTEDCODEBLOCKS 0x0010 /* Disable indented code blocks. (Only fenced code works.) */
|
||||
#define MD_FLAG_NOHTMLBLOCKS 0x0020 /* Disable raw HTML blocks. */
|
||||
#define MD_FLAG_NOHTMLSPANS 0x0040 /* Disable raw HTML (inline). */
|
||||
#define MD_FLAG_TABLES 0x0100 /* Enable tables extension. */
|
||||
#define MD_FLAG_STRIKETHROUGH 0x0200 /* Enable strikethrough extension. */
|
||||
#define MD_FLAG_PERMISSIVEWWWAUTOLINKS 0x0400 /* Enable WWW autolinks (even without any scheme prefix, if they begin with 'www.') */
|
||||
#define MD_FLAG_TASKLISTS 0x0800 /* Enable task list extension. */
|
||||
#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */
|
||||
#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */
|
||||
#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */
|
||||
|
||||
#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS)
|
||||
#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS)
|
||||
|
||||
/* Convenient sets of flags corresponding to well-known Markdown dialects.
|
||||
*
|
||||
* Note we may only support subset of features of the referred dialect.
|
||||
* The constant just enables those extensions which bring us as close as
|
||||
* possible given what features we implement.
|
||||
*
|
||||
* ABI compatibility note: Meaning of these can change in time as new
|
||||
* extensions, bringing the dialect closer to the original, are implemented.
|
||||
*/
|
||||
#define MD_DIALECT_COMMONMARK 0
|
||||
#define MD_DIALECT_GITHUB (MD_FLAG_PERMISSIVEAUTOLINKS | MD_FLAG_TABLES | MD_FLAG_STRIKETHROUGH | MD_FLAG_TASKLISTS)
|
||||
|
||||
/* Parser structure.
|
||||
*/
|
||||
typedef struct MD_PARSER {
|
||||
/* Reserved. Set to zero.
|
||||
*/
|
||||
unsigned abi_version;
|
||||
|
||||
/* Dialect options. Bitmask of MD_FLAG_xxxx values.
|
||||
*/
|
||||
unsigned flags;
|
||||
|
||||
/* Caller-provided rendering callbacks.
|
||||
*
|
||||
* For some block/span types, more detailed information is provided in a
|
||||
* type-specific structure pointed by the argument 'detail'.
|
||||
*
|
||||
* The last argument of all callbacks, 'userdata', is just propagated from
|
||||
* md_parse() and is available for any use by the application.
|
||||
*
|
||||
* Note any strings provided to the callbacks as their arguments or as
|
||||
* members of any detail structure are generally not zero-terminated.
|
||||
* Application has to take the respective size information into account.
|
||||
*
|
||||
* Any rendering callback may abort further parsing of the document by
|
||||
* returning non-zero.
|
||||
*/
|
||||
int (*enter_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
|
||||
int (*leave_block)(MD_BLOCKTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
|
||||
|
||||
int (*enter_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
|
||||
int (*leave_span)(MD_SPANTYPE /*type*/, void* /*detail*/, void* /*userdata*/);
|
||||
|
||||
int (*text)(MD_TEXTTYPE /*type*/, const MD_CHAR* /*text*/, MD_SIZE /*size*/, void* /*userdata*/);
|
||||
|
||||
/* Debug callback. Optional (may be NULL).
|
||||
*
|
||||
* If provided and something goes wrong, this function gets called.
|
||||
* This is intended for debugging and problem diagnosis for developers;
|
||||
* it is not intended to provide any errors suitable for displaying to an
|
||||
* end user.
|
||||
*/
|
||||
void (*debug_log)(const char* /*msg*/, void* /*userdata*/);
|
||||
|
||||
/* Reserved. Set to NULL.
|
||||
*/
|
||||
void (*syntax)(void);
|
||||
} MD_PARSER;
|
||||
|
||||
|
||||
/* For backward compatibility. Do not use in new code.
|
||||
*/
|
||||
typedef MD_PARSER MD_RENDERER;
|
||||
|
||||
|
||||
/* Parse the Markdown document stored in the string 'text' of size 'size'.
|
||||
* The parser provides callbacks to be called during the parsing so the
|
||||
* caller can render the document on the screen or convert the Markdown
|
||||
* to another format.
|
||||
*
|
||||
* Zero is returned on success. If a runtime error occurs (e.g. a memory
|
||||
* fails), -1 is returned. If the processing is aborted due any callback
|
||||
* returning non-zero, the return value of the callback is returned.
|
||||
*/
|
||||
int md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userdata);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" { */
|
||||
#endif
|
||||
|
||||
#endif /* MD4C_H */
|
@ -1,6 +0,0 @@
|
||||
include ../../../../var.mk
|
||||
|
||||
LIB_NAME=pibot.$(LIB_EXT)
|
||||
LIB_OBJ= pibot.o
|
||||
|
||||
include ../../lib.mk
|
@ -1,260 +0,0 @@
|
||||
|
||||
#include "../lualib.h"
|
||||
#include "../../lua-api.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
static const char *device = "/dev/spidev0.0";
|
||||
static uint8_t mode;
|
||||
static uint8_t bits = 8;
|
||||
static uint32_t speed = 500000;
|
||||
static uint16_t delay = 110;
|
||||
|
||||
static int fd_spi = -1;
|
||||
|
||||
int spi_open()
|
||||
{
|
||||
int ret;
|
||||
int fd = open(device, O_RDWR);
|
||||
if (fd < 0)
|
||||
{
|
||||
perror("can't open device \n");
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* spi mode
|
||||
*/
|
||||
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("can't set spi mode \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("can't get spi mode \n");
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* bits per word
|
||||
*/
|
||||
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("can't set bits per word \n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("can't get bits per word");
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* max speed hz
|
||||
*/
|
||||
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("can't set max speed hz");
|
||||
return -1;
|
||||
}
|
||||
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
|
||||
if (ret == -1)
|
||||
{
|
||||
perror("can't get max speed hz");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("spi mode: %d\n", mode);
|
||||
printf("bits per word: %d\n", bits);
|
||||
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int spi_send_cmd(int fd, uint8_t cmd, uint8_t idx, uint8_t value)
|
||||
{
|
||||
int ret;
|
||||
uint8_t tx[3];
|
||||
uint8_t rx[3] = {0, };
|
||||
struct spi_ioc_transfer tr = {
|
||||
.tx_buf = (unsigned long)tx,
|
||||
.rx_buf = (unsigned long)rx,
|
||||
.len = 3,
|
||||
.delay_usecs = delay,
|
||||
.speed_hz = speed,
|
||||
.bits_per_word = bits
|
||||
};
|
||||
tx[0] = cmd;
|
||||
tx[1] = idx;
|
||||
tx[2] = value;
|
||||
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
|
||||
if (ret < 1)
|
||||
{
|
||||
perror("can't send spi message");
|
||||
return -1;
|
||||
}
|
||||
//if(cmd == 255)
|
||||
// printf("RX %d %d %d \n", rx[0], rx[1], rx[2]);
|
||||
return (int) rx[0];
|
||||
}
|
||||
|
||||
int spi_set(int fd,uint8_t idx, uint8_t v)
|
||||
{
|
||||
return spi_send_cmd(fd,1, idx, v);
|
||||
}
|
||||
|
||||
int spi_get(int fd,uint8_t idx)
|
||||
{
|
||||
// send command
|
||||
int ret;
|
||||
ret = spi_send_cmd(fd,0,idx,0);
|
||||
if(ret == -1) return -1;
|
||||
// read back
|
||||
return spi_send_cmd(fd,255,255,255);
|
||||
}
|
||||
|
||||
void spi_read_buff(int fd,uint8_t* buf, int size)
|
||||
{
|
||||
int ret;
|
||||
uint8_t tx[size];
|
||||
struct spi_ioc_transfer tr = {
|
||||
.tx_buf = (unsigned long)tx,
|
||||
.rx_buf = (unsigned long)buf,
|
||||
.len = size,
|
||||
.delay_usecs = delay,
|
||||
.speed_hz = speed,
|
||||
.bits_per_word = bits
|
||||
};
|
||||
spi_send_cmd(fd,2,0,size);
|
||||
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
|
||||
if (ret < 1)
|
||||
{
|
||||
perror("can't send spi message");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void spi_write_buff(int fd, uint8_t* buf, int size)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i < size; i++)
|
||||
spi_set(fd,i,buf[i]);
|
||||
|
||||
}
|
||||
|
||||
static int l_init(lua_State* L)
|
||||
{
|
||||
fd_spi = spi_open();
|
||||
if(fd_spi == -1)
|
||||
lua_pushboolean(L,0);
|
||||
else
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_release(lua_State* L)
|
||||
{
|
||||
if(fd_spi > 0)
|
||||
close(fd_spi);
|
||||
fd_spi = -1;
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_read(lua_State* L)
|
||||
{
|
||||
int size = luaL_checknumber(L,1);
|
||||
unsigned char data_buf[size];
|
||||
if(fd_spi == -1)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
// request data
|
||||
spi_read_buff(fd_spi,data_buf,size);
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
int i;
|
||||
for(i =0; i < size; i++)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_pushnumber(L,data_buf[i]);
|
||||
lua_settable(L,-3);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_write(lua_State* L)
|
||||
{
|
||||
/* 1st argument must be a table (t) */
|
||||
byte_array_t* data_buf = l_check_barray(L, 1);
|
||||
if(fd_spi == -1)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
spi_write_buff(fd_spi,data_buf->data, data_buf->size);
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_set(lua_State* L)
|
||||
{
|
||||
int idx = luaL_checknumber(L,1);
|
||||
int val = luaL_checknumber(L,2);
|
||||
if(fd_spi == -1)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
spi_set(fd_spi,idx,val);
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_get(lua_State* L)
|
||||
{
|
||||
int idx = luaL_checknumber(L,1);
|
||||
if(fd_spi == -1)
|
||||
{
|
||||
lua_pushboolean(L,0);
|
||||
return 1;
|
||||
}
|
||||
spi_get(fd_spi,idx);
|
||||
lua_pushboolean(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg _lib [] = {
|
||||
{"init", l_init},
|
||||
{"release",l_release},
|
||||
{"read",l_read},
|
||||
{"write",l_write},
|
||||
{"set",l_set},
|
||||
{"get",l_get},
|
||||
{NULL,NULL}
|
||||
};
|
||||
|
||||
int luaopen_pibot(lua_State *L)
|
||||
{
|
||||
luaL_newlib(L, _lib);
|
||||
return 1;
|
||||
}
|
428
lua-api.c
428
lua-api.c
@ -1,126 +1,340 @@
|
||||
#define PLUGIN_IMPLEMENT 1
|
||||
#include <dlfcn.h>
|
||||
#include <antd/plugin.h>
|
||||
#include <antd/scheduler.h>
|
||||
|
||||
#include "lib/lualib.h"
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <time.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
static void* core_handle = NULL;
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define LUA_HDL_FN "lua_handle"
|
||||
#define MAX_SOCK_NAME 64
|
||||
#define SOCKET_NAME "lua.sock"
|
||||
|
||||
#define PING_INTERVAL 10u // 10s
|
||||
#define PROCESS_TIMEOUT 200u //100ms
|
||||
|
||||
typedef struct {
|
||||
plugin_header_t* __plugin__;
|
||||
int fd;
|
||||
} lua_thread_data_t;
|
||||
|
||||
static pid_t pid = 0;
|
||||
static char sock_path[108];
|
||||
|
||||
static int open_unix_socket()
|
||||
{
|
||||
struct sockaddr_un address;
|
||||
address.sun_family = AF_UNIX;
|
||||
(void) strncpy(address.sun_path, sock_path, sizeof(address.sun_path));
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if(fd == -1)
|
||||
{
|
||||
ERROR( "Unable to create Unix domain socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if(connect(fd, (struct sockaddr*)(&address), sizeof(address)) == -1)
|
||||
{
|
||||
ERROR( "Unable to connect to socket '%s': %s", address.sun_path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
LOG( "Socket %s is created successfully", sock_path);
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int mk_socket()
|
||||
{
|
||||
struct sockaddr_un address;
|
||||
address.sun_family = AF_UNIX;
|
||||
// create the socket
|
||||
(void)strncpy(address.sun_path, sock_path, sizeof(address.sun_path));
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1)
|
||||
{
|
||||
ERROR("Unable to create Unix domain socket: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (bind(fd, (struct sockaddr *)(&address), sizeof(address)) == -1)
|
||||
{
|
||||
ERROR("Unable to bind name: %s to a socket: %s", address.sun_path, strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
// mark the socket as passive mode
|
||||
if (listen(fd, 500) == -1)
|
||||
{
|
||||
ERROR("Unable to listen to socket: %d (%s): %s", fd, sock_path, strerror(errno));
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
LOG("Socket %s is created successfully: %d", sock_path, fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void lua_serve()
|
||||
{
|
||||
void* core = NULL;
|
||||
void* lua_handle = NULL;
|
||||
void *(*handle_fn)(void*);
|
||||
char path[BUFFLEN];
|
||||
char* error;
|
||||
(void)snprintf(path, BUFFLEN, "%s/lua/core.so", __plugin__.pdir);
|
||||
core = dlopen(path, RTLD_NOW| RTLD_GLOBAL);
|
||||
if(!core)
|
||||
{
|
||||
ERROR("Cannot load Lua core: %s", dlerror());
|
||||
return;
|
||||
}
|
||||
// now load the handle
|
||||
(void)snprintf(path, BUFFLEN, "%s/lua/handle.so", __plugin__.pdir);
|
||||
lua_handle = dlopen(path, RTLD_LAZY);
|
||||
if(!lua_handle)
|
||||
{
|
||||
ERROR("Cannot load lua_handle: %s", dlerror());
|
||||
return;
|
||||
}
|
||||
// find the fn
|
||||
handle_fn = (void *(*)(void*))dlsym(lua_handle, LUA_HDL_FN);
|
||||
if ((error = dlerror()) != NULL)
|
||||
{
|
||||
ERROR("Problem when finding %s method from handle : %s", LUA_HDL_FN, error);
|
||||
handle_fn = NULL;
|
||||
return;
|
||||
}
|
||||
int socket = mk_socket();
|
||||
if(socket != -1)
|
||||
{
|
||||
int fd;
|
||||
if (setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) == -1)
|
||||
{
|
||||
ERROR("Unable to set reuse address on %d - setsockopt: %s", socket, strerror(errno));
|
||||
}
|
||||
LOG("LUA server online");
|
||||
/*set log level*/
|
||||
const char * enable_debug = getenv("ANTD_DEBUG");
|
||||
int log_level = LOG_ERR;
|
||||
if(enable_debug)
|
||||
{
|
||||
if(atoi(enable_debug))
|
||||
{
|
||||
LOG("LUA Debug is enabled");
|
||||
log_level = LOG_NOTICE;
|
||||
}
|
||||
}
|
||||
setlogmask(LOG_UPTO(log_level));
|
||||
while((fd = accept(socket, NULL, NULL)) > 0)
|
||||
{
|
||||
pthread_t thread;
|
||||
lua_thread_data_t* data = (lua_thread_data_t*)malloc(sizeof(lua_thread_data_t));
|
||||
data->__plugin__ = &__plugin__;
|
||||
data->fd = fd;
|
||||
//set_nonblock(fd);
|
||||
if (pthread_create(&thread, NULL, (void *(*)(void*))handle_fn, (void *)data) != 0)
|
||||
{
|
||||
ERROR("pthread_create: cannot create lua thread: %s", strerror(errno));
|
||||
(void)close(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("Serve thread created for %d", fd);
|
||||
pthread_detach(thread);
|
||||
}
|
||||
|
||||
}
|
||||
if (fd < 0)
|
||||
{
|
||||
ERROR("Unable to accept the new connection: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
if(core)
|
||||
(void)dlclose(core);
|
||||
if(lua_handle)
|
||||
(void)dlclose(lua_handle);
|
||||
LOG("lua_serve: stop serve due to error");
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
char* path = __s("%s/lua/core.so", __plugin__.pdir);
|
||||
core_handle = dlopen(path, RTLD_NOW| RTLD_GLOBAL);
|
||||
if(!core_handle)
|
||||
{
|
||||
ERROR("Cannot load Lua core; %s", dlerror());
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("Lua core loaded");
|
||||
}
|
||||
free(path);
|
||||
(void)snprintf(sock_path, sizeof(sock_path), "%s/%s", __plugin__.tmpdir, SOCKET_NAME);
|
||||
LOG("Lua socket will be stored in %s", sock_path);
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
// child
|
||||
lua_serve();
|
||||
}
|
||||
LOG("Lua module initialized");
|
||||
}
|
||||
/**
|
||||
|
||||
* Plugin handler, reads request from the server and processes it
|
||||
*
|
||||
*/
|
||||
static void push_dict_to_lua(lua_State* L, dictionary_t d)
|
||||
static void push_dict_to_socket(antd_client_t* cl, char* name, char* parent_name, dictionary_t d)
|
||||
{
|
||||
lua_newtable(L);
|
||||
|
||||
chain_t as;
|
||||
if(d)
|
||||
for_each_assoc(as, d)
|
||||
{
|
||||
lua_pushstring(L,as->key);
|
||||
//printf("KEY %s\n", as->key);
|
||||
if(EQU(as->key,"COOKIE") || EQU(as->key,"REQUEST_HEADER") || EQU(as->key,"REQUEST_DATA") )
|
||||
push_dict_to_lua(L, (dictionary_t)as->value);
|
||||
else
|
||||
{
|
||||
lua_pushstring(L,as->value);
|
||||
//printf("VALUE : %s\n",as->value );
|
||||
}
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
antd_send(cl,name, strlen(name));
|
||||
antd_send(cl,"\n", 1);
|
||||
chain_t as;
|
||||
if(d)
|
||||
for_each_assoc(as, d)
|
||||
{
|
||||
if(EQU(as->key,"COOKIE") || EQU(as->key,"REQUEST_HEADER") || EQU(as->key,"REQUEST_DATA") )
|
||||
push_dict_to_socket(cl, as->key, name, (dictionary_t)as->value);
|
||||
else if(as->value)
|
||||
{
|
||||
antd_send(cl,as->key, strlen(as->key));
|
||||
antd_send(cl,"\n", 1);
|
||||
antd_send(cl,as->value, strlen(as->value));
|
||||
antd_send(cl,"\n", 1);
|
||||
}
|
||||
}
|
||||
antd_send(cl,parent_name, strlen(parent_name));
|
||||
antd_send(cl,"\n", 1);
|
||||
}
|
||||
|
||||
static void *process(void *data)
|
||||
{
|
||||
antd_request_t *rq = (antd_request_t *)data;
|
||||
antd_client_t* cl = (antd_client_t* ) dvalue(rq->request, "LUA_CL_DATA");
|
||||
struct pollfd pfds[2];
|
||||
pfds[0].fd = rq->client->sock;
|
||||
pfds[0].events = POLLIN;
|
||||
if(rq->client->ssl)
|
||||
{
|
||||
pfds[0].events = POLLIN | POLLOUT;
|
||||
}
|
||||
pfds[1].fd = cl->sock;
|
||||
pfds[1].events = POLLIN;
|
||||
|
||||
int rc = poll(pfds, 2, PROCESS_TIMEOUT);
|
||||
antd_task_t* task;
|
||||
uint8_t buff[BUFFLEN];
|
||||
int ret;
|
||||
switch (rc)
|
||||
{
|
||||
case -1:
|
||||
ERROR("Error on poll(): %s", strerror(errno));
|
||||
antd_close(cl);
|
||||
dput(rq->request, "LUA_CL_DATA", NULL);
|
||||
return antd_create_task(NULL, data, NULL, rq->client->last_io);
|
||||
case 0:
|
||||
// time out
|
||||
task = antd_create_task(process, (void *)rq, NULL, time(NULL));
|
||||
antd_task_bind_event(task, rq->client->sock, 0, TASK_EVT_ON_WRITABLE | TASK_EVT_ON_READABLE);
|
||||
antd_task_bind_event(task, cl->sock, 0, TASK_EVT_ON_READABLE);
|
||||
return task;
|
||||
// we have data
|
||||
default:
|
||||
// If data is on webserver
|
||||
if ((pfds[0].revents & POLLIN) || (rq->client->ssl && (pfds[0].revents & POLLOUT)) )
|
||||
{
|
||||
while((ret = antd_recv_upto(rq->client,buff, BUFFLEN)) > 0)
|
||||
{
|
||||
// write data to the other side
|
||||
if(antd_send(cl,buff, ret) != ret)
|
||||
{
|
||||
ERROR("Error on atnd_send(): %s", strerror(errno));
|
||||
antd_close(cl);
|
||||
dput(rq->request, "LUA_CL_DATA", NULL);
|
||||
return antd_create_task(NULL, data, NULL, rq->client->last_io);
|
||||
}
|
||||
}
|
||||
if(ret < 0)
|
||||
{
|
||||
LOG("antd_recv_upto() on %d: %s",rq->client->sock, strerror(errno));
|
||||
antd_close(cl);
|
||||
dput(rq->request, "LUA_CL_DATA", NULL);
|
||||
return antd_create_task(NULL, data, NULL, rq->client->last_io);
|
||||
}
|
||||
}
|
||||
else if(pfds[0].revents &(POLLERR | POLLHUP))
|
||||
{
|
||||
ERROR("POLLERR or POLLHUP received on %d", rq->client->sock);
|
||||
antd_close(cl);
|
||||
dput(rq->request, "LUA_CL_DATA", NULL);
|
||||
return antd_create_task(NULL, data, NULL, rq->client->last_io);
|
||||
}
|
||||
if(pfds[1].revents & POLLIN)
|
||||
{
|
||||
while((ret = antd_recv_upto(cl,buff, BUFFLEN)) > 0)
|
||||
{
|
||||
// write data to the other side
|
||||
if(antd_send(rq->client,buff, ret) != ret)
|
||||
{
|
||||
ERROR("Error atnd_send(): %s", strerror(errno));
|
||||
antd_close(cl);
|
||||
dput(rq->request, "LUA_CL_DATA", NULL);
|
||||
return antd_create_task(NULL, data, NULL, rq->client->last_io);
|
||||
}
|
||||
}
|
||||
if(ret < 0)
|
||||
{
|
||||
LOG("antd_recv_upto() on %d: %s", cl->sock, strerror(errno));
|
||||
antd_close(cl);
|
||||
dput(rq->request, "LUA_CL_DATA", NULL);
|
||||
return antd_create_task(NULL, data, NULL, rq->client->last_io);
|
||||
}
|
||||
}
|
||||
else if(pfds[1].revents &(POLLERR | POLLHUP))
|
||||
{
|
||||
ERROR("POLLERR or POLLHUP received on %d", cl->sock);
|
||||
antd_close(cl);
|
||||
dput(rq->request, "LUA_CL_DATA", NULL);
|
||||
return antd_create_task(NULL, data, NULL, rq->client->last_io);
|
||||
}
|
||||
task = antd_create_task(process, (void *)rq, NULL, time(NULL));
|
||||
antd_task_bind_event(task, rq->client->sock, 0, TASK_EVT_ON_WRITABLE | TASK_EVT_ON_READABLE);
|
||||
antd_task_bind_event(task, cl->sock, 0, TASK_EVT_ON_READABLE);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
||||
void* handle(void* data)
|
||||
{
|
||||
antd_request_t* rq = (antd_request_t*) data;
|
||||
plugin_header_t* __plugin__ = meta();
|
||||
lua_State* L = NULL;
|
||||
//char * index = __s("%s/%s",__plugin__.htdocs,"router.lua");
|
||||
char* cnf = config_dir();
|
||||
char * apis = __s("%s/%s",cnf,"api.lua");
|
||||
L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
//module loader
|
||||
//luaL_newlib(L, modules);
|
||||
//lua_setglobal(L, "modules");
|
||||
// set up global variable
|
||||
// API header
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"name");
|
||||
lua_pushstring(L, __plugin__->name);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"root");
|
||||
lua_pushstring(L, rq->client->port_config->htdocs);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"apiroot");
|
||||
lua_pushstring(L, cnf);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"tmpdir");
|
||||
lua_pushstring(L, tmpdir());
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"dbpath");
|
||||
lua_pushstring(L, __plugin__->dbpath);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_setglobal(L, "__api__");
|
||||
|
||||
// Request
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,"id");
|
||||
lua_pushlightuserdata(L, rq->client);
|
||||
//lua_pushnumber(L,client);
|
||||
lua_settable(L, -3);
|
||||
lua_pushstring(L,"request");
|
||||
push_dict_to_lua(L,rq->request);
|
||||
lua_settable(L, -3);
|
||||
lua_setglobal(L, "HTTP_REQUEST");
|
||||
|
||||
// load major apis
|
||||
if(is_file(apis))
|
||||
if (luaL_loadfile(L, apis) || lua_pcall(L, 0, 0, 0))
|
||||
{
|
||||
ERROR( "cannot start API file: [%s] %s\n", apis, lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
/*if (luaL_loadfile(L, index) || lua_pcall(L, 0, 0, 0))
|
||||
{
|
||||
text(client);
|
||||
__t(client, "Cannot run router: %s", lua_tostring(L, -1));
|
||||
}
|
||||
free(index);*/
|
||||
// clear request
|
||||
if(L)
|
||||
lua_close(L);
|
||||
if(cnf)
|
||||
free(cnf);
|
||||
if(apis)
|
||||
free(apis);
|
||||
return antd_create_task(NULL, (void*)rq, NULL,rq->client->last_io);
|
||||
//lua_close(L);
|
||||
antd_request_t *rq = (antd_request_t *)data;
|
||||
// connect to socket
|
||||
int fd = open_unix_socket();
|
||||
if(fd < 0)
|
||||
{
|
||||
antd_error(rq->client, 503, "Service unavailable");
|
||||
return antd_create_task(NULL, data, NULL, rq->client->last_io);
|
||||
}
|
||||
LOG("Connected to lua server at %d", fd);
|
||||
set_nonblock(fd);
|
||||
// write all header to lua
|
||||
antd_client_t* cl = (antd_client_t*) malloc(sizeof(antd_client_t));
|
||||
(void)memset(cl, 0, sizeof(antd_client_t));
|
||||
cl->sock = fd;
|
||||
time(&cl->last_io);
|
||||
cl->ssl = NULL;
|
||||
cl->state = ANTD_CLIENT_PLUGIN_EXEC;
|
||||
cl->z_status = 0;
|
||||
cl->z_level = ANTD_CNONE;
|
||||
cl->zstream = NULL;
|
||||
rq->client->z_level = ANTD_CNONE;
|
||||
push_dict_to_socket(cl, "request","HTTP_REQUEST", rq->request);
|
||||
antd_send(cl,"\r\n", 2);
|
||||
dput(rq->request, "LUA_CL_DATA", cl);
|
||||
antd_task_t* task = antd_create_task(process, (void *)rq, NULL, time(NULL));
|
||||
antd_task_bind_event(task, rq->client->sock, 0, TASK_EVT_ON_WRITABLE | TASK_EVT_ON_READABLE);
|
||||
antd_task_bind_event(task, fd, 0, TASK_EVT_ON_READABLE);
|
||||
return task;
|
||||
}
|
||||
void destroy()
|
||||
{
|
||||
if(core_handle)
|
||||
dlclose(core_handle);
|
||||
LOG("Exit LUA Handle");
|
||||
if(pid > 0)
|
||||
{
|
||||
kill(pid, SIGHUP);
|
||||
}
|
||||
LOG("Exit LUA Handle");
|
||||
}
|
||||
|
Reference in New Issue
Block a user