mirror of
https://github.com/lxsang/antd-lua-plugin
synced 2025-07-16 22:09:46 +02:00
Compare commits
50 Commits
add-licens
...
use_unix_d
Author | SHA1 | Date | |
---|---|---|---|
d4edd66258 | |||
f752e7e79d | |||
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 |
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
|
119
APIs/api.lua
119
APIs/api.lua
@ -1,10 +1,61 @@
|
||||
|
||||
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", table.unpack({...}) or ""))
|
||||
end
|
||||
|
||||
function LOG_ERROR(fmt,...)
|
||||
ulib.syslog(3,string.format(fmt or "ERROR", table.unpack({...}) or ""))
|
||||
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,61 @@ 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
|
||||
|
||||
-- OOP support
|
||||
--require("OOP")
|
||||
-- load sqlite helper
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,3 @@
|
||||
std = modules.std()
|
||||
bytes = modules.bytes()
|
||||
array = modules.array()
|
||||
|
||||
@ -62,6 +61,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)
|
||||
|
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
|
104
Jenkinsfile
vendored
Normal file
104
Jenkinsfile
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
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 $WORKSPACE/../ant-http/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('Build AMD64') {
|
||||
agent {
|
||||
docker {
|
||||
image 'xsangle/ci-tools:latest-amd64'
|
||||
args '-v /var/jenkins_home/workspace/ant-http:/var/jenkins_home/workspace/ant-http'
|
||||
// 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:latest-arm64'
|
||||
args '-v /var/jenkins_home/workspace/ant-http:/var/jenkins_home/workspace/ant-http'
|
||||
// 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:latest-arm'
|
||||
args '-v /var/jenkins_home/workspace/ant-http:/var/jenkins_home/workspace/ant-http'
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -131,10 +131,10 @@ AC_CONFIG_FILES([
|
||||
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 md
|
||||
if HAS_CMAKE
|
||||
SUBDIRS += ann
|
||||
endif
|
||||
EXTRA_DIST = lualib.h
|
||||
#if HAS_CMAKE
|
||||
# SUBDIRS += ann
|
||||
#endif
|
||||
EXTRA_DIST = lualib.h
|
||||
|
@ -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
|
||||
|
1248
lib/asl/antd.c
1248
lib/asl/antd.c
File diff suppressed because it is too large
Load Diff
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);
|
||||
}
|
@ -231,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;
|
||||
|
||||
}
|
||||
|
174
lib/asl/ulib.c
174
lib/asl/ulib.c
@ -3,6 +3,8 @@
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <shadow.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/sendfile.h>
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@ -145,7 +147,7 @@ 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));
|
||||
lua_pushboolean(L,0);
|
||||
@ -165,7 +167,7 @@ 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));
|
||||
lua_pushboolean(L,0);
|
||||
@ -180,6 +182,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);
|
||||
@ -370,6 +379,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);
|
||||
@ -622,6 +712,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},
|
||||
@ -643,6 +807,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;
|
||||
}
|
@ -6,13 +6,14 @@
|
||||
# Your platform. See PLATS for possible values.
|
||||
PLAT= none
|
||||
|
||||
CC= gcc -std=gnu99
|
||||
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 rcu
|
||||
RANLIB= ranlib
|
||||
AR?= ar
|
||||
LAR= $(AR) rcu
|
||||
RANLIB?= ranlib
|
||||
RM= rm -f
|
||||
|
||||
SYSCFLAGS=
|
||||
@ -56,11 +57,11 @@ o: $(ALL_O)
|
||||
a: $(ALL_A)
|
||||
|
||||
$(LUA_A): $(BASE_O)
|
||||
$(AR) $@ $(BASE_O)
|
||||
$(LAR) $@ $(BASE_O)
|
||||
$(RANLIB) $@
|
||||
|
||||
$(LUA_SO): $(BASE_O)
|
||||
gcc -shared $(BASE_O) -o $@ -ldl -lm
|
||||
$(CC) -shared $(BASE_O) -o $@ -ldl -lm
|
||||
|
||||
$(LUA_T): $(LUA_O) $(LUA_A)
|
||||
$(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
|
||||
@ -84,7 +85,7 @@ echo:
|
||||
@echo "CFLAGS= $(CFLAGS)"
|
||||
@echo "LDFLAGS= $(SYSLDFLAGS)"
|
||||
@echo "LIBS= $(LIBS)"
|
||||
@echo "AR= $(AR)"
|
||||
@echo "AR= $(LAR)"
|
||||
@echo "RANLIB= $(RANLIB)"
|
||||
@echo "RM= $(RM)"
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
// add byte array support
|
||||
typedef struct{
|
||||
int size;
|
||||
unsigned char data[1];
|
||||
unsigned char * data;
|
||||
} byte_array_t;
|
||||
|
||||
typedef struct{
|
||||
|
@ -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;
|
||||
}
|
414
lua-api.c
414
lua-api.c
@ -2,130 +2,322 @@
|
||||
#include <dlfcn.h>
|
||||
#include <antd/plugin.h>
|
||||
#include <antd/scheduler.h>
|
||||
#include <antd/dbhelper.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 <sys/select.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include "lib/lualib.h"
|
||||
|
||||
static void* core_handle = NULL;
|
||||
#define LUA_HDL_FN "lua_handle"
|
||||
#define MAX_SOCK_NAME 64
|
||||
#define SOCKET_NAME "lua.sock"
|
||||
|
||||
#define MAX_SESSION_TIMEOUT (15u * 60u) //15 min
|
||||
#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));
|
||||
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));
|
||||
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)
|
||||
{
|
||||
fd_set fd_in;
|
||||
antd_request_t *rq = (antd_request_t *)data;
|
||||
antd_client_t* cl = (antd_client_t* ) dvalue(rq->request, "LUA_CL_DATA");
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = PROCESS_TIMEOUT;
|
||||
FD_ZERO(&fd_in);
|
||||
FD_SET(rq->client->sock, &fd_in);
|
||||
FD_SET(cl->sock, &fd_in);
|
||||
int max_fdm = rq->client->sock > cl->sock ? rq->client->sock : cl->sock;
|
||||
int rc = select(max_fdm + 1, &fd_in, NULL, NULL, &timeout);
|
||||
antd_task_t* task;
|
||||
uint8_t buff[BUFFLEN];
|
||||
int ret;
|
||||
switch (rc)
|
||||
{
|
||||
case -1:
|
||||
ERROR("Error on select(): %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_WRITABLE | TASK_EVT_ON_READABLE);
|
||||
return task;
|
||||
// we have data
|
||||
default:
|
||||
// If data is on webserver
|
||||
if (FD_ISSET(rq->client->sock, &fd_in))
|
||||
{
|
||||
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(FD_ISSET(cl->sock, &fd_in))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
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_WRITABLE | TASK_EVT_ON_READABLE);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
||||
void* handle(void* data)
|
||||
{
|
||||
antd_request_t* rq = (antd_request_t*) data;
|
||||
char buf[BUFFLEN];
|
||||
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");
|
||||
htdocs(rq, buf);
|
||||
lua_pushstring(L, buf);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"apiroot");
|
||||
lua_pushstring(L, cnf);
|
||||
lua_settable(L,-3);
|
||||
|
||||
lua_pushstring(L,"tmpdir");
|
||||
tmpdir(buf);
|
||||
lua_pushstring(L, buf);
|
||||
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