From d3487d2d3c6016f17d741bcf9fe5a608023a484b Mon Sep 17 00:00:00 2001 From: samuele3hu Date: Thu, 20 Mar 2014 17:04:54 +0800 Subject: [PATCH 1/2] close #4400: Use the newest version of LuaSocket for lua --- build/android-build.py | 8 + .../project.pbxproj.REMOVED.git-id | 2 +- .../manual/LuaScriptHandlerMgr.cpp | 4 +- .../lua-bindings/manual/lua_extensions.c | 4 - .../project.pbxproj | 60 ++- .../lua-bindings/proj.win32/liblua.vcxproj | 10 +- .../proj.win32/liblua.vcxproj.filters | 104 ++--- .../{luasocket_buffer.c => buffer.c} | 2 +- .../{luasocket_buffer.h => buffer.h} | 2 +- external/lua/luasocket/except.c | 4 + external/lua/luasocket/ftp.lua | 285 ++++++++++++++ external/lua/luasocket/headers.lua | 104 +++++ external/lua/luasocket/http.lua | 354 ++++++++++++++++++ external/lua/luasocket/inet.c | 252 +++++++------ external/lua/luasocket/inet.h | 18 +- .../lua/luasocket/{luasocket_io.c => io.c} | 2 +- .../lua/luasocket/{luasocket_io.h => io.h} | 2 +- external/lua/luasocket/ltn12.lua | 298 +++++++++++++++ external/lua/luasocket/luasocket.c | 18 +- external/lua/luasocket/luasocket.h | 9 +- external/lua/luasocket/mbox.lua | 92 +++++ external/lua/luasocket/mime.c | 5 + external/lua/luasocket/mime.h | 4 +- external/lua/luasocket/mime.lua | 90 +++++ external/lua/luasocket/options.c | 108 +++++- external/lua/luasocket/options.h | 10 + external/lua/luasocket/select.c | 4 + external/lua/luasocket/serial.c | 14 +- external/lua/luasocket/smtp.lua | 256 +++++++++++++ external/lua/luasocket/socket.h | 2 +- external/lua/luasocket/socket.lua | 149 ++++++++ .../luasocket/socket_scripts.c.REMOVED.git-id | 1 - external/lua/luasocket/socket_scripts.h | 32 -- external/lua/luasocket/tcp.c | 25 +- external/lua/luasocket/tcp.h | 2 +- external/lua/luasocket/timeout.c | 4 + external/lua/luasocket/tp.lua | 126 +++++++ external/lua/luasocket/udp.c | 175 ++++----- external/lua/luasocket/unix.c | 16 +- external/lua/luasocket/unix.h | 10 +- external/lua/luasocket/url.lua | 307 +++++++++++++++ external/lua/luasocket/usocket.h | 16 + external/lua/luasocket/wsocket.c | 39 +- external/lua/luasocket/wsocket.h | 8 + templates/cocos2dx_files.json.REMOVED.git-id | 2 +- .../runtime-src/proj.win32/HelloLua.vcxproj | 20 +- .../proj.win32/HelloLua.vcxproj.user | 4 +- .../project/proj.win32/lua-empty-test.vcxproj | 18 +- .../proj.win32/lua-empty-test.vcxproj.user | 4 +- .../proj.win32/lua-tests.win32.vcxproj | 22 +- .../proj.win32/lua-tests.win32.vcxproj.user | 4 +- 51 files changed, 2639 insertions(+), 472 deletions(-) rename external/lua/luasocket/{luasocket_buffer.c => buffer.c} (99%) rename external/lua/luasocket/{luasocket_buffer.h => buffer.h} (98%) create mode 100644 external/lua/luasocket/ftp.lua create mode 100644 external/lua/luasocket/headers.lua create mode 100644 external/lua/luasocket/http.lua rename external/lua/luasocket/{luasocket_io.c => io.c} (97%) rename external/lua/luasocket/{luasocket_io.h => io.h} (98%) create mode 100644 external/lua/luasocket/ltn12.lua create mode 100644 external/lua/luasocket/mbox.lua create mode 100644 external/lua/luasocket/mime.lua create mode 100644 external/lua/luasocket/smtp.lua create mode 100644 external/lua/luasocket/socket.lua delete mode 100644 external/lua/luasocket/socket_scripts.c.REMOVED.git-id delete mode 100644 external/lua/luasocket/socket_scripts.h create mode 100644 external/lua/luasocket/tp.lua create mode 100644 external/lua/luasocket/url.lua diff --git a/build/android-build.py b/build/android-build.py index 1bdf09370a..363783cea3 100755 --- a/build/android-build.py +++ b/build/android-build.py @@ -175,6 +175,14 @@ def copy_resources(target, app_android_root): resources_dir = os.path.join(app_android_root, "../../../cpp-tests/Resources") copy_files(resources_dir, assets_res_dir) + if target == "lua-empty-test": + resources_dir = os.path.join(app_android_root, "../../../../external/lua/luasocket") + for root, dirs, files in os.walk(resources_dir): + for f in files: + if os.path.splitext(f)[1] == '.lua': + fall = os.path.join(root,f) + os.system('cp ' + fall+ ' ' + assets_dir) + def build_samples(target,ndk_build_param,android_platform,build_mode): ndk_root = check_environment_variables() diff --git a/build/cocos2d_tests.xcodeproj/project.pbxproj.REMOVED.git-id b/build/cocos2d_tests.xcodeproj/project.pbxproj.REMOVED.git-id index e4fd4a2b00..5abe38af2c 100644 --- a/build/cocos2d_tests.xcodeproj/project.pbxproj.REMOVED.git-id +++ b/build/cocos2d_tests.xcodeproj/project.pbxproj.REMOVED.git-id @@ -1 +1 @@ -2c5a07d179e9514618036dfb7cfedd3f9cf4c506 \ No newline at end of file +34cbf89cb5f2098dd2768f2106deaf1457c08866 \ No newline at end of file diff --git a/cocos/scripting/lua-bindings/manual/LuaScriptHandlerMgr.cpp b/cocos/scripting/lua-bindings/manual/LuaScriptHandlerMgr.cpp index a690f8dd42..72f26b622e 100644 --- a/cocos/scripting/lua-bindings/manual/LuaScriptHandlerMgr.cpp +++ b/cocos/scripting/lua-bindings/manual/LuaScriptHandlerMgr.cpp @@ -243,14 +243,14 @@ static void tolua_reg_script_handler_mgr_type(lua_State* tolua_S) { tolua_usertype(tolua_S, "ScheduleHandlerDelegate"); tolua_usertype(tolua_S, "ScriptHandlerMgr"); -} +} /* method: getInstance of class ScriptHandlerMgr */ #ifndef TOLUA_DISABLE_tolua_Cocos2d_ScriptHandlerMgr_getInstance00 static int tolua_Cocos2d_ScriptHandlerMgr_getInstance00(lua_State* tolua_S) { #ifndef TOLUA_RELEASE - tolua_Error tolua_err; + tolua_Error tolua_err; if (!tolua_isusertable(tolua_S,1,"ScriptHandlerMgr",0,&tolua_err) || !tolua_isnoobj(tolua_S,2,&tolua_err) ) goto tolua_lerror; diff --git a/cocos/scripting/lua-bindings/manual/lua_extensions.c b/cocos/scripting/lua-bindings/manual/lua_extensions.c index 91f3a7ba37..986036c640 100644 --- a/cocos/scripting/lua-bindings/manual/lua_extensions.c +++ b/cocos/scripting/lua-bindings/manual/lua_extensions.c @@ -7,7 +7,6 @@ extern "C" { // socket #include "luasocket/luasocket.h" #include "luasocket/mime.h" -#include "luasocket/socket_scripts.h" static luaL_Reg luax_exts[] = { {"socket.core", luaopen_socket_core}, @@ -27,9 +26,6 @@ void luaopen_lua_extensions(lua_State *L) lua_setfield(L, -2, lib->name); } lua_pop(L, 2); - - // load extensions script - luaopen_socket_scripts(L); } #if __cplusplus diff --git a/cocos/scripting/lua-bindings/proj.ios_mac/cocos2d_lua_bindings.xcodeproj/project.pbxproj b/cocos/scripting/lua-bindings/proj.ios_mac/cocos2d_lua_bindings.xcodeproj/project.pbxproj index 63eca00029..abb15d19bc 100644 --- a/cocos/scripting/lua-bindings/proj.ios_mac/cocos2d_lua_bindings.xcodeproj/project.pbxproj +++ b/cocos/scripting/lua-bindings/proj.ios_mac/cocos2d_lua_bindings.xcodeproj/project.pbxproj @@ -7,6 +7,14 @@ objects = { /* Begin PBXBuildFile section */ + 1503FAA118DA8A1C00F6518C /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 1503FA9D18DA8A1C00F6518C /* buffer.c */; }; + 1503FAA218DA8A1C00F6518C /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 1503FA9D18DA8A1C00F6518C /* buffer.c */; }; + 1503FAA318DA8A1C00F6518C /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1503FA9E18DA8A1C00F6518C /* buffer.h */; }; + 1503FAA418DA8A1C00F6518C /* buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1503FA9E18DA8A1C00F6518C /* buffer.h */; }; + 1503FAA518DA8A1C00F6518C /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 1503FA9F18DA8A1C00F6518C /* io.c */; }; + 1503FAA618DA8A1C00F6518C /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = 1503FA9F18DA8A1C00F6518C /* io.c */; }; + 1503FAA718DA8A1C00F6518C /* io.h in Headers */ = {isa = PBXBuildFile; fileRef = 1503FAA018DA8A1C00F6518C /* io.h */; }; + 1503FAA818DA8A1C00F6518C /* io.h in Headers */ = {isa = PBXBuildFile; fileRef = 1503FAA018DA8A1C00F6518C /* io.h */; }; 1A262AB818BEEF5900D2DB92 /* tolua_fix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A262AB718BEEF5900D2DB92 /* tolua_fix.cpp */; }; 1A262AB918BEEF5900D2DB92 /* tolua_fix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A262AB718BEEF5900D2DB92 /* tolua_fix.cpp */; }; 1AACE7B518BC45C200215002 /* lua_cocos2dx_auto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AACE74918BC45C200215002 /* lua_cocos2dx_auto.cpp */; }; @@ -150,14 +158,6 @@ 1ABCA23E18CD8F7D0087CE3A /* luasocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA21518CD8F7D0087CE3A /* luasocket.c */; }; 1ABCA23F18CD8F7D0087CE3A /* luasocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA21618CD8F7D0087CE3A /* luasocket.h */; }; 1ABCA24018CD8F7D0087CE3A /* luasocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA21618CD8F7D0087CE3A /* luasocket.h */; }; - 1ABCA24118CD8F7D0087CE3A /* luasocket_buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA21718CD8F7D0087CE3A /* luasocket_buffer.c */; }; - 1ABCA24218CD8F7D0087CE3A /* luasocket_buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA21718CD8F7D0087CE3A /* luasocket_buffer.c */; }; - 1ABCA24318CD8F7D0087CE3A /* luasocket_buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA21818CD8F7D0087CE3A /* luasocket_buffer.h */; }; - 1ABCA24418CD8F7D0087CE3A /* luasocket_buffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA21818CD8F7D0087CE3A /* luasocket_buffer.h */; }; - 1ABCA24518CD8F7D0087CE3A /* luasocket_io.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA21918CD8F7D0087CE3A /* luasocket_io.c */; }; - 1ABCA24618CD8F7D0087CE3A /* luasocket_io.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA21918CD8F7D0087CE3A /* luasocket_io.c */; }; - 1ABCA24718CD8F7D0087CE3A /* luasocket_io.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA21A18CD8F7D0087CE3A /* luasocket_io.h */; }; - 1ABCA24818CD8F7D0087CE3A /* luasocket_io.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA21A18CD8F7D0087CE3A /* luasocket_io.h */; }; 1ABCA24918CD8F7D0087CE3A /* mime.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA21B18CD8F7D0087CE3A /* mime.c */; }; 1ABCA24A18CD8F7D0087CE3A /* mime.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA21B18CD8F7D0087CE3A /* mime.c */; }; 1ABCA24B18CD8F7D0087CE3A /* mime.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA21C18CD8F7D0087CE3A /* mime.h */; }; @@ -174,10 +174,6 @@ 1ABCA25618CD8F7D0087CE3A /* serial.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA22118CD8F7D0087CE3A /* serial.c */; }; 1ABCA25718CD8F7D0087CE3A /* socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA22218CD8F7D0087CE3A /* socket.h */; }; 1ABCA25818CD8F7D0087CE3A /* socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA22218CD8F7D0087CE3A /* socket.h */; }; - 1ABCA25918CD8F7D0087CE3A /* socket_scripts.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA22318CD8F7D0087CE3A /* socket_scripts.c */; }; - 1ABCA25A18CD8F7D0087CE3A /* socket_scripts.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA22318CD8F7D0087CE3A /* socket_scripts.c */; }; - 1ABCA25B18CD8F7D0087CE3A /* socket_scripts.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA22418CD8F7D0087CE3A /* socket_scripts.h */; }; - 1ABCA25C18CD8F7D0087CE3A /* socket_scripts.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA22418CD8F7D0087CE3A /* socket_scripts.h */; }; 1ABCA25D18CD8F7D0087CE3A /* tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA22518CD8F7D0087CE3A /* tcp.c */; }; 1ABCA25E18CD8F7D0087CE3A /* tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = 1ABCA22518CD8F7D0087CE3A /* tcp.c */; }; 1ABCA25F18CD8F7D0087CE3A /* tcp.h in Headers */ = {isa = PBXBuildFile; fileRef = 1ABCA22618CD8F7D0087CE3A /* tcp.h */; }; @@ -214,6 +210,10 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 1503FA9D18DA8A1C00F6518C /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = buffer.c; sourceTree = ""; }; + 1503FA9E18DA8A1C00F6518C /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = buffer.h; sourceTree = ""; }; + 1503FA9F18DA8A1C00F6518C /* io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = ""; }; + 1503FAA018DA8A1C00F6518C /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = io.h; sourceTree = ""; }; 1A262AB718BEEF5900D2DB92 /* tolua_fix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tolua_fix.cpp; sourceTree = ""; }; 1AACE74618BC45A000215002 /* libluabindings Mac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libluabindings Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 1AACE74718BC45A000215002 /* libluabindings iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libluabindings iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -289,10 +289,6 @@ 1ABCA21418CD8F7D0087CE3A /* inet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inet.h; sourceTree = ""; }; 1ABCA21518CD8F7D0087CE3A /* luasocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = luasocket.c; sourceTree = ""; }; 1ABCA21618CD8F7D0087CE3A /* luasocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = luasocket.h; sourceTree = ""; }; - 1ABCA21718CD8F7D0087CE3A /* luasocket_buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = luasocket_buffer.c; sourceTree = ""; }; - 1ABCA21818CD8F7D0087CE3A /* luasocket_buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = luasocket_buffer.h; sourceTree = ""; }; - 1ABCA21918CD8F7D0087CE3A /* luasocket_io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = luasocket_io.c; sourceTree = ""; }; - 1ABCA21A18CD8F7D0087CE3A /* luasocket_io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = luasocket_io.h; sourceTree = ""; }; 1ABCA21B18CD8F7D0087CE3A /* mime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mime.c; sourceTree = ""; }; 1ABCA21C18CD8F7D0087CE3A /* mime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mime.h; sourceTree = ""; }; 1ABCA21D18CD8F7D0087CE3A /* options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = options.c; sourceTree = ""; }; @@ -301,8 +297,6 @@ 1ABCA22018CD8F7D0087CE3A /* select.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = select.h; sourceTree = ""; }; 1ABCA22118CD8F7D0087CE3A /* serial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = serial.c; sourceTree = ""; }; 1ABCA22218CD8F7D0087CE3A /* socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socket.h; sourceTree = ""; }; - 1ABCA22318CD8F7D0087CE3A /* socket_scripts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = socket_scripts.c; sourceTree = ""; }; - 1ABCA22418CD8F7D0087CE3A /* socket_scripts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = socket_scripts.h; sourceTree = ""; }; 1ABCA22518CD8F7D0087CE3A /* tcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tcp.c; sourceTree = ""; }; 1ABCA22618CD8F7D0087CE3A /* tcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcp.h; sourceTree = ""; }; 1ABCA22718CD8F7D0087CE3A /* timeout.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = timeout.c; sourceTree = ""; }; @@ -509,6 +503,10 @@ 1ABCA20E18CD8F7D0087CE3A /* luasocket */ = { isa = PBXGroup; children = ( + 1503FA9D18DA8A1C00F6518C /* buffer.c */, + 1503FA9E18DA8A1C00F6518C /* buffer.h */, + 1503FA9F18DA8A1C00F6518C /* io.c */, + 1503FAA018DA8A1C00F6518C /* io.h */, 1ABCA20F18CD8F7D0087CE3A /* auxiliar.c */, 1ABCA21018CD8F7D0087CE3A /* auxiliar.h */, 1ABCA21118CD8F7D0087CE3A /* except.c */, @@ -517,10 +515,6 @@ 1ABCA21418CD8F7D0087CE3A /* inet.h */, 1ABCA21518CD8F7D0087CE3A /* luasocket.c */, 1ABCA21618CD8F7D0087CE3A /* luasocket.h */, - 1ABCA21718CD8F7D0087CE3A /* luasocket_buffer.c */, - 1ABCA21818CD8F7D0087CE3A /* luasocket_buffer.h */, - 1ABCA21918CD8F7D0087CE3A /* luasocket_io.c */, - 1ABCA21A18CD8F7D0087CE3A /* luasocket_io.h */, 1ABCA21B18CD8F7D0087CE3A /* mime.c */, 1ABCA21C18CD8F7D0087CE3A /* mime.h */, 1ABCA21D18CD8F7D0087CE3A /* options.c */, @@ -529,8 +523,6 @@ 1ABCA22018CD8F7D0087CE3A /* select.h */, 1ABCA22118CD8F7D0087CE3A /* serial.c */, 1ABCA22218CD8F7D0087CE3A /* socket.h */, - 1ABCA22318CD8F7D0087CE3A /* socket_scripts.c */, - 1ABCA22418CD8F7D0087CE3A /* socket_scripts.h */, 1ABCA22518CD8F7D0087CE3A /* tcp.c */, 1ABCA22618CD8F7D0087CE3A /* tcp.h */, 1ABCA22718CD8F7D0087CE3A /* timeout.c */, @@ -553,13 +545,12 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1503FAA818DA8A1C00F6518C /* io.h in Headers */, 1ABCA26C18CD8F7D0087CE3A /* unix.h in Headers */, 1AACE7E018BC45C200215002 /* CCLuaBridge.h in Headers */, C0FEF4D918BE0E70001F446C /* lua_debugger.h in Headers */, 1AACE7B818BC45C200215002 /* lua_cocos2dx_auto.hpp in Headers */, 1AACE7E418BC45C200215002 /* CCLuaEngine.h in Headers */, - 1ABCA25C18CD8F7D0087CE3A /* socket_scripts.h in Headers */, - 1ABCA24818CD8F7D0087CE3A /* luasocket_io.h in Headers */, 1AACE7F018BC45C200215002 /* Cocos2dxLuaLoader.h in Headers */, 1AACE7DC18BC45C200215002 /* CCBProxy.h in Headers */, 1ABCA20D18CD8F6E0087CE3A /* tolua++.h in Headers */, @@ -573,12 +564,12 @@ 1ABCA1EB18CD8F470087CE3A /* lauxlib.h in Headers */, 1AACE81018BC45C200215002 /* lua_extensions.h in Headers */, 1AACE82018BC45C200215002 /* LuaOpengl.h in Headers */, + 1503FAA418DA8A1C00F6518C /* buffer.h in Headers */, 1ABCA26018CD8F7D0087CE3A /* tcp.h in Headers */, 1AACE80418BC45C200215002 /* lua_cocos2dx_manual.hpp in Headers */, 1AACE81818BC45C200215002 /* lua_xml_http_request.h in Headers */, 1AACE87C18BC45C200215002 /* tolua_fix.h in Headers */, 1AACE83218BC45C200215002 /* CCLuaObjcBridge.h in Headers */, - 1ABCA24418CD8F7D0087CE3A /* luasocket_buffer.h in Headers */, 1AACE82418BC45C200215002 /* LuaScriptHandlerMgr.h in Headers */, 1AACE7FC18BC45C200215002 /* lua_cocos2dx_extension_manual.h in Headers */, 2905FAD318CF12E600240AA3 /* lua_cocos2dx_ui_auto.hpp in Headers */, @@ -611,13 +602,12 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1503FAA718DA8A1C00F6518C /* io.h in Headers */, 1ABCA26B18CD8F7D0087CE3A /* unix.h in Headers */, 1AACE7DF18BC45C200215002 /* CCLuaBridge.h in Headers */, C0FEF4D818BE0E70001F446C /* lua_debugger.h in Headers */, 1AACE7B718BC45C200215002 /* lua_cocos2dx_auto.hpp in Headers */, 1AACE7E318BC45C200215002 /* CCLuaEngine.h in Headers */, - 1ABCA25B18CD8F7D0087CE3A /* socket_scripts.h in Headers */, - 1ABCA24718CD8F7D0087CE3A /* luasocket_io.h in Headers */, 1AACE7EF18BC45C200215002 /* Cocos2dxLuaLoader.h in Headers */, 1AACE7DB18BC45C200215002 /* CCBProxy.h in Headers */, 1ABCA20C18CD8F6E0087CE3A /* tolua++.h in Headers */, @@ -631,12 +621,12 @@ 1ABCA1EA18CD8F470087CE3A /* lauxlib.h in Headers */, 1AACE80F18BC45C200215002 /* lua_extensions.h in Headers */, 1AACE81F18BC45C200215002 /* LuaOpengl.h in Headers */, + 1503FAA318DA8A1C00F6518C /* buffer.h in Headers */, 1ABCA25F18CD8F7D0087CE3A /* tcp.h in Headers */, 1AACE80318BC45C200215002 /* lua_cocos2dx_manual.hpp in Headers */, 1AACE81718BC45C200215002 /* lua_xml_http_request.h in Headers */, 1AACE87B18BC45C200215002 /* tolua_fix.h in Headers */, 1AACE83118BC45C200215002 /* CCLuaObjcBridge.h in Headers */, - 1ABCA24318CD8F7D0087CE3A /* luasocket_buffer.h in Headers */, 1AACE82318BC45C200215002 /* LuaScriptHandlerMgr.h in Headers */, 1AACE7FB18BC45C200215002 /* lua_cocos2dx_extension_manual.h in Headers */, 2905FAD218CF12E600240AA3 /* lua_cocos2dx_ui_auto.hpp in Headers */, @@ -743,17 +733,18 @@ 1AACE81E18BC45C200215002 /* LuaOpengl.cpp in Sources */, 1AACE7CE18BC45C200215002 /* lua_cocos2dx_spine_auto.cpp in Sources */, 1AACE80218BC45C200215002 /* lua_cocos2dx_manual.cpp in Sources */, - 1ABCA24618CD8F7D0087CE3A /* luasocket_io.c in Sources */, 1ABCA23E18CD8F7D0087CE3A /* luasocket.c in Sources */, 1ABCA25218CD8F7D0087CE3A /* select.c in Sources */, 1ABCA24A18CD8F7D0087CE3A /* mime.c in Sources */, 1ABCA26218CD8F7D0087CE3A /* timeout.c in Sources */, + 1503FAA618DA8A1C00F6518C /* io.c in Sources */, 1ABCA26618CD8F7D0087CE3A /* udp.c in Sources */, 1AACE82218BC45C200215002 /* LuaScriptHandlerMgr.cpp in Sources */, 1ABCA23618CD8F7D0087CE3A /* except.c in Sources */, 2905FAD718CF143800240AA3 /* lua_cocos2dx_ui_manual.cpp in Sources */, 1ABCA26A18CD8F7D0087CE3A /* unix.c in Sources */, 1AACE7F218BC45C200215002 /* lua_cocos2dx_coco_studio_manual.cpp in Sources */, + 1503FAA218DA8A1C00F6518C /* buffer.c in Sources */, 1AACE80E18BC45C200215002 /* lua_extensions.c in Sources */, 1AACE7EA18BC45C200215002 /* CCLuaValue.cpp in Sources */, 1AACE7D418BC45C200215002 /* lua_cocos2dx_studio_auto.cpp in Sources */, @@ -762,10 +753,8 @@ 1AACE82618BC45C200215002 /* LuaSkeletonAnimation.cpp in Sources */, 1ABCA25E18CD8F7D0087CE3A /* tcp.c in Sources */, 1AACE80A18BC45C200215002 /* lua_cocos2dx_spine_manual.cpp in Sources */, - 1ABCA24218CD8F7D0087CE3A /* luasocket_buffer.c in Sources */, 1AACE81A18BC45C200215002 /* LuaBasicConversions.cpp in Sources */, 1AACE7EE18BC45C200215002 /* Cocos2dxLuaLoader.cpp in Sources */, - 1ABCA25A18CD8F7D0087CE3A /* socket_scripts.c in Sources */, 1AACE7DA18BC45C200215002 /* CCBProxy.cpp in Sources */, 1AACE81618BC45C200215002 /* lua_xml_http_request.cpp in Sources */, 1ABCA23A18CD8F7D0087CE3A /* inet.c in Sources */, @@ -800,17 +789,18 @@ 1AACE81D18BC45C200215002 /* LuaOpengl.cpp in Sources */, 1AACE7CD18BC45C200215002 /* lua_cocos2dx_spine_auto.cpp in Sources */, 1AACE80118BC45C200215002 /* lua_cocos2dx_manual.cpp in Sources */, - 1ABCA24518CD8F7D0087CE3A /* luasocket_io.c in Sources */, 1ABCA23D18CD8F7D0087CE3A /* luasocket.c in Sources */, 1ABCA25118CD8F7D0087CE3A /* select.c in Sources */, 1ABCA24918CD8F7D0087CE3A /* mime.c in Sources */, 1ABCA26118CD8F7D0087CE3A /* timeout.c in Sources */, + 1503FAA518DA8A1C00F6518C /* io.c in Sources */, 1ABCA26518CD8F7D0087CE3A /* udp.c in Sources */, 1AACE82118BC45C200215002 /* LuaScriptHandlerMgr.cpp in Sources */, 1ABCA23518CD8F7D0087CE3A /* except.c in Sources */, 2905FAD618CF143800240AA3 /* lua_cocos2dx_ui_manual.cpp in Sources */, 1ABCA26918CD8F7D0087CE3A /* unix.c in Sources */, 1AACE7F118BC45C200215002 /* lua_cocos2dx_coco_studio_manual.cpp in Sources */, + 1503FAA118DA8A1C00F6518C /* buffer.c in Sources */, 1AACE80D18BC45C200215002 /* lua_extensions.c in Sources */, 1AACE7E918BC45C200215002 /* CCLuaValue.cpp in Sources */, 1AACE7D318BC45C200215002 /* lua_cocos2dx_studio_auto.cpp in Sources */, @@ -819,10 +809,8 @@ 1AACE82518BC45C200215002 /* LuaSkeletonAnimation.cpp in Sources */, 1ABCA25D18CD8F7D0087CE3A /* tcp.c in Sources */, 1AACE80918BC45C200215002 /* lua_cocos2dx_spine_manual.cpp in Sources */, - 1ABCA24118CD8F7D0087CE3A /* luasocket_buffer.c in Sources */, 1AACE81918BC45C200215002 /* LuaBasicConversions.cpp in Sources */, 1AACE7ED18BC45C200215002 /* Cocos2dxLuaLoader.cpp in Sources */, - 1ABCA25918CD8F7D0087CE3A /* socket_scripts.c in Sources */, 1AACE7D918BC45C200215002 /* CCBProxy.cpp in Sources */, 1AACE81518BC45C200215002 /* lua_xml_http_request.cpp in Sources */, 1ABCA23918CD8F7D0087CE3A /* inet.c in Sources */, diff --git a/cocos/scripting/lua-bindings/proj.win32/liblua.vcxproj b/cocos/scripting/lua-bindings/proj.win32/liblua.vcxproj index 50acd4842d..929c92a21f 100644 --- a/cocos/scripting/lua-bindings/proj.win32/liblua.vcxproj +++ b/cocos/scripting/lua-bindings/proj.win32/liblua.vcxproj @@ -12,15 +12,14 @@ + + - - - @@ -65,16 +64,15 @@ + + - - - diff --git a/cocos/scripting/lua-bindings/proj.win32/liblua.vcxproj.filters b/cocos/scripting/lua-bindings/proj.win32/liblua.vcxproj.filters index 5f1a7e127e..26eec8ffcb 100644 --- a/cocos/scripting/lua-bindings/proj.win32/liblua.vcxproj.filters +++ b/cocos/scripting/lua-bindings/proj.win32/liblua.vcxproj.filters @@ -13,6 +13,12 @@ {c36f2204-a252-47c0-b36c-b84cda218746} + + {24fae6d6-ebb5-4da1-b0da-3f3845a9e9a9} + + + {cc863463-a948-487a-aacd-dc233c3e5200} + @@ -111,12 +117,6 @@ luasocket - - luasocket - - - luasocket - luasocket @@ -126,36 +126,39 @@ luasocket - - luasocket - luasocket luasocket - - luasocket - - - luasocket - - - luasocket - - - luasocket - - - luasocket - luasocket luasocket + + luasocket + + + luasocket + + + tolua + + + tolua + + + tolua + + + tolua + + + tolua + @@ -251,27 +254,9 @@ luasocket - - luasocket - - - luasocket - - - luasocket - - - luasocket - luasocket - - luasocket - - - luasocket - luasocket @@ -284,27 +269,42 @@ luasocket - - luasocket - luasocket luasocket - - luasocket - - - luasocket - luasocket luasocket + + luasocket + + + luasocket + + + tolua + + + tolua + + + luajit + + + luajit + + + luajit + + + luajit + @@ -362,4 +362,4 @@ script - + \ No newline at end of file diff --git a/external/lua/luasocket/luasocket_buffer.c b/external/lua/luasocket/buffer.c similarity index 99% rename from external/lua/luasocket/luasocket_buffer.c rename to external/lua/luasocket/buffer.c index 13140bccc0..4ef4e8eb5c 100644 --- a/external/lua/luasocket/luasocket_buffer.c +++ b/external/lua/luasocket/buffer.c @@ -5,7 +5,7 @@ #include "lua.h" #include "lauxlib.h" -#include "luasocket_buffer.h" +#include "buffer.h" /*=========================================================================*\ * Internal function prototypes diff --git a/external/lua/luasocket/luasocket_buffer.h b/external/lua/luasocket/buffer.h similarity index 98% rename from external/lua/luasocket/luasocket_buffer.h rename to external/lua/luasocket/buffer.h index 2456cd386b..1281bb3914 100644 --- a/external/lua/luasocket/luasocket_buffer.h +++ b/external/lua/luasocket/buffer.h @@ -17,7 +17,7 @@ \*=========================================================================*/ #include "lua.h" -#include "luasocket_io.h" +#include "io.h" #include "timeout.h" /* buffer size in bytes */ diff --git a/external/lua/luasocket/except.c b/external/lua/luasocket/except.c index 1d1ade0ee0..002e701068 100644 --- a/external/lua/luasocket/except.c +++ b/external/lua/luasocket/except.c @@ -92,6 +92,10 @@ static int global_protect(lua_State *L) { * Init module \*-------------------------------------------------------------------------*/ int except_open(lua_State *L) { +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + luaL_setfuncs(L, func, 0); +#else luaL_openlib(L, NULL, func, 0); +#endif return 0; } diff --git a/external/lua/luasocket/ftp.lua b/external/lua/luasocket/ftp.lua new file mode 100644 index 0000000000..ea1145bcb9 --- /dev/null +++ b/external/lua/luasocket/ftp.lua @@ -0,0 +1,285 @@ +----------------------------------------------------------------------------- +-- FTP support for the Lua language +-- LuaSocket toolkit. +-- Author: Diego Nehab +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local table = require("table") +local string = require("string") +local math = require("math") +local socket = require("socket") +local url = require("socket.url") +local tp = require("socket.tp") +local ltn12 = require("ltn12") +socket.ftp = {} +local _M = socket.ftp +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- timeout in seconds before the program gives up on a connection +_M.TIMEOUT = 60 +-- default port for ftp service +_M.PORT = 21 +-- this is the default anonymous password. used when no password is +-- provided in url. should be changed to your e-mail. +_M.USER = "ftp" +_M.PASSWORD = "anonymous@anonymous.org" + +----------------------------------------------------------------------------- +-- Low level FTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function _M.open(server, port, create) + local tp = socket.try(tp.connect(server, port or _M.PORT, _M.TIMEOUT, create)) + local f = base.setmetatable({ tp = tp }, metat) + -- make sure everything gets closed in an exception + f.try = socket.newtry(function() f:close() end) + return f +end + +function metat.__index:portconnect() + self.try(self.server:settimeout(_M.TIMEOUT)) + self.data = self.try(self.server:accept()) + self.try(self.data:settimeout(_M.TIMEOUT)) +end + +function metat.__index:pasvconnect() + self.data = self.try(socket.tcp()) + self.try(self.data:settimeout(_M.TIMEOUT)) + self.try(self.data:connect(self.pasvt.ip, self.pasvt.port)) +end + +function metat.__index:login(user, password) + self.try(self.tp:command("user", user or _M.USER)) + local code, reply = self.try(self.tp:check{"2..", 331}) + if code == 331 then + self.try(self.tp:command("pass", password or _M.PASSWORD)) + self.try(self.tp:check("2..")) + end + return 1 +end + +function metat.__index:pasv() + self.try(self.tp:command("pasv")) + local code, reply = self.try(self.tp:check("2..")) + local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" + local a, b, c, d, p1, p2 = socket.skip(2, string.find(reply, pattern)) + self.try(a and b and c and d and p1 and p2, reply) + self.pasvt = { + ip = string.format("%d.%d.%d.%d", a, b, c, d), + port = p1*256 + p2 + } + if self.server then + self.server:close() + self.server = nil + end + return self.pasvt.ip, self.pasvt.port +end + +function metat.__index:port(ip, port) + self.pasvt = nil + if not ip then + ip, port = self.try(self.tp:getcontrol():getsockname()) + self.server = self.try(socket.bind(ip, 0)) + ip, port = self.try(self.server:getsockname()) + self.try(self.server:settimeout(_M.TIMEOUT)) + end + local pl = math.mod(port, 256) + local ph = (port - pl)/256 + local arg = string.gsub(string.format("%s,%d,%d", ip, ph, pl), "%.", ",") + self.try(self.tp:command("port", arg)) + self.try(self.tp:check("2..")) + return 1 +end + +function metat.__index:send(sendt) + self.try(self.pasvt or self.server, "need port or pasv first") + -- if there is a pasvt table, we already sent a PASV command + -- we just get the data connection into self.data + if self.pasvt then self:pasvconnect() end + -- get the transfer argument and command + local argument = sendt.argument or + url.unescape(string.gsub(sendt.path or "", "^[/\\]", "")) + if argument == "" then argument = nil end + local command = sendt.command or "stor" + -- send the transfer command and check the reply + self.try(self.tp:command(command, argument)) + local code, reply = self.try(self.tp:check{"2..", "1.."}) + -- if there is not a a pasvt table, then there is a server + -- and we already sent a PORT command + if not self.pasvt then self:portconnect() end + -- get the sink, source and step for the transfer + local step = sendt.step or ltn12.pump.step + local readt = {self.tp.c} + local checkstep = function(src, snk) + -- check status in control connection while downloading + local readyt = socket.select(readt, nil, 0) + if readyt[tp] then code = self.try(self.tp:check("2..")) end + return step(src, snk) + end + local sink = socket.sink("close-when-done", self.data) + -- transfer all data and check error + self.try(ltn12.pump.all(sendt.source, sink, checkstep)) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + -- done with data connection + self.data:close() + -- find out how many bytes were sent + local sent = socket.skip(1, self.data:getstats()) + self.data = nil + return sent +end + +function metat.__index:receive(recvt) + self.try(self.pasvt or self.server, "need port or pasv first") + if self.pasvt then self:pasvconnect() end + local argument = recvt.argument or + url.unescape(string.gsub(recvt.path or "", "^[/\\]", "")) + if argument == "" then argument = nil end + local command = recvt.command or "retr" + self.try(self.tp:command(command, argument)) + local code,reply = self.try(self.tp:check{"1..", "2.."}) + if (code >= 200) and (code <= 299) then + recvt.sink(reply) + return 1 + end + if not self.pasvt then self:portconnect() end + local source = socket.source("until-closed", self.data) + local step = recvt.step or ltn12.pump.step + self.try(ltn12.pump.all(source, recvt.sink, step)) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + self.data:close() + self.data = nil + return 1 +end + +function metat.__index:cwd(dir) + self.try(self.tp:command("cwd", dir)) + self.try(self.tp:check(250)) + return 1 +end + +function metat.__index:type(type) + self.try(self.tp:command("type", type)) + self.try(self.tp:check(200)) + return 1 +end + +function metat.__index:greet() + local code = self.try(self.tp:check{"1..", "2.."}) + if string.find(code, "1..") then self.try(self.tp:check("2..")) end + return 1 +end + +function metat.__index:quit() + self.try(self.tp:command("quit")) + self.try(self.tp:check("2..")) + return 1 +end + +function metat.__index:close() + if self.data then self.data:close() end + if self.server then self.server:close() end + return self.tp:close() +end + +----------------------------------------------------------------------------- +-- High level FTP API +----------------------------------------------------------------------------- +local function override(t) + if t.url then + local u = url.parse(t.url) + for i,v in base.pairs(t) do + u[i] = v + end + return u + else return t end +end + +local function tput(putt) + putt = override(putt) + socket.try(putt.host, "missing hostname") + local f = _M.open(putt.host, putt.port, putt.create) + f:greet() + f:login(putt.user, putt.password) + if putt.type then f:type(putt.type) end + f:pasv() + local sent = f:send(putt) + f:quit() + f:close() + return sent +end + +local default = { + path = "/", + scheme = "ftp" +} + +local function parse(u) + local t = socket.try(url.parse(u, default)) + socket.try(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'") + socket.try(t.host, "missing hostname") + local pat = "^type=(.)$" + if t.params then + t.type = socket.skip(2, string.find(t.params, pat)) + socket.try(t.type == "a" or t.type == "i", + "invalid type '" .. t.type .. "'") + end + return t +end + +local function sput(u, body) + local putt = parse(u) + putt.source = ltn12.source.string(body) + return tput(putt) +end + +_M.put = socket.protect(function(putt, body) + if base.type(putt) == "string" then return sput(putt, body) + else return tput(putt) end +end) + +local function tget(gett) + gett = override(gett) + socket.try(gett.host, "missing hostname") + local f = _M.open(gett.host, gett.port, gett.create) + f:greet() + f:login(gett.user, gett.password) + if gett.type then f:type(gett.type) end + f:pasv() + f:receive(gett) + f:quit() + return f:close() +end + +local function sget(u) + local gett = parse(u) + local t = {} + gett.sink = ltn12.sink.table(t) + tget(gett) + return table.concat(t) +end + +_M.command = socket.protect(function(cmdt) + cmdt = override(cmdt) + socket.try(cmdt.host, "missing hostname") + socket.try(cmdt.command, "missing command") + local f = open(cmdt.host, cmdt.port, cmdt.create) + f:greet() + f:login(cmdt.user, cmdt.password) + f.try(f.tp:command(cmdt.command, cmdt.argument)) + if cmdt.check then f.try(f.tp:check(cmdt.check)) end + f:quit() + return f:close() +end) + +_M.get = socket.protect(function(gett) + if base.type(gett) == "string" then return sget(gett) + else return tget(gett) end +end) + +return _M \ No newline at end of file diff --git a/external/lua/luasocket/headers.lua b/external/lua/luasocket/headers.lua new file mode 100644 index 0000000000..1eb8223b9d --- /dev/null +++ b/external/lua/luasocket/headers.lua @@ -0,0 +1,104 @@ +----------------------------------------------------------------------------- +-- Canonic header field capitalization +-- LuaSocket toolkit. +-- Author: Diego Nehab +----------------------------------------------------------------------------- +local socket = require("socket") +socket.headers = {} +local _M = socket.headers + +_M.canonic = { + ["accept"] = "Accept", + ["accept-charset"] = "Accept-Charset", + ["accept-encoding"] = "Accept-Encoding", + ["accept-language"] = "Accept-Language", + ["accept-ranges"] = "Accept-Ranges", + ["action"] = "Action", + ["alternate-recipient"] = "Alternate-Recipient", + ["age"] = "Age", + ["allow"] = "Allow", + ["arrival-date"] = "Arrival-Date", + ["authorization"] = "Authorization", + ["bcc"] = "Bcc", + ["cache-control"] = "Cache-Control", + ["cc"] = "Cc", + ["comments"] = "Comments", + ["connection"] = "Connection", + ["content-description"] = "Content-Description", + ["content-disposition"] = "Content-Disposition", + ["content-encoding"] = "Content-Encoding", + ["content-id"] = "Content-ID", + ["content-language"] = "Content-Language", + ["content-length"] = "Content-Length", + ["content-location"] = "Content-Location", + ["content-md5"] = "Content-MD5", + ["content-range"] = "Content-Range", + ["content-transfer-encoding"] = "Content-Transfer-Encoding", + ["content-type"] = "Content-Type", + ["cookie"] = "Cookie", + ["date"] = "Date", + ["diagnostic-code"] = "Diagnostic-Code", + ["dsn-gateway"] = "DSN-Gateway", + ["etag"] = "ETag", + ["expect"] = "Expect", + ["expires"] = "Expires", + ["final-log-id"] = "Final-Log-ID", + ["final-recipient"] = "Final-Recipient", + ["from"] = "From", + ["host"] = "Host", + ["if-match"] = "If-Match", + ["if-modified-since"] = "If-Modified-Since", + ["if-none-match"] = "If-None-Match", + ["if-range"] = "If-Range", + ["if-unmodified-since"] = "If-Unmodified-Since", + ["in-reply-to"] = "In-Reply-To", + ["keywords"] = "Keywords", + ["last-attempt-date"] = "Last-Attempt-Date", + ["last-modified"] = "Last-Modified", + ["location"] = "Location", + ["max-forwards"] = "Max-Forwards", + ["message-id"] = "Message-ID", + ["mime-version"] = "MIME-Version", + ["original-envelope-id"] = "Original-Envelope-ID", + ["original-recipient"] = "Original-Recipient", + ["pragma"] = "Pragma", + ["proxy-authenticate"] = "Proxy-Authenticate", + ["proxy-authorization"] = "Proxy-Authorization", + ["range"] = "Range", + ["received"] = "Received", + ["received-from-mta"] = "Received-From-MTA", + ["references"] = "References", + ["referer"] = "Referer", + ["remote-mta"] = "Remote-MTA", + ["reply-to"] = "Reply-To", + ["reporting-mta"] = "Reporting-MTA", + ["resent-bcc"] = "Resent-Bcc", + ["resent-cc"] = "Resent-Cc", + ["resent-date"] = "Resent-Date", + ["resent-from"] = "Resent-From", + ["resent-message-id"] = "Resent-Message-ID", + ["resent-reply-to"] = "Resent-Reply-To", + ["resent-sender"] = "Resent-Sender", + ["resent-to"] = "Resent-To", + ["retry-after"] = "Retry-After", + ["return-path"] = "Return-Path", + ["sender"] = "Sender", + ["server"] = "Server", + ["smtp-remote-recipient"] = "SMTP-Remote-Recipient", + ["status"] = "Status", + ["subject"] = "Subject", + ["te"] = "TE", + ["to"] = "To", + ["trailer"] = "Trailer", + ["transfer-encoding"] = "Transfer-Encoding", + ["upgrade"] = "Upgrade", + ["user-agent"] = "User-Agent", + ["vary"] = "Vary", + ["via"] = "Via", + ["warning"] = "Warning", + ["will-retry-until"] = "Will-Retry-Until", + ["www-authenticate"] = "WWW-Authenticate", + ["x-mailer"] = "X-Mailer", +} + +return _M \ No newline at end of file diff --git a/external/lua/luasocket/http.lua b/external/lua/luasocket/http.lua new file mode 100644 index 0000000000..ac4b2d61eb --- /dev/null +++ b/external/lua/luasocket/http.lua @@ -0,0 +1,354 @@ +----------------------------------------------------------------------------- +-- HTTP/1.1 client support for the Lua language. +-- LuaSocket toolkit. +-- Author: Diego Nehab +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +------------------------------------------------------------------------------- +local socket = require("socket") +local url = require("socket.url") +local ltn12 = require("ltn12") +local mime = require("mime") +local string = require("string") +local headers = require("socket.headers") +local base = _G +local table = require("table") +socket.http = {} +local _M = socket.http + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- connection timeout in seconds +TIMEOUT = 60 +-- default port for document retrieval +_M.PORT = 80 +-- user agent field sent in request +_M.USERAGENT = socket._VERSION + +----------------------------------------------------------------------------- +-- Reads MIME headers from a connection, unfolding where needed +----------------------------------------------------------------------------- +local function receiveheaders(sock, headers) + local line, name, value, err + headers = headers or {} + -- get first line + line, err = sock:receive() + if err then return nil, err end + -- headers go until a blank line is found + while line ~= "" do + -- get field-name and value + name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)")) + if not (name and value) then return nil, "malformed reponse headers" end + name = string.lower(name) + -- get next line (value might be folded) + line, err = sock:receive() + if err then return nil, err end + -- unfold any folded values + while string.find(line, "^%s") do + value = value .. line + line = sock:receive() + if err then return nil, err end + end + -- save pair in table + if headers[name] then headers[name] = headers[name] .. ", " .. value + else headers[name] = value end + end + return headers +end + +----------------------------------------------------------------------------- +-- Extra sources and sinks +----------------------------------------------------------------------------- +socket.sourcet["http-chunked"] = function(sock, headers) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + -- get chunk size, skip extention + local line, err = sock:receive() + if err then return nil, err end + local size = base.tonumber(string.gsub(line, ";.*", ""), 16) + if not size then return nil, "invalid chunk size" end + -- was it the last chunk? + if size > 0 then + -- if not, get chunk and skip terminating CRLF + local chunk, err, part = sock:receive(size) + if chunk then sock:receive() end + return chunk, err + else + -- if it was, read trailers into headers table + headers, err = receiveheaders(sock, headers) + if not headers then return nil, err end + end + end + }) +end + +socket.sinkt["http-chunked"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if not chunk then return sock:send("0\r\n\r\n") end + local size = string.format("%X\r\n", string.len(chunk)) + return sock:send(size .. chunk .. "\r\n") + end + }) +end + +----------------------------------------------------------------------------- +-- Low level HTTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function _M.open(host, port, create) + -- create socket with user connect function, or with default + local c = socket.try((create or socket.tcp)()) + local h = base.setmetatable({ c = c }, metat) + -- create finalized try + h.try = socket.newtry(function() h:close() end) + -- set timeout before connecting + h.try(c:settimeout(_M.TIMEOUT)) + h.try(c:connect(host, port or _M.PORT)) + -- here everything worked + return h +end + +function metat.__index:sendrequestline(method, uri) + local reqline = string.format("%s %s HTTP/1.1\r\n", method or "GET", uri) + return self.try(self.c:send(reqline)) +end + +function metat.__index:sendheaders(tosend) + local canonic = headers.canonic + local h = "\r\n" + for f, v in base.pairs(tosend) do + h = (canonic[f] or f) .. ": " .. v .. "\r\n" .. h + end + self.try(self.c:send(h)) + return 1 +end + +function metat.__index:sendbody(headers, source, step) + source = source or ltn12.source.empty() + step = step or ltn12.pump.step + -- if we don't know the size in advance, send chunked and hope for the best + local mode = "http-chunked" + if headers["content-length"] then mode = "keep-open" end + return self.try(ltn12.pump.all(source, socket.sink(mode, self.c), step)) +end + +function metat.__index:receivestatusline() + local status = self.try(self.c:receive(5)) + -- identify HTTP/0.9 responses, which do not contain a status line + -- this is just a heuristic, but is what the RFC recommends + if status ~= "HTTP/" then return nil, status end + -- otherwise proceed reading a status line + status = self.try(self.c:receive("*l", status)) + local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)")) + return self.try(base.tonumber(code), status) +end + +function metat.__index:receiveheaders() + return self.try(receiveheaders(self.c)) +end + +function metat.__index:receivebody(headers, sink, step) + sink = sink or ltn12.sink.null() + step = step or ltn12.pump.step + local length = base.tonumber(headers["content-length"]) + local t = headers["transfer-encoding"] -- shortcut + local mode = "default" -- connection close + if t and t ~= "identity" then mode = "http-chunked" + elseif base.tonumber(headers["content-length"]) then mode = "by-length" end + return self.try(ltn12.pump.all(socket.source(mode, self.c, length), + sink, step)) +end + +function metat.__index:receive09body(status, sink, step) + local source = ltn12.source.rewind(socket.source("until-closed", self.c)) + source(status) + return self.try(ltn12.pump.all(source, sink, step)) +end + +function metat.__index:close() + return self.c:close() +end + +----------------------------------------------------------------------------- +-- High level HTTP API +----------------------------------------------------------------------------- +local function adjusturi(reqt) + local u = reqt + -- if there is a proxy, we need the full url. otherwise, just a part. + if not reqt.proxy and not PROXY then + u = { + path = socket.try(reqt.path, "invalid path 'nil'"), + params = reqt.params, + query = reqt.query, + fragment = reqt.fragment + } + end + return url.build(u) +end + +local function adjustproxy(reqt) + local proxy = reqt.proxy or PROXY + if proxy then + proxy = url.parse(proxy) + return proxy.host, proxy.port or 3128 + else + return reqt.host, reqt.port + end +end + +local function adjustheaders(reqt) + -- default headers + local lower = { + ["user-agent"] = _M.USERAGENT, + ["host"] = reqt.host, + ["connection"] = "close, TE", + ["te"] = "trailers" + } + -- if we have authentication information, pass it along + if reqt.user and reqt.password then + lower["authorization"] = + "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password)) + end + -- override with user headers + for i,v in base.pairs(reqt.headers or lower) do + lower[string.lower(i)] = v + end + return lower +end + +-- default url parts +local default = { + host = "", + port = _M.PORT, + path ="/", + scheme = "http" +} + +local function adjustrequest(reqt) + -- parse url if provided + local nreqt = reqt.url and url.parse(reqt.url, default) or {} + -- explicit components override url + for i,v in base.pairs(reqt) do nreqt[i] = v end + if nreqt.port == "" then nreqt.port = 80 end + socket.try(nreqt.host and nreqt.host ~= "", + "invalid host '" .. base.tostring(nreqt.host) .. "'") + -- compute uri if user hasn't overriden + nreqt.uri = reqt.uri or adjusturi(nreqt) + -- ajust host and port if there is a proxy + nreqt.host, nreqt.port = adjustproxy(nreqt) + -- adjust headers in request + nreqt.headers = adjustheaders(nreqt) + return nreqt +end + +local function shouldredirect(reqt, code, headers) + return headers.location and + string.gsub(headers.location, "%s", "") ~= "" and + (reqt.redirect ~= false) and + (code == 301 or code == 302 or code == 303 or code == 307) and + (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD") + and (not reqt.nredirects or reqt.nredirects < 5) +end + +local function shouldreceivebody(reqt, code) + if reqt.method == "HEAD" then return nil end + if code == 204 or code == 304 then return nil end + if code >= 100 and code < 200 then return nil end + return 1 +end + +-- forward declarations +local trequest, tredirect + +--[[local]] function tredirect(reqt, location) + local result, code, headers, status = trequest { + -- the RFC says the redirect URL has to be absolute, but some + -- servers do not respect that + url = url.absolute(reqt.url, location), + source = reqt.source, + sink = reqt.sink, + headers = reqt.headers, + proxy = reqt.proxy, + nredirects = (reqt.nredirects or 0) + 1, + create = reqt.create + } + -- pass location header back as a hint we redirected + headers = headers or {} + headers.location = headers.location or location + return result, code, headers, status +end + +--[[local]] function trequest(reqt) + -- we loop until we get what we want, or + -- until we are sure there is no way to get it + local nreqt = adjustrequest(reqt) + local h = _M.open(nreqt.host, nreqt.port, nreqt.create) + -- send request line and headers + h:sendrequestline(nreqt.method, nreqt.uri) + h:sendheaders(nreqt.headers) + -- if there is a body, send it + if nreqt.source then + h:sendbody(nreqt.headers, nreqt.source, nreqt.step) + end + local code, status = h:receivestatusline() + -- if it is an HTTP/0.9 server, simply get the body and we are done + if not code then + h:receive09body(status, nreqt.sink, nreqt.step) + return 1, 200 + end + local headers + -- ignore any 100-continue messages + while code == 100 do + headers = h:receiveheaders() + code, status = h:receivestatusline() + end + headers = h:receiveheaders() + -- at this point we should have a honest reply from the server + -- we can't redirect if we already used the source, so we report the error + if shouldredirect(nreqt, code, headers) and not nreqt.source then + h:close() + return tredirect(reqt, headers.location) + end + -- here we are finally done + if shouldreceivebody(nreqt, code) then + h:receivebody(headers, nreqt.sink, nreqt.step) + end + h:close() + return 1, code, headers, status +end + +local function srequest(u, b) + local t = {} + local reqt = { + url = u, + sink = ltn12.sink.table(t) + } + if b then + reqt.source = ltn12.source.string(b) + reqt.headers = { + ["content-length"] = string.len(b), + ["content-type"] = "application/x-www-form-urlencoded" + } + reqt.method = "POST" + end + local code, headers, status = socket.skip(1, trequest(reqt)) + return table.concat(t), code, headers, status +end + +_M.request = socket.protect(function(reqt, body) + if base.type(reqt) == "string" then return srequest(reqt, body) + else return trequest(reqt) end +end) + +return _M \ No newline at end of file diff --git a/external/lua/luasocket/inet.c b/external/lua/luasocket/inet.c index 16f709387c..1a411f65ec 100644 --- a/external/lua/luasocket/inet.c +++ b/external/lua/luasocket/inet.c @@ -3,6 +3,7 @@ * LuaSocket toolkit \*=========================================================================*/ #include +#include #include #include "lua.h" @@ -30,24 +31,6 @@ static luaL_Reg func[] = { { NULL, NULL} }; -#ifdef _WINDOWS_ -/****luodx patch for windows xp start**/ -char* win32xp_inet_ntop(int family, PVOID src, char* dest, size_t length) -{ - char* result = inet_ntoa(*(IN_ADDR*)src); - if (result != NULL){ - strcpy(dest, result); - } - return result; -} - -int win32xp_inet_pton(int family, const char* string, PVOID dest) { - return inet_aton(string, (IN_ADDR*)dest); -} -/****luodx patch for windows xp end**/ -#endif - - /*=========================================================================*\ * Exported functions \*=========================================================================*/ @@ -58,7 +41,11 @@ int inet_open(lua_State *L) { lua_pushstring(L, "dns"); lua_newtable(L); +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + luaL_setfuncs(L, func, 0); +#else luaL_openlib(L, NULL, func, 0); +#endif lua_settable(L, -3); return 0; } @@ -97,24 +84,22 @@ static int inet_global_tohostname(lua_State *L) { } static int inet_global_getnameinfo(lua_State *L) { + char hbuf[NI_MAXHOST]; + char sbuf[NI_MAXSERV]; int i, ret; - char host[1024]; - char serv[32]; struct addrinfo hints; struct addrinfo *resolved, *iter; - const char *node = luaL_optstring(L, 1, NULL); - const char *service = luaL_optstring(L, 2, NULL); + const char *host = luaL_optstring(L, 1, NULL); + const char *serv = luaL_optstring(L, 2, NULL); - if (!(node || service)) - luaL_error(L, "You have to specify a hostname, a service, or both"); + if (!(host || serv)) + luaL_error(L, "host and serv cannot be both nil"); memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_family = PF_UNSPEC; - /* getaddrinfo must get a node and a service argument */ - ret = getaddrinfo(node ? node : "127.0.0.1", service ? service : "7", - &hints, &resolved); + ret = getaddrinfo(host, serv, &hints, &resolved); if (ret != 0) { lua_pushnil(L); lua_pushstring(L, socket_gaistrerror(ret)); @@ -123,19 +108,19 @@ static int inet_global_getnameinfo(lua_State *L) { lua_newtable(L); for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) { - getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen, host, - node ? (socklen_t) sizeof(host) : 0, serv, service ? (socklen_t) sizeof(serv) : 0, 0); - - if (node) { + getnameinfo(iter->ai_addr, (socklen_t) iter->ai_addrlen, + hbuf, host? (socklen_t) sizeof(hbuf): 0, + sbuf, serv? (socklen_t) sizeof(sbuf): 0, 0); + if (host) { lua_pushnumber(L, i); - lua_pushstring(L, host); + lua_pushstring(L, hbuf); lua_settable(L, -3); } } freeaddrinfo(resolved); - if (service) { - lua_pushstring(L, serv); + if (serv) { + lua_pushstring(L, sbuf); return 2; } else { return 1; @@ -194,9 +179,14 @@ static int inet_global_getaddrinfo(lua_State *L) } lua_newtable(L); for (iterator = resolved; iterator; iterator = iterator->ai_next) { - char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; - getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen, hbuf, - (socklen_t) sizeof(hbuf), sbuf, 0, NI_NUMERICHOST); + char hbuf[NI_MAXHOST]; + ret = getnameinfo(iterator->ai_addr, (socklen_t) iterator->ai_addrlen, + hbuf, (socklen_t) sizeof(hbuf), NULL, 0, NI_NUMERICHOST); + if (ret){ + lua_pushnil(L); + lua_pushstring(L, socket_gaistrerror(ret)); + return 2; + } lua_pushnumber(L, i); lua_newtable(L); switch (iterator->ai_family) { @@ -209,7 +199,7 @@ static int inet_global_getaddrinfo(lua_State *L) lua_pushliteral(L, "family"); lua_pushliteral(L, "inet6"); lua_settable(L, -3); - break;; + break; } lua_pushliteral(L, "addr"); lua_pushstring(L, hbuf); @@ -221,7 +211,6 @@ static int inet_global_getaddrinfo(lua_State *L) return 1; } - /*-------------------------------------------------------------------------*\ * Gets the host name \*-------------------------------------------------------------------------*/ @@ -239,8 +228,6 @@ static int inet_global_gethostname(lua_State *L) } } - - /*=========================================================================*\ * Lua methods \*=========================================================================*/ @@ -249,44 +236,34 @@ static int inet_global_gethostname(lua_State *L) \*-------------------------------------------------------------------------*/ int inet_meth_getpeername(lua_State *L, p_socket ps, int family) { - switch (family) { - case PF_INET: { - struct sockaddr_in peer; - socklen_t peer_len = sizeof(peer); - char name[INET_ADDRSTRLEN]; - if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { - lua_pushnil(L); - lua_pushstring(L, socket_strerror(errno)); - return 2; - } else { - my_inet_ntop(family, &peer.sin_addr, name, sizeof(name)); - lua_pushstring(L, name); - lua_pushnumber(L, ntohs(peer.sin_port)); - lua_pushliteral(L, "inet"); - return 3; - } - } - case PF_INET6: { - struct sockaddr_in6 peer; - socklen_t peer_len = sizeof(peer); - char name[INET6_ADDRSTRLEN]; - if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { - lua_pushnil(L); - lua_pushstring(L, socket_strerror(errno)); - return 2; - } else { - my_inet_ntop(family, &peer.sin6_addr, name, sizeof(name)); - lua_pushstring(L, name); - lua_pushnumber(L, ntohs(peer.sin6_port)); - lua_pushliteral(L, "inet6"); - return 3; - } - } - default: - lua_pushnil(L); - lua_pushfstring(L, "unknown family %d", family); - return 2; + int err; + struct sockaddr_storage peer; + socklen_t peer_len = sizeof(peer); + char name[INET6_ADDRSTRLEN]; + char port[6]; /* 65535 = 5 bytes + 0 to terminate it */ + if (getpeername(*ps, (SA *) &peer, &peer_len) < 0) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(errno)); + return 2; } + err = getnameinfo((struct sockaddr *) &peer, peer_len, + name, INET6_ADDRSTRLEN, + port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV); + if (err) { + lua_pushnil(L); + lua_pushstring(L, gai_strerror(err)); + return 2; + } + lua_pushstring(L, name); + lua_pushinteger(L, (int) strtol(port, (char **) NULL, 10)); + if (family == PF_INET) { + lua_pushliteral(L, "inet"); + } else if (family == PF_INET6) { + lua_pushliteral(L, "inet6"); + } else { + lua_pushliteral(L, "uknown family"); + } + return 3; } /*-------------------------------------------------------------------------*\ @@ -294,44 +271,33 @@ int inet_meth_getpeername(lua_State *L, p_socket ps, int family) \*-------------------------------------------------------------------------*/ int inet_meth_getsockname(lua_State *L, p_socket ps, int family) { - switch (family) { - case PF_INET: { - struct sockaddr_in local; - socklen_t local_len = sizeof(local); - char name[INET_ADDRSTRLEN]; - if (getsockname(*ps, (SA *) &local, &local_len) < 0) { - lua_pushnil(L); - lua_pushstring(L, socket_strerror(errno)); - return 2; - } else { - my_inet_ntop(family, &local.sin_addr, name, sizeof(name)); - lua_pushstring(L, name); - lua_pushnumber(L, ntohs(local.sin_port)); - lua_pushliteral(L, "inet"); - return 3; - } - } - case PF_INET6: { - struct sockaddr_in6 local; - socklen_t local_len = sizeof(local); - char name[INET6_ADDRSTRLEN]; - if (getsockname(*ps, (SA *) &local, &local_len) < 0) { - lua_pushnil(L); - lua_pushstring(L, socket_strerror(errno)); - return 2; - } else { - my_inet_ntop(family, &local.sin6_addr, name, sizeof(name)); - lua_pushstring(L, name); - lua_pushnumber(L, ntohs(local.sin6_port)); - lua_pushliteral(L, "inet6"); - return 3; - } - } - default: - lua_pushnil(L); - lua_pushfstring(L, "unknown family %d", family); - return 2; + int err; + struct sockaddr_storage peer; + socklen_t peer_len = sizeof(peer); + char name[INET6_ADDRSTRLEN]; + char port[6]; /* 65535 = 5 bytes + 0 to terminate it */ + if (getsockname(*ps, (SA *) &peer, &peer_len) < 0) { + lua_pushnil(L); + lua_pushstring(L, socket_strerror(errno)); + return 2; } + err=getnameinfo((struct sockaddr *)&peer, peer_len, + name, INET6_ADDRSTRLEN, port, 6, NI_NUMERICHOST | NI_NUMERICSERV); + if (err) { + lua_pushnil(L); + lua_pushstring(L, gai_strerror(err)); + return 2; + } + lua_pushstring(L, name); + lua_pushstring(L, port); + if (family == PF_INET) { + lua_pushliteral(L, "inet"); + } else if (family == PF_INET6) { + lua_pushliteral(L, "inet6"); + } else { + lua_pushliteral(L, "uknown family"); + } + return 3; } /*=========================================================================*\ @@ -403,7 +369,6 @@ const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm) struct in6_addr addrany = IN6ADDR_ANY_INIT; memset((char *) &sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_UNSPEC; -fprintf(stderr, "disconnecting\n"); sin6.sin6_addr = addrany; return socket_strerror(socket_connect(ps, (SA *) &sin6, sizeof(sin6), tm)); @@ -415,7 +380,7 @@ fprintf(stderr, "disconnecting\n"); /*-------------------------------------------------------------------------*\ * Tries to connect to remote address (address, port) \*-------------------------------------------------------------------------*/ -const char *inet_tryconnect(p_socket ps, const char *address, +const char *inet_tryconnect(p_socket ps, int *family, const char *address, const char *serv, p_timeout tm, struct addrinfo *connecthints) { struct addrinfo *iterator = NULL, *resolved = NULL; @@ -429,6 +394,23 @@ const char *inet_tryconnect(p_socket ps, const char *address, } for (iterator = resolved; iterator; iterator = iterator->ai_next) { timeout_markstart(tm); + /* create new socket if necessary. if there was no + * bind, we need to create one for every new family + * that shows up while iterating. if there was a + * bind, all families will be the same and we will + * not enter this branch. */ + if (*family != iterator->ai_family) { + socket_destroy(ps); + err = socket_strerror(socket_create(ps, iterator->ai_family, + iterator->ai_socktype, iterator->ai_protocol)); + if (err != NULL) { + freeaddrinfo(resolved); + return err; + } + *family = iterator->ai_family; + /* all sockets initially non-blocking */ + socket_setnonblocking(ps); + } /* try connecting to remote address */ err = socket_strerror(socket_connect(ps, (SA *) iterator->ai_addr, (socklen_t) iterator->ai_addrlen, tm)); @@ -443,7 +425,8 @@ const char *inet_tryconnect(p_socket ps, const char *address, /*-------------------------------------------------------------------------*\ * Tries to accept a socket \*-------------------------------------------------------------------------*/ -const char *inet_tryaccept(p_socket server, int family, p_socket client, p_timeout tm) +const char *inet_tryaccept(p_socket server, int family, p_socket client, + p_timeout tm) { socklen_t len; t_sockaddr_storage addr; @@ -452,7 +435,8 @@ const char *inet_tryaccept(p_socket server, int family, p_socket client, p_timeo } else { len = sizeof(struct sockaddr_in); } - return socket_strerror(socket_accept(server, client, (SA *) &addr, &len, tm)); + return socket_strerror(socket_accept(server, client, (SA *) &addr, + &len, tm)); } /*-------------------------------------------------------------------------*\ @@ -464,6 +448,9 @@ const char *inet_trybind(p_socket ps, const char *address, const char *serv, struct addrinfo *iterator = NULL, *resolved = NULL; const char *err = NULL; t_socket sock = *ps; + /* translate luasocket special values to C */ + if (strcmp(address, "*") == 0) address = NULL; + if (!serv) serv = "0"; /* try resolving */ err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved)); if (err) { @@ -500,10 +487,9 @@ const char *inet_trybind(p_socket ps, const char *address, const char *serv, } /*-------------------------------------------------------------------------*\ -* Some systems do not provide this so that we provide our own. It's not -* marvelously fast, but it works just fine. +* Some systems do not provide these so that we provide our own. \*-------------------------------------------------------------------------*/ -#ifdef INET_ATON +#ifdef LUASOCKET_INET_ATON int inet_aton(const char *cp, struct in_addr *inp) { unsigned int a = 0, b = 0, c = 0, d = 0; @@ -525,4 +511,26 @@ int inet_aton(const char *cp, struct in_addr *inp) } #endif +#ifdef LUASOCKET_INET_PTON +int inet_pton(int af, const char *src, void *dst) +{ + struct addrinfo hints, *res; + int ret = 1; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(src, NULL, &hints, &res) != 0) return -1; + if (af == AF_INET) { + struct sockaddr_in *in = (struct sockaddr_in *) res->ai_addr; + memcpy(dst, &in->sin_addr, sizeof(in->sin_addr)); + } else if (af == AF_INET6) { + struct sockaddr_in6 *in = (struct sockaddr_in6 *) res->ai_addr; + memcpy(dst, &in->sin6_addr, sizeof(in->sin6_addr)); + } else { + ret = -1; + } + freeaddrinfo(res); + return ret; +} +#endif diff --git a/external/lua/luasocket/inet.h b/external/lua/luasocket/inet.h index 9971002103..1f1a96a338 100644 --- a/external/lua/luasocket/inet.h +++ b/external/lua/luasocket/inet.h @@ -19,13 +19,13 @@ #include "timeout.h" #ifdef _WIN32 -#define INET_ATON +#define LUASOCKET_INET_ATON #endif int inet_open(lua_State *L); const char *inet_trycreate(p_socket ps, int family, int type); -const char *inet_tryconnect(p_socket ps, const char *address, +const char *inet_tryconnect(p_socket ps, int *family, const char *address, const char *serv, p_timeout tm, struct addrinfo *connecthints); const char *inet_trybind(p_socket ps, const char *address, const char *serv, struct addrinfo *bindhints); @@ -38,19 +38,13 @@ int inet_meth_getsockname(lua_State *L, p_socket ps, int family); int inet_optfamily(lua_State* L, int narg, const char* def); int inet_optsocktype(lua_State* L, int narg, const char* def); -#ifdef INET_ATON +#ifdef LUASOCKET_INET_ATON int inet_aton(const char *cp, struct in_addr *inp); #endif -#ifndef _WINDOWS_ -#define my_inet_ntop(a,b,c,d) inet_ntop(a,b,c,d) -#define my_inet_pton(a,b,c) inet_pton(a,b,c) -#else -int win32xp_inet_pton(int family, const char* string, PVOID dest); -char* win32xp_inet_ntop(int family, PVOID src, char* dest, size_t length); -#define my_inet_ntop(a,b,c,d) win32xp_inet_ntop(a,b,c,d) -#define my_inet_pton(a,b,c) win32xp_inet_pton(a,b,c) +#ifdef LUASOCKET_INET_PTON +const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); +int inet_pton(int af, const char *src, void *dst); #endif - #endif /* INET_H */ diff --git a/external/lua/luasocket/luasocket_io.c b/external/lua/luasocket/io.c similarity index 97% rename from external/lua/luasocket/luasocket_io.c rename to external/lua/luasocket/io.c index 74722a5abf..35f46f785a 100644 --- a/external/lua/luasocket/luasocket_io.c +++ b/external/lua/luasocket/io.c @@ -2,7 +2,7 @@ * Input/Output abstraction * LuaSocket toolkit \*=========================================================================*/ -#include "luasocket_io.h" +#include "io.h" /*=========================================================================*\ * Exported functions diff --git a/external/lua/luasocket/luasocket_io.h b/external/lua/luasocket/io.h similarity index 98% rename from external/lua/luasocket/luasocket_io.h rename to external/lua/luasocket/io.h index 8cca08a860..76a3e585c2 100644 --- a/external/lua/luasocket/luasocket_io.h +++ b/external/lua/luasocket/io.h @@ -22,7 +22,7 @@ enum { IO_DONE = 0, /* operation completed successfully */ IO_TIMEOUT = -1, /* operation timed out */ IO_CLOSED = -2, /* the connection has been closed */ - IO_UNKNOWN = -3 + IO_UNKNOWN = -3 }; /* interface to error message function */ diff --git a/external/lua/luasocket/ltn12.lua b/external/lua/luasocket/ltn12.lua new file mode 100644 index 0000000000..5b10f56d50 --- /dev/null +++ b/external/lua/luasocket/ltn12.lua @@ -0,0 +1,298 @@ +----------------------------------------------------------------------------- +-- LTN12 - Filters, sources, sinks and pumps. +-- LuaSocket toolkit. +-- Author: Diego Nehab +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module +----------------------------------------------------------------------------- +local string = require("string") +local table = require("table") +local base = _G +local _M = {} +if module then -- heuristic for exporting a global package table + ltn12 = _M +end +local filter,source,sink,pump = {},{},{},{} + +_M.filter = filter +_M.source = source +_M.sink = sink +_M.pump = pump + +-- 2048 seems to be better in windows... +_M.BLOCKSIZE = 2048 +_M._VERSION = "LTN12 1.0.3" + +----------------------------------------------------------------------------- +-- Filter stuff +----------------------------------------------------------------------------- +-- returns a high level filter that cycles a low-level filter +function filter.cycle(low, ctx, extra) + base.assert(low) + return function(chunk) + local ret + ret, ctx = low(ctx, chunk, extra) + return ret + end +end + +-- chains a bunch of filters together +-- (thanks to Wim Couwenberg) +function filter.chain(...) + local arg = {...} + local n = select('#',...) + local top, index = 1, 1 + local retry = "" + return function(chunk) + retry = chunk and retry + while true do + if index == top then + chunk = arg[index](chunk) + if chunk == "" or top == n then return chunk + elseif chunk then index = index + 1 + else + top = top+1 + index = top + end + else + chunk = arg[index](chunk or "") + if chunk == "" then + index = index - 1 + chunk = retry + elseif chunk then + if index == n then return chunk + else index = index + 1 end + else base.error("filter returned inappropriate nil") end + end + end + end +end + +----------------------------------------------------------------------------- +-- Source stuff +----------------------------------------------------------------------------- +-- create an empty source +local function empty() + return nil +end + +function source.empty() + return empty +end + +-- returns a source that just outputs an error +function source.error(err) + return function() + return nil, err + end +end + +-- creates a file source +function source.file(handle, io_err) + if handle then + return function() + local chunk = handle:read(_M.BLOCKSIZE) + if not chunk then handle:close() end + return chunk + end + else return source.error(io_err or "unable to open file") end +end + +-- turns a fancy source into a simple source +function source.simplify(src) + base.assert(src) + return function() + local chunk, err_or_new = src() + src = err_or_new or src + if not chunk then return nil, err_or_new + else return chunk end + end +end + +-- creates string source +function source.string(s) + if s then + local i = 1 + return function() + local chunk = string.sub(s, i, i+_M.BLOCKSIZE-1) + i = i + _M.BLOCKSIZE + if chunk ~= "" then return chunk + else return nil end + end + else return source.empty() end +end + +-- creates rewindable source +function source.rewind(src) + base.assert(src) + local t = {} + return function(chunk) + if not chunk then + chunk = table.remove(t) + if not chunk then return src() + else return chunk end + else + table.insert(t, chunk) + end + end +end + +function source.chain(src, f) + base.assert(src and f) + local last_in, last_out = "", "" + local state = "feeding" + local err + return function() + if not last_out then + base.error('source is empty!', 2) + end + while true do + if state == "feeding" then + last_in, err = src() + if err then return nil, err end + last_out = f(last_in) + if not last_out then + if last_in then + base.error('filter returned inappropriate nil') + else + return nil + end + elseif last_out ~= "" then + state = "eating" + if last_in then last_in = "" end + return last_out + end + else + last_out = f(last_in) + if last_out == "" then + if last_in == "" then + state = "feeding" + else + base.error('filter returned ""') + end + elseif not last_out then + if last_in then + base.error('filter returned inappropriate nil') + else + return nil + end + else + return last_out + end + end + end + end +end + +-- creates a source that produces contents of several sources, one after the +-- other, as if they were concatenated +-- (thanks to Wim Couwenberg) +function source.cat(...) + local arg = {...} + local src = table.remove(arg, 1) + return function() + while src do + local chunk, err = src() + if chunk then return chunk end + if err then return nil, err end + src = table.remove(arg, 1) + end + end +end + +----------------------------------------------------------------------------- +-- Sink stuff +----------------------------------------------------------------------------- +-- creates a sink that stores into a table +function sink.table(t) + t = t or {} + local f = function(chunk, err) + if chunk then table.insert(t, chunk) end + return 1 + end + return f, t +end + +-- turns a fancy sink into a simple sink +function sink.simplify(snk) + base.assert(snk) + return function(chunk, err) + local ret, err_or_new = snk(chunk, err) + if not ret then return nil, err_or_new end + snk = err_or_new or snk + return 1 + end +end + +-- creates a file sink +function sink.file(handle, io_err) + if handle then + return function(chunk, err) + if not chunk then + handle:close() + return 1 + else return handle:write(chunk) end + end + else return sink.error(io_err or "unable to open file") end +end + +-- creates a sink that discards data +local function null() + return 1 +end + +function sink.null() + return null +end + +-- creates a sink that just returns an error +function sink.error(err) + return function() + return nil, err + end +end + +-- chains a sink with a filter +function sink.chain(f, snk) + base.assert(f and snk) + return function(chunk, err) + if chunk ~= "" then + local filtered = f(chunk) + local done = chunk and "" + while true do + local ret, snkerr = snk(filtered, err) + if not ret then return nil, snkerr end + if filtered == done then return 1 end + filtered = f(done) + end + else return 1 end + end +end + +----------------------------------------------------------------------------- +-- Pump stuff +----------------------------------------------------------------------------- +-- pumps one chunk from the source to the sink +function pump.step(src, snk) + local chunk, src_err = src() + local ret, snk_err = snk(chunk, src_err) + if chunk and ret then return 1 + else return nil, src_err or snk_err end +end + +-- pumps all data from a source to a sink, using a step function +function pump.all(src, snk, step) + base.assert(src and snk) + step = step or pump.step + while true do + local ret, err = step(src, snk) + if not ret then + if err then return nil, err + else return 1 end + end + end +end + +return _M diff --git a/external/lua/luasocket/luasocket.c b/external/lua/luasocket/luasocket.c index c86a3e86b0..e6ee74764d 100644 --- a/external/lua/luasocket/luasocket.c +++ b/external/lua/luasocket/luasocket.c @@ -18,9 +18,6 @@ #include "lua.h" #include "lauxlib.h" -#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) -#include "compat-5.1.h" -#endif /*=========================================================================*\ * LuaSocket includes @@ -29,7 +26,7 @@ #include "auxiliar.h" #include "except.h" #include "timeout.h" -#include "luasocket_buffer.h" +#include "buffer.h" #include "inet.h" #include "tcp.h" #include "udp.h" @@ -81,13 +78,26 @@ static int global_unload(lua_State *L) { return 0; } +#if LUA_VERSION_NUM > 501 +int luaL_typerror (lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} +#endif + /*-------------------------------------------------------------------------*\ * Setup basic stuff. \*-------------------------------------------------------------------------*/ static int base_open(lua_State *L) { if (socket_open()) { /* export functions (and leave namespace table on top of stack) */ +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + lua_newtable(L); + luaL_setfuncs(L, func, 0); +#else luaL_openlib(L, "socket", func, 0); +#endif #ifdef LUASOCKET_DEBUG lua_pushstring(L, "_DEBUG"); lua_pushboolean(L, 1); diff --git a/external/lua/luasocket/luasocket.h b/external/lua/luasocket/luasocket.h index f2ca3c159e..f75d21f226 100644 --- a/external/lua/luasocket/luasocket.h +++ b/external/lua/luasocket/luasocket.h @@ -11,9 +11,8 @@ /*-------------------------------------------------------------------------*\ * Current socket library version \*-------------------------------------------------------------------------*/ -#define LUASOCKET_VERSION "LuaSocket 2.1-rc1" -#define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2012 Diego Nehab" -#define LUASOCKET_AUTHORS "Diego Nehab" +#define LUASOCKET_VERSION "LuaSocket 3.0-rc1" +#define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2013 Diego Nehab" /*-------------------------------------------------------------------------*\ * This macro prefixes all exported API functions @@ -22,10 +21,6 @@ #define LUASOCKET_API extern #endif -#if LUA_VERSION_NUM > 501 & !( defined LUA_COMPAT_MODULE) -# error Lua 5.2 requires LUA_COMPAT_MODULE defined for luaL_openlib -#endif - /*-------------------------------------------------------------------------*\ * Initializes the library. \*-------------------------------------------------------------------------*/ diff --git a/external/lua/luasocket/mbox.lua b/external/lua/luasocket/mbox.lua new file mode 100644 index 0000000000..7724ae2859 --- /dev/null +++ b/external/lua/luasocket/mbox.lua @@ -0,0 +1,92 @@ +local _M = {} + +if module then + mbox = _M +end + +function _M.split_message(message_s) + local message = {} + message_s = string.gsub(message_s, "\r\n", "\n") + string.gsub(message_s, "^(.-\n)\n", function (h) message.headers = h end) + string.gsub(message_s, "^.-\n\n(.*)", function (b) message.body = b end) + if not message.body then + string.gsub(message_s, "^\n(.*)", function (b) message.body = b end) + end + if not message.headers and not message.body then + message.headers = message_s + end + return message.headers or "", message.body or "" +end + +function _M.split_headers(headers_s) + local headers = {} + headers_s = string.gsub(headers_s, "\r\n", "\n") + headers_s = string.gsub(headers_s, "\n[ ]+", " ") + string.gsub("\n" .. headers_s, "\n([^\n]+)", function (h) table.insert(headers, h) end) + return headers +end + +function _M.parse_header(header_s) + header_s = string.gsub(header_s, "\n[ ]+", " ") + header_s = string.gsub(header_s, "\n+", "") + local _, __, name, value = string.find(header_s, "([^%s:]-):%s*(.*)") + return name, value +end + +function _M.parse_headers(headers_s) + local headers_t = _M.split_headers(headers_s) + local headers = {} + for i = 1, #headers_t do + local name, value = _M.parse_header(headers_t[i]) + if name then + name = string.lower(name) + if headers[name] then + headers[name] = headers[name] .. ", " .. value + else headers[name] = value end + end + end + return headers +end + +function _M.parse_from(from) + local _, __, name, address = string.find(from, "^%s*(.-)%s*%<(.-)%>") + if not address then + _, __, address = string.find(from, "%s*(.+)%s*") + end + name = name or "" + address = address or "" + if name == "" then name = address end + name = string.gsub(name, '"', "") + return name, address +end + +function _M.split_mbox(mbox_s) + mbox = {} + mbox_s = string.gsub(mbox_s, "\r\n", "\n") .."\n\nFrom \n" + local nj, i, j = 1, 1, 1 + while 1 do + i, nj = string.find(mbox_s, "\n\nFrom .-\n", j) + if not i then break end + local message = string.sub(mbox_s, j, i-1) + table.insert(mbox, message) + j = nj+1 + end + return mbox +end + +function _M.parse(mbox_s) + local mbox = _M.split_mbox(mbox_s) + for i = 1, #mbox do + mbox[i] = _M.parse_message(mbox[i]) + end + return mbox +end + +function _M.parse_message(message_s) + local message = {} + message.headers, message.body = _M.split_message(message_s) + message.headers = _M.parse_headers(message.headers) + return message +end + +return _M diff --git a/external/lua/luasocket/mime.c b/external/lua/luasocket/mime.c index dddd3d66ea..dd37dcf06f 100644 --- a/external/lua/luasocket/mime.c +++ b/external/lua/luasocket/mime.c @@ -81,7 +81,12 @@ static UC b64unbase[256]; \*-------------------------------------------------------------------------*/ MIME_API int luaopen_mime_core(lua_State *L) { +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + lua_newtable(L); + luaL_setfuncs(L, func, 0); +#else luaL_openlib(L, "mime", func, 0); +#endif /* make version string available to scripts */ lua_pushstring(L, "_VERSION"); lua_pushstring(L, MIME_VERSION); diff --git a/external/lua/luasocket/mime.h b/external/lua/luasocket/mime.h index 150e7adf91..99968a55d1 100644 --- a/external/lua/luasocket/mime.h +++ b/external/lua/luasocket/mime.h @@ -13,8 +13,8 @@ /*-------------------------------------------------------------------------*\ * Current MIME library version \*-------------------------------------------------------------------------*/ -#define MIME_VERSION "MIME 1.0.3-rc1" -#define MIME_COPYRIGHT "Copyright (C) 2004-2012 Diego Nehab" +#define MIME_VERSION "MIME 1.0.3" +#define MIME_COPYRIGHT "Copyright (C) 2004-2013 Diego Nehab" #define MIME_AUTHORS "Diego Nehab" /*-------------------------------------------------------------------------*\ diff --git a/external/lua/luasocket/mime.lua b/external/lua/luasocket/mime.lua new file mode 100644 index 0000000000..642cd9ca6e --- /dev/null +++ b/external/lua/luasocket/mime.lua @@ -0,0 +1,90 @@ +----------------------------------------------------------------------------- +-- MIME support for the Lua language. +-- Author: Diego Nehab +-- Conforming to RFCs 2045-2049 +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local ltn12 = require("ltn12") +local mime = require("mime.core") +local io = require("io") +local string = require("string") +local _M = mime + +-- encode, decode and wrap algorithm tables +local encodet, decodet, wrapt = {},{},{} + +_M.encodet = encodet +_M.decodet = decodet +_M.wrapt = wrapt + +-- creates a function that chooses a filter by name from a given table +local function choose(table) + return function(name, opt1, opt2) + if base.type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local f = table[name or "nil"] + if not f then + base.error("unknown key (" .. base.tostring(name) .. ")", 3) + else return f(opt1, opt2) end + end +end + +-- define the encoding filters +encodet['base64'] = function() + return ltn12.filter.cycle(_M.b64, "") +end + +encodet['quoted-printable'] = function(mode) + return ltn12.filter.cycle(_M.qp, "", + (mode == "binary") and "=0D=0A" or "\r\n") +end + +-- define the decoding filters +decodet['base64'] = function() + return ltn12.filter.cycle(_M.unb64, "") +end + +decodet['quoted-printable'] = function() + return ltn12.filter.cycle(_M.unqp, "") +end + +local function format(chunk) + if chunk then + if chunk == "" then return "''" + else return string.len(chunk) end + else return "nil" end +end + +-- define the line-wrap filters +wrapt['text'] = function(length) + length = length or 76 + return ltn12.filter.cycle(_M.wrp, length, length) +end +wrapt['base64'] = wrapt['text'] +wrapt['default'] = wrapt['text'] + +wrapt['quoted-printable'] = function() + return ltn12.filter.cycle(_M.qpwrp, 76, 76) +end + +-- function that choose the encoding, decoding or wrap algorithm +_M.encode = choose(encodet) +_M.decode = choose(decodet) +_M.wrap = choose(wrapt) + +-- define the end-of-line normalization filter +function _M.normalize(marker) + return ltn12.filter.cycle(_M.eol, 0, marker) +end + +-- high level stuffing filter +function _M.stuff() + return ltn12.filter.cycle(_M.dot, 2) +end + +return _M \ No newline at end of file diff --git a/external/lua/luasocket/options.c b/external/lua/luasocket/options.c index 6cae7eeb92..8ac2a14415 100644 --- a/external/lua/luasocket/options.c +++ b/external/lua/luasocket/options.c @@ -10,12 +10,16 @@ #include "options.h" #include "inet.h" + /*=========================================================================*\ * Internal functions prototypes \*=========================================================================*/ static int opt_setmembership(lua_State *L, p_socket ps, int level, int name); +static int opt_ip6_setmembership(lua_State *L, p_socket ps, int level, int name); static int opt_setboolean(lua_State *L, p_socket ps, int level, int name); static int opt_getboolean(lua_State *L, p_socket ps, int level, int name); +static int opt_setint(lua_State *L, p_socket ps, int level, int name); +static int opt_getint(lua_State *L, p_socket ps, int level, int name); static int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len); static int opt_get(lua_State *L, p_socket ps, int level, int name, @@ -106,6 +110,26 @@ int opt_set_broadcast(lua_State *L, p_socket ps) return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); } +int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS); +} + +int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps) +{ + return opt_getint(L, ps, IPPROTO_IPV6, IPV6_UNICAST_HOPS); +} + +int opt_set_ip6_multicast_hops(lua_State *L, p_socket ps) +{ + return opt_setint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS); +} + +int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps) +{ + return opt_getint(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_HOPS); +} + int opt_set_ip_multicast_loop(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); @@ -116,6 +140,16 @@ int opt_get_ip_multicast_loop(lua_State *L, p_socket ps) return opt_getboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); } +int opt_set_ip6_multicast_loop(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP); +} + +int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_MULTICAST_LOOP); +} + int opt_set_linger(lua_State *L, p_socket ps) { struct linger li; /* obj, name, table */ @@ -150,9 +184,7 @@ int opt_get_linger(lua_State *L, p_socket ps) int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps) { - int val = (int) luaL_checknumber(L, 3); /* obj, name, int */ - return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_TTL, - (char *) &val, sizeof(val)); + return opt_setint(L, ps, IPPROTO_IP, IP_MULTICAST_TTL); } int opt_set_ip_multicast_if(lua_State *L, p_socket ps) @@ -189,6 +221,21 @@ int opt_set_ip_drop_membersip(lua_State *L, p_socket ps) return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); } +int opt_set_ip6_add_membership(lua_State *L, p_socket ps) +{ + return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP); +} + +int opt_set_ip6_drop_membersip(lua_State *L, p_socket ps) +{ + return opt_ip6_setmembership(L, ps, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP); +} + +int opt_get_ip6_v6only(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); +} + int opt_set_ip6_v6only(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, IPPROTO_IPV6, IPV6_V6ONLY); @@ -218,6 +265,32 @@ static int opt_setmembership(lua_State *L, p_socket ps, int level, int name) return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); } +static int opt_ip6_setmembership(lua_State *L, p_socket ps, int level, int name) +{ + struct ipv6_mreq val; /* obj, opt-name, table */ + memset(&val, 0, sizeof(val)); + if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE)); + lua_pushstring(L, "multiaddr"); + lua_gettable(L, 3); + if (!lua_isstring(L, -1)) + luaL_argerror(L, 3, "string 'multiaddr' field expected"); + if (!inet_pton(AF_INET6, lua_tostring(L, -1), &val.ipv6mr_multiaddr)) + luaL_argerror(L, 3, "invalid 'multiaddr' ip address"); + lua_pushstring(L, "interface"); + lua_gettable(L, 3); + /* By default we listen to interface on default route + * (sigh). However, interface= can override it. We should + * support either number, or name for it. Waiting for + * windows port of if_nametoindex */ + if (!lua_isnil(L, -1)) { + if (lua_isnumber(L, -1)) { + val.ipv6mr_interface = (unsigned int) lua_tonumber(L, -1); + } else + luaL_argerror(L, -1, "number 'interface' field expected"); + } + return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); +} + static int opt_get(lua_State *L, p_socket ps, int level, int name, void *val, int* len) { @@ -254,9 +327,38 @@ static int opt_getboolean(lua_State *L, p_socket ps, int level, int name) return 1; } +int opt_get_error(lua_State *L, p_socket ps) +{ + int val = 0; + socklen_t len = sizeof(val); + if (getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *) &val, &len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getsockopt failed"); + return 2; + } + lua_pushstring(L, socket_strerror(val)); + return 1; +} + static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) { int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); } +static int opt_getint(lua_State *L, p_socket ps, int level, int name) +{ + int val = 0; + int len = sizeof(val); + int err = opt_get(L, ps, level, name, (char *) &val, &len); + if (err) + return err; + lua_pushnumber(L, val); + return 1; +} + +static int opt_setint(lua_State *L, p_socket ps, int level, int name) +{ + int val = (int) lua_tonumber(L, 3); /* obj, name, int */ + return opt_set(L, ps, level, name, (char *) &val, sizeof(val)); +} diff --git a/external/lua/luasocket/options.h b/external/lua/luasocket/options.h index 55447f78f4..5657a066ac 100644 --- a/external/lua/luasocket/options.h +++ b/external/lua/luasocket/options.h @@ -32,6 +32,11 @@ int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps); int opt_set_ip_multicast_loop(lua_State *L, p_socket ps); int opt_set_ip_add_membership(lua_State *L, p_socket ps); int opt_set_ip_drop_membersip(lua_State *L, p_socket ps); +int opt_set_ip6_unicast_hops(lua_State *L, p_socket ps); +int opt_set_ip6_multicast_hops(lua_State *L, p_socket ps); +int opt_set_ip6_multicast_loop(lua_State *L, p_socket ps); +int opt_set_ip6_add_membership(lua_State *L, p_socket ps); +int opt_set_ip6_drop_membersip(lua_State *L, p_socket ps); int opt_set_ip6_v6only(lua_State *L, p_socket ps); /* supported options for getoption */ @@ -42,6 +47,11 @@ int opt_get_linger(lua_State *L, p_socket ps); int opt_get_reuseaddr(lua_State *L, p_socket ps); int opt_get_ip_multicast_loop(lua_State *L, p_socket ps); int opt_get_ip_multicast_if(lua_State *L, p_socket ps); +int opt_get_error(lua_State *L, p_socket ps); +int opt_get_ip6_multicast_loop(lua_State *L, p_socket ps); +int opt_get_ip6_multicast_hops(lua_State *L, p_socket ps); +int opt_get_ip6_unicast_hops(lua_State *L, p_socket ps); +int opt_get_ip6_v6only(lua_State *L, p_socket ps); /* invokes the appropriate option handler */ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); diff --git a/external/lua/luasocket/select.c b/external/lua/luasocket/select.c index 51fb198611..fafaa6270b 100644 --- a/external/lua/luasocket/select.c +++ b/external/lua/luasocket/select.c @@ -40,7 +40,11 @@ int select_open(lua_State *L) { lua_pushstring(L, "_SETSIZE"); lua_pushnumber(L, FD_SETSIZE); lua_rawset(L, -3); +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + luaL_setfuncs(L, func, 0); +#else luaL_openlib(L, NULL, func, 0); +#endif return 0; } diff --git a/external/lua/luasocket/serial.c b/external/lua/luasocket/serial.c index 5b09e76830..02ee05b53a 100644 --- a/external/lua/luasocket/serial.c +++ b/external/lua/luasocket/serial.c @@ -11,6 +11,7 @@ #include "socket.h" #include "options.h" #include "unix.h" +#include "luasocket.h" #include /* @@ -55,6 +56,8 @@ static luaL_Reg serial_methods[] = { }; /* our socket creation function */ +/* this is an ad-hoc module that returns a single function + * as such, do not include other functions in this array. */ static luaL_Reg func[] = { {"serial", global_create}, {NULL, NULL} @@ -69,11 +72,14 @@ LUASOCKET_API int luaopen_socket_serial(lua_State *L) { auxiliar_newclass(L, "serial{client}", serial_methods); /* create class groups */ auxiliar_add2group(L, "serial{client}", "serial{any}"); - /* make sure the function ends up in the package table */ +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + lua_pushcfunction(L, global_create); + (void) func; +#else + /* set function into socket namespace */ luaL_openlib(L, "socket", func, 0); - /* return the function instead of the 'socket' table */ - lua_pushstring(L, "serial"); - lua_gettable(L, -2); + lua_pushcfunction(L, global_create); +#endif return 1; } diff --git a/external/lua/luasocket/smtp.lua b/external/lua/luasocket/smtp.lua new file mode 100644 index 0000000000..b113d00677 --- /dev/null +++ b/external/lua/luasocket/smtp.lua @@ -0,0 +1,256 @@ +----------------------------------------------------------------------------- +-- SMTP client support for the Lua language. +-- LuaSocket toolkit. +-- Author: Diego Nehab +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local coroutine = require("coroutine") +local string = require("string") +local math = require("math") +local os = require("os") +local socket = require("socket") +local tp = require("socket.tp") +local ltn12 = require("ltn12") +local headers = require("socket.headers") +local mime = require("mime") + +socket.smtp = {} +local _M = socket.smtp + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +-- timeout for connection +_M.TIMEOUT = 60 +-- default server used to send e-mails +_M.SERVER = "localhost" +-- default port +_M.PORT = 25 +-- domain used in HELO command and default sendmail +-- If we are under a CGI, try to get from environment +_M.DOMAIN = os.getenv("SERVER_NAME") or "localhost" +-- default time zone (means we don't know) +_M.ZONE = "-0000" + +--------------------------------------------------------------------------- +-- Low level SMTP API +----------------------------------------------------------------------------- +local metat = { __index = {} } + +function metat.__index:greet(domain) + self.try(self.tp:check("2..")) + self.try(self.tp:command("EHLO", domain or _M.DOMAIN)) + return socket.skip(1, self.try(self.tp:check("2.."))) +end + +function metat.__index:mail(from) + self.try(self.tp:command("MAIL", "FROM:" .. from)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:rcpt(to) + self.try(self.tp:command("RCPT", "TO:" .. to)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:data(src, step) + self.try(self.tp:command("DATA")) + self.try(self.tp:check("3..")) + self.try(self.tp:source(src, step)) + self.try(self.tp:send("\r\n.\r\n")) + return self.try(self.tp:check("2..")) +end + +function metat.__index:quit() + self.try(self.tp:command("QUIT")) + return self.try(self.tp:check("2..")) +end + +function metat.__index:close() + return self.tp:close() +end + +function metat.__index:login(user, password) + self.try(self.tp:command("AUTH", "LOGIN")) + self.try(self.tp:check("3..")) + self.try(self.tp:send(mime.b64(user) .. "\r\n")) + self.try(self.tp:check("3..")) + self.try(self.tp:send(mime.b64(password) .. "\r\n")) + return self.try(self.tp:check("2..")) +end + +function metat.__index:plain(user, password) + local auth = "PLAIN " .. mime.b64("\0" .. user .. "\0" .. password) + self.try(self.tp:command("AUTH", auth)) + return self.try(self.tp:check("2..")) +end + +function metat.__index:auth(user, password, ext) + if not user or not password then return 1 end + if string.find(ext, "AUTH[^\n]+LOGIN") then + return self:login(user, password) + elseif string.find(ext, "AUTH[^\n]+PLAIN") then + return self:plain(user, password) + else + self.try(nil, "authentication not supported") + end +end + +-- send message or throw an exception +function metat.__index:send(mailt) + self:mail(mailt.from) + if base.type(mailt.rcpt) == "table" then + for i,v in base.ipairs(mailt.rcpt) do + self:rcpt(v) + end + else + self:rcpt(mailt.rcpt) + end + self:data(ltn12.source.chain(mailt.source, mime.stuff()), mailt.step) +end + +function _M.open(server, port, create) + local tp = socket.try(tp.connect(server or _M.SERVER, port or _M.PORT, + _M.TIMEOUT, create)) + local s = base.setmetatable({tp = tp}, metat) + -- make sure tp is closed if we get an exception + s.try = socket.newtry(function() + s:close() + end) + return s +end + +-- convert headers to lowercase +local function lower_headers(headers) + local lower = {} + for i,v in base.pairs(headers or lower) do + lower[string.lower(i)] = v + end + return lower +end + +--------------------------------------------------------------------------- +-- Multipart message source +----------------------------------------------------------------------------- +-- returns a hopefully unique mime boundary +local seqno = 0 +local function newboundary() + seqno = seqno + 1 + return string.format('%s%05d==%05u', os.date('%d%m%Y%H%M%S'), + math.random(0, 99999), seqno) +end + +-- send_message forward declaration +local send_message + +-- yield the headers all at once, it's faster +local function send_headers(tosend) + local canonic = headers.canonic + local h = "\r\n" + for f,v in base.pairs(tosend) do + h = (canonic[f] or f) .. ': ' .. v .. "\r\n" .. h + end + coroutine.yield(h) +end + +-- yield multipart message body from a multipart message table +local function send_multipart(mesgt) + -- make sure we have our boundary and send headers + local bd = newboundary() + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or 'multipart/mixed' + headers['content-type'] = headers['content-type'] .. + '; boundary="' .. bd .. '"' + send_headers(headers) + -- send preamble + if mesgt.body.preamble then + coroutine.yield(mesgt.body.preamble) + coroutine.yield("\r\n") + end + -- send each part separated by a boundary + for i, m in base.ipairs(mesgt.body) do + coroutine.yield("\r\n--" .. bd .. "\r\n") + send_message(m) + end + -- send last boundary + coroutine.yield("\r\n--" .. bd .. "--\r\n\r\n") + -- send epilogue + if mesgt.body.epilogue then + coroutine.yield(mesgt.body.epilogue) + coroutine.yield("\r\n") + end +end + +-- yield message body from a source +local function send_source(mesgt) + -- make sure we have a content-type + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or + 'text/plain; charset="iso-8859-1"' + send_headers(headers) + -- send body from source + while true do + local chunk, err = mesgt.body() + if err then coroutine.yield(nil, err) + elseif chunk then coroutine.yield(chunk) + else break end + end +end + +-- yield message body from a string +local function send_string(mesgt) + -- make sure we have a content-type + local headers = lower_headers(mesgt.headers or {}) + headers['content-type'] = headers['content-type'] or + 'text/plain; charset="iso-8859-1"' + send_headers(headers) + -- send body from string + coroutine.yield(mesgt.body) +end + +-- message source +function send_message(mesgt) + if base.type(mesgt.body) == "table" then send_multipart(mesgt) + elseif base.type(mesgt.body) == "function" then send_source(mesgt) + else send_string(mesgt) end +end + +-- set defaul headers +local function adjust_headers(mesgt) + local lower = lower_headers(mesgt.headers) + lower["date"] = lower["date"] or + os.date("!%a, %d %b %Y %H:%M:%S ") .. (mesgt.zone or _M.ZONE) + lower["x-mailer"] = lower["x-mailer"] or socket._VERSION + -- this can't be overriden + lower["mime-version"] = "1.0" + return lower +end + +function _M.message(mesgt) + mesgt.headers = adjust_headers(mesgt) + -- create and return message source + local co = coroutine.create(function() send_message(mesgt) end) + return function() + local ret, a, b = coroutine.resume(co) + if ret then return a, b + else return nil, a end + end +end + +--------------------------------------------------------------------------- +-- High level SMTP API +----------------------------------------------------------------------------- +_M.send = socket.protect(function(mailt) + local s = _M.open(mailt.server, mailt.port, mailt.create) + local ext = s:greet(mailt.domain) + s:auth(mailt.user, mailt.password, ext) + s:send(mailt) + s:quit() + return s:close() +end) + +return _M \ No newline at end of file diff --git a/external/lua/luasocket/socket.h b/external/lua/luasocket/socket.h index 03fa186b8a..63573de5da 100644 --- a/external/lua/luasocket/socket.h +++ b/external/lua/luasocket/socket.h @@ -9,7 +9,7 @@ * (and the associated usocket.h and wsocket.h) factor these differences and * creates a interface compatible with the io.h module. \*=========================================================================*/ -#include "luasocket_io.h" +#include "io.h" /*=========================================================================*\ * Platform specific compatibilization diff --git a/external/lua/luasocket/socket.lua b/external/lua/luasocket/socket.lua new file mode 100644 index 0000000000..3913e6fca4 --- /dev/null +++ b/external/lua/luasocket/socket.lua @@ -0,0 +1,149 @@ +----------------------------------------------------------------------------- +-- LuaSocket helper module +-- Author: Diego Nehab +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local math = require("math") +local socket = require("socket.core") + +local _M = socket + +----------------------------------------------------------------------------- +-- Exported auxiliar functions +----------------------------------------------------------------------------- +function _M.connect4(address, port, laddress, lport) + return socket.connect(address, port, laddress, lport, "inet") +end + +function _M.connect6(address, port, laddress, lport) + return socket.connect(address, port, laddress, lport, "inet6") +end + +function _M.bind(host, port, backlog) + if host == "*" then host = "0.0.0.0" end + local addrinfo, err = socket.dns.getaddrinfo(host); + if not addrinfo then return nil, err end + local sock, res + err = "no info on address" + for i, alt in base.ipairs(addrinfo) do + if alt.family == "inet" then + sock, err = socket.tcp() + else + sock, err = socket.tcp6() + end + if not sock then return nil, err end + sock:setoption("reuseaddr", true) + res, err = sock:bind(alt.addr, port) + if not res then + sock:close() + else + res, err = sock:listen(backlog) + if not res then + sock:close() + else + return sock + end + end + end + return nil, err +end + +_M.try = _M.newtry() + +function _M.choose(table) + return function(name, opt1, opt2) + if base.type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local f = table[name or "nil"] + if not f then base.error("unknown key (".. base.tostring(name) ..")", 3) + else return f(opt1, opt2) end + end +end + +----------------------------------------------------------------------------- +-- Socket sources and sinks, conforming to LTN12 +----------------------------------------------------------------------------- +-- create namespaces inside LuaSocket namespace +local sourcet, sinkt = {}, {} +_M.sourcet = sourcet +_M.sinkt = sinkt + +_M.BLOCKSIZE = 2048 + +sinkt["close-when-done"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if not chunk then + sock:close() + return 1 + else return sock:send(chunk) end + end + }) +end + +sinkt["keep-open"] = function(sock) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function(self, chunk, err) + if chunk then return sock:send(chunk) + else return 1 end + end + }) +end + +sinkt["default"] = sinkt["keep-open"] + +_M.sink = _M.choose(sinkt) + +sourcet["by-length"] = function(sock, length) + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + if length <= 0 then return nil end + local size = math.min(socket.BLOCKSIZE, length) + local chunk, err = sock:receive(size) + if err then return nil, err end + length = length - string.len(chunk) + return chunk + end + }) +end + +sourcet["until-closed"] = function(sock) + local done + return base.setmetatable({ + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end + }, { + __call = function() + if done then return nil end + local chunk, err, partial = sock:receive(socket.BLOCKSIZE) + if not err then return chunk + elseif err == "closed" then + sock:close() + done = 1 + return partial + else return nil, err end + end + }) +end + + +sourcet["default"] = sourcet["until-closed"] + +_M.source = _M.choose(sourcet) + +return _M diff --git a/external/lua/luasocket/socket_scripts.c.REMOVED.git-id b/external/lua/luasocket/socket_scripts.c.REMOVED.git-id deleted file mode 100644 index f8ab743b49..0000000000 --- a/external/lua/luasocket/socket_scripts.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -e79358cdf4b02c66a50e684543e505002bdbcc91 \ No newline at end of file diff --git a/external/lua/luasocket/socket_scripts.h b/external/lua/luasocket/socket_scripts.h deleted file mode 100644 index 939fcb2d03..0000000000 --- a/external/lua/luasocket/socket_scripts.h +++ /dev/null @@ -1,32 +0,0 @@ - -/* socket_scripts.h */ - -#ifndef __LUA_MODULES_E58C07CB2FBAF5B178B7E1836DC22849_H_ -#define __LUA_MODULES_E58C07CB2FBAF5B178B7E1836DC22849_H_ - -#if __cplusplus -extern "C" { -#endif - -#include "lua.h" - -void luaopen_socket_scripts(lua_State* L); - -/* -int luaopen_lua_m_ltn12(lua_State* L); -int luaopen_lua_m_mime(lua_State* L); -int luaopen_lua_m_socket_ftp(lua_State* L); -int luaopen_lua_m_socket_headers(lua_State* L); -int luaopen_lua_m_socket_http(lua_State* L); -int luaopen_lua_m_socket_mbox(lua_State* L); -int luaopen_lua_m_socket_smtp(lua_State* L); -int luaopen_lua_m_socket_tp(lua_State* L); -int luaopen_lua_m_socket_url(lua_State* L); -int luaopen_lua_m_socket(lua_State* L); -*/ - -#if __cplusplus -} -#endif - -#endif /* __LUA_MODULES_E58C07CB2FBAF5B178B7E1836DC22849_H_ */ diff --git a/external/lua/luasocket/tcp.c b/external/lua/luasocket/tcp.c index 6734dc0b49..dfeb282c5b 100644 --- a/external/lua/luasocket/tcp.c +++ b/external/lua/luasocket/tcp.c @@ -12,6 +12,7 @@ #include "inet.h" #include "options.h" #include "tcp.h" +#include "buffer.h" /*=========================================================================*\ * Internal function prototypes @@ -73,6 +74,7 @@ static t_opt optget[] = { {"reuseaddr", opt_get_reuseaddr}, {"tcp-nodelay", opt_get_tcp_nodelay}, {"linger", opt_get_linger}, + {"error", opt_get_error}, {NULL, NULL} }; @@ -107,7 +109,11 @@ int tcp_open(lua_State *L) auxiliar_add2group(L, "tcp{client}", "tcp{any}"); auxiliar_add2group(L, "tcp{server}", "tcp{any}"); /* define library functions */ +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + luaL_setfuncs(L, func, 0); +#else luaL_openlib(L, NULL, func, 0); +#endif return 0; } @@ -222,7 +228,6 @@ static int meth_bind(lua_State *L) bindhints.ai_socktype = SOCK_STREAM; bindhints.ai_family = tcp->family; bindhints.ai_flags = AI_PASSIVE; - address = strcmp(address, "*")? address: NULL; err = inet_trybind(&tcp->sock, address, port, &bindhints); if (err) { lua_pushnil(L); @@ -248,7 +253,8 @@ static int meth_connect(lua_State *L) /* make sure we try to connect only to the same family */ connecthints.ai_family = tcp->family; timeout_markstart(&tcp->tm); - err = inet_tryconnect(&tcp->sock, address, port, &tcp->tm, &connecthints); + err = inet_tryconnect(&tcp->sock, &tcp->family, address, port, + &tcp->tm, &connecthints); /* have to set the class even if it failed due to non-blocking connects */ auxiliar_setclass(L, "tcp{client}", 1); if (err) { @@ -388,6 +394,7 @@ static int global_create6(lua_State *L) { return tcp_create(L, AF_INET6); } +#if 0 static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, struct addrinfo *connecthints, p_tcp tcp) { struct addrinfo *iterator = NULL, *resolved = NULL; @@ -402,8 +409,13 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, /* iterate over all returned addresses trying to connect */ for (iterator = resolved; iterator; iterator = iterator->ai_next) { p_timeout tm = timeout_markstart(&tcp->tm); - /* create new socket if one wasn't created by the bind stage */ - if (tcp->sock == SOCKET_INVALID) { + /* create new socket if necessary. if there was no + * bind, we need to create one for every new family + * that shows up while iterating. if there was a + * bind, all families will be the same and we will + * not enter this branch. */ + if (tcp->family != iterator->ai_family) { + socket_destroy(&tcp->sock); err = socket_strerror(socket_create(&tcp->sock, iterator->ai_family, iterator->ai_socktype, iterator->ai_protocol)); @@ -427,6 +439,7 @@ static const char *tryconnect6(const char *remoteaddr, const char *remoteserv, /* here, if err is set, we failed */ return err; } +#endif static int global_connect(lua_State *L) { const char *remoteaddr = luaL_checkstring(L, 1); @@ -444,6 +457,7 @@ static int global_connect(lua_State *L) { timeout_init(&tcp->tm, -1, -1); buffer_init(&tcp->buf, &tcp->io, &tcp->tm); tcp->sock = SOCKET_INVALID; + tcp->family = PF_UNSPEC; /* allow user to pick local address and port */ memset(&bindhints, 0, sizeof(bindhints)); bindhints.ai_socktype = SOCK_STREAM; @@ -463,7 +477,8 @@ static int global_connect(lua_State *L) { connecthints.ai_socktype = SOCK_STREAM; /* make sure we try to connect only to the same family */ connecthints.ai_family = bindhints.ai_family; - err = tryconnect6(remoteaddr, remoteserv, &connecthints, tcp); + err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv, + &tcp->tm, &connecthints); if (err) { socket_destroy(&tcp->sock); lua_pushnil(L); diff --git a/external/lua/luasocket/tcp.h b/external/lua/luasocket/tcp.h index a8b9b6f2cf..eded620324 100644 --- a/external/lua/luasocket/tcp.h +++ b/external/lua/luasocket/tcp.h @@ -16,7 +16,7 @@ \*=========================================================================*/ #include "lua.h" -#include "luasocket_buffer.h" +#include "buffer.h" #include "timeout.h" #include "socket.h" diff --git a/external/lua/luasocket/timeout.c b/external/lua/luasocket/timeout.c index c7354b52f3..bdd5e1c819 100644 --- a/external/lua/luasocket/timeout.c +++ b/external/lua/luasocket/timeout.c @@ -144,7 +144,11 @@ double timeout_gettime(void) { * Initializes module \*-------------------------------------------------------------------------*/ int timeout_open(lua_State *L) { +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + luaL_setfuncs(L, func, 0); +#else luaL_openlib(L, NULL, func, 0); +#endif return 0; } diff --git a/external/lua/luasocket/tp.lua b/external/lua/luasocket/tp.lua new file mode 100644 index 0000000000..cbeff566a9 --- /dev/null +++ b/external/lua/luasocket/tp.lua @@ -0,0 +1,126 @@ +----------------------------------------------------------------------------- +-- Unified SMTP/FTP subsystem +-- LuaSocket toolkit. +-- Author: Diego Nehab +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module and import dependencies +----------------------------------------------------------------------------- +local base = _G +local string = require("string") +local socket = require("socket") +local ltn12 = require("ltn12") + +socket.tp = {} +local _M = socket.tp + +----------------------------------------------------------------------------- +-- Program constants +----------------------------------------------------------------------------- +_M.TIMEOUT = 60 + +----------------------------------------------------------------------------- +-- Implementation +----------------------------------------------------------------------------- +-- gets server reply (works for SMTP and FTP) +local function get_reply(c) + local code, current, sep + local line, err = c:receive() + local reply = line + if err then return nil, err end + code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) + if not code then return nil, "invalid server reply" end + if sep == "-" then -- reply is multiline + repeat + line, err = c:receive() + if err then return nil, err end + current, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) + reply = reply .. "\n" .. line + -- reply ends with same code + until code == current and sep == " " + end + return code, reply +end + +-- metatable for sock object +local metat = { __index = {} } + +function metat.__index:check(ok) + local code, reply = get_reply(self.c) + if not code then return nil, reply end + if base.type(ok) ~= "function" then + if base.type(ok) == "table" then + for i, v in base.ipairs(ok) do + if string.find(code, v) then + return base.tonumber(code), reply + end + end + return nil, reply + else + if string.find(code, ok) then return base.tonumber(code), reply + else return nil, reply end + end + else return ok(base.tonumber(code), reply) end +end + +function metat.__index:command(cmd, arg) + cmd = string.upper(cmd) + if arg then + return self.c:send(cmd .. " " .. arg.. "\r\n") + else + return self.c:send(cmd .. "\r\n") + end +end + +function metat.__index:sink(snk, pat) + local chunk, err = c:receive(pat) + return snk(chunk, err) +end + +function metat.__index:send(data) + return self.c:send(data) +end + +function metat.__index:receive(pat) + return self.c:receive(pat) +end + +function metat.__index:getfd() + return self.c:getfd() +end + +function metat.__index:dirty() + return self.c:dirty() +end + +function metat.__index:getcontrol() + return self.c +end + +function metat.__index:source(source, step) + local sink = socket.sink("keep-open", self.c) + local ret, err = ltn12.pump.all(source, sink, step or ltn12.pump.step) + return ret, err +end + +-- closes the underlying c +function metat.__index:close() + self.c:close() + return 1 +end + +-- connect with server and return c object +function _M.connect(host, port, timeout, create) + local c, e = (create or socket.tcp)() + if not c then return nil, e end + c:settimeout(timeout or _M.TIMEOUT) + local r, e = c:connect(host, port) + if not r then + c:close() + return nil, e + end + return base.setmetatable({c = c}, metat) +end + +return _M \ No newline at end of file diff --git a/external/lua/luasocket/udp.c b/external/lua/luasocket/udp.c index c51bd9ddd2..a9f23930a4 100644 --- a/external/lua/luasocket/udp.c +++ b/external/lua/luasocket/udp.c @@ -3,6 +3,7 @@ * LuaSocket toolkit \*=========================================================================*/ #include +#include #include "lua.h" #include "lauxlib.h" @@ -68,24 +69,34 @@ static luaL_Reg udp_methods[] = { /* socket options for setoption */ static t_opt optset[] = { - {"dontroute", opt_set_dontroute}, - {"broadcast", opt_set_broadcast}, - {"reuseaddr", opt_set_reuseaddr}, - {"reuseport", opt_set_reuseport}, - {"ip-multicast-if", opt_set_ip_multicast_if}, - {"ip-multicast-ttl", opt_set_ip_multicast_ttl}, - {"ip-multicast-loop", opt_set_ip_multicast_loop}, - {"ip-add-membership", opt_set_ip_add_membership}, - {"ip-drop-membership", opt_set_ip_drop_membersip}, - {"ipv6-v6only", opt_set_ip6_v6only}, - {NULL, NULL} + {"dontroute", opt_set_dontroute}, + {"broadcast", opt_set_broadcast}, + {"reuseaddr", opt_set_reuseaddr}, + {"reuseport", opt_set_reuseport}, + {"ip-multicast-if", opt_set_ip_multicast_if}, + {"ip-multicast-ttl", opt_set_ip_multicast_ttl}, + {"ip-multicast-loop", opt_set_ip_multicast_loop}, + {"ip-add-membership", opt_set_ip_add_membership}, + {"ip-drop-membership", opt_set_ip_drop_membersip}, + {"ipv6-unicast-hops", opt_set_ip6_unicast_hops}, + {"ipv6-multicast-hops", opt_set_ip6_unicast_hops}, + {"ipv6-multicast-loop", opt_set_ip6_multicast_loop}, + {"ipv6-add-membership", opt_set_ip6_add_membership}, + {"ipv6-drop-membership", opt_set_ip6_drop_membersip}, + {"ipv6-v6only", opt_set_ip6_v6only}, + {NULL, NULL} }; /* socket options for getoption */ static t_opt optget[] = { - {"ip-multicast-if", opt_get_ip_multicast_if}, - {"ip-multicast-loop", opt_get_ip_multicast_loop}, - {NULL, NULL} + {"ip-multicast-if", opt_get_ip_multicast_if}, + {"ip-multicast-loop", opt_get_ip_multicast_loop}, + {"error", opt_get_error}, + {"ipv6-unicast-hops", opt_get_ip6_unicast_hops}, + {"ipv6-multicast-hops", opt_get_ip6_unicast_hops}, + {"ipv6-multicast-loop", opt_get_ip6_multicast_loop}, + {"ipv6-v6only", opt_get_ip6_v6only}, + {NULL, NULL} }; /* functions in library namespace */ @@ -109,7 +120,11 @@ int udp_open(lua_State *L) auxiliar_add2group(L, "udp{connected}", "select{able}"); auxiliar_add2group(L, "udp{unconnected}", "select{able}"); /* define library functions */ +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + luaL_setfuncs(L, func, 0); +#else luaL_openlib(L, NULL, func, 0); +#endif return 0; } @@ -151,39 +166,25 @@ static int meth_sendto(lua_State *L) { size_t count, sent = 0; const char *data = luaL_checklstring(L, 2, &count); const char *ip = luaL_checkstring(L, 3); - unsigned short port = (unsigned short) luaL_checknumber(L, 4); + const char *port = luaL_checkstring(L, 4); p_timeout tm = &udp->tm; int err; - switch (udp->family) { - case PF_INET: { - struct sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - if (!my_inet_pton(AF_INET, ip, &addr.sin_addr)) - luaL_argerror(L, 3, "invalid ip address"); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - timeout_markstart(tm); - err = socket_sendto(&udp->sock, data, count, &sent, - (SA *) &addr, sizeof(addr), tm); - break; - } - case PF_INET6: { - struct sockaddr_in6 addr; - memset(&addr, 0, sizeof(addr)); - if (!my_inet_pton(AF_INET6, ip, &addr.sin6_addr)) - luaL_argerror(L, 3, "invalid ip address"); - addr.sin6_family = AF_INET6; - addr.sin6_port = htons(port); - timeout_markstart(tm); - err = socket_sendto(&udp->sock, data, count, &sent, - (SA *) &addr, sizeof(addr), tm); - break; - } - default: - lua_pushnil(L); - lua_pushfstring(L, "unknown family %d", udp->family); - return 2; + struct addrinfo aihint; + struct addrinfo *ai; + memset(&aihint, 0, sizeof(aihint)); + aihint.ai_family = udp->family; + aihint.ai_socktype = SOCK_DGRAM; + aihint.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV; + err = getaddrinfo(ip, port, &aihint, &ai); + if (err) { + lua_pushnil(L); + lua_pushstring(L, gai_strerror(err)); + return 2; } + timeout_markstart(tm); + err = socket_sendto(&udp->sock, data, count, &sent, ai->ai_addr, + (socklen_t) ai->ai_addrlen, tm); + freeaddrinfo(ai); if (err != IO_DONE) { lua_pushnil(L); lua_pushstring(L, udp_strerror(err)); @@ -220,69 +221,40 @@ static int meth_receive(lua_State *L) { /*-------------------------------------------------------------------------*\ * Receives data and sender from a UDP socket \*-------------------------------------------------------------------------*/ -static int meth_receivefrom(lua_State *L) { +static int meth_receivefrom(lua_State *L) +{ p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); char buffer[UDP_DATAGRAMSIZE]; size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); int err; p_timeout tm = &udp->tm; + struct sockaddr_storage addr; + socklen_t addr_len = sizeof(addr); + char addrstr[INET6_ADDRSTRLEN]; + char portstr[6]; timeout_markstart(tm); count = MIN(count, sizeof(buffer)); - switch (udp->family) { - case PF_INET: { - struct sockaddr_in addr; - socklen_t addr_len = sizeof(addr); - err = socket_recvfrom(&udp->sock, buffer, count, &got, - (SA *) &addr, &addr_len, tm); - /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ - if (err == IO_CLOSED) - err = IO_DONE; - if (err == IO_DONE) { - char addrstr[INET_ADDRSTRLEN]; - lua_pushlstring(L, buffer, got); - if (!my_inet_ntop(AF_INET, &addr.sin_addr, - addrstr, sizeof(addrstr))) { - lua_pushnil(L); - lua_pushstring(L, "invalid source address"); - return 2; - } - lua_pushstring(L, addrstr); - lua_pushnumber(L, ntohs(addr.sin_port)); - return 3; - } - break; - } - case PF_INET6: { - struct sockaddr_in6 addr; - socklen_t addr_len = sizeof(addr); - err = socket_recvfrom(&udp->sock, buffer, count, &got, - (SA *) &addr, &addr_len, tm); - /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ - if (err == IO_CLOSED) - err = IO_DONE; - if (err == IO_DONE) { - char addrstr[INET6_ADDRSTRLEN]; - lua_pushlstring(L, buffer, got); - if (!my_inet_ntop(AF_INET6, &addr.sin6_addr, - addrstr, sizeof(addrstr))) { - lua_pushnil(L); - lua_pushstring(L, "invalid source address"); - return 2; - } - lua_pushstring(L, addrstr); - lua_pushnumber(L, ntohs(addr.sin6_port)); - return 3; - } - break; - } - default: + err = socket_recvfrom(&udp->sock, buffer, count, &got, (SA *) &addr, + &addr_len, tm); + /* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */ + if (err == IO_CLOSED) + err = IO_DONE; + if (err != IO_DONE) { lua_pushnil(L); - lua_pushfstring(L, "unknown family %d", udp->family); + lua_pushstring(L, udp_strerror(err)); return 2; } - lua_pushnil(L); - lua_pushstring(L, udp_strerror(err)); - return 2; + err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr, + INET6_ADDRSTRLEN, portstr, 6, NI_NUMERICHOST | NI_NUMERICSERV); + if (err) { + lua_pushnil(L); + lua_pushstring(L, gai_strerror(err)); + return 2; + } + lua_pushlstring(L, buffer, got); + lua_pushstring(L, addrstr); + lua_pushinteger(L, (int) strtol(portstr, (char **) NULL, 10)); + return 3; } /*-------------------------------------------------------------------------*\ @@ -376,7 +348,8 @@ static int meth_setpeername(lua_State *L) { /* make sure we try to connect only to the same family */ connecthints.ai_family = udp->family; if (connecting) { - err = inet_tryconnect(&udp->sock, address, port, tm, &connecthints); + err = inet_tryconnect(&udp->sock, &udp->family, address, + port, tm, &connecthints); if (err) { lua_pushnil(L); lua_pushstring(L, err); @@ -412,7 +385,7 @@ static int meth_setsockname(lua_State *L) { const char *address = luaL_checkstring(L, 2); const char *port = luaL_checkstring(L, 3); const char *err; - struct addrinfo bindhints; + struct addrinfo bindhints; memset(&bindhints, 0, sizeof(bindhints)); bindhints.ai_socktype = SOCK_DGRAM; bindhints.ai_family = udp->family; @@ -460,9 +433,9 @@ static int udp_create(lua_State *L, int family) { } static int global_create(lua_State *L) { - return udp_create(L, AF_INET); + return udp_create(L, AF_INET); } static int global_create6(lua_State *L) { - return udp_create(L, AF_INET6); + return udp_create(L, AF_INET6); } diff --git a/external/lua/luasocket/unix.c b/external/lua/luasocket/unix.c index 28d4cc7b84..91aaaf8c36 100644 --- a/external/lua/luasocket/unix.c +++ b/external/lua/luasocket/unix.c @@ -69,6 +69,8 @@ static t_opt optset[] = { }; /* our socket creation function */ +/* this is an ad-hoc module that returns a single function + * as such, do not include other functions in this array. */ static luaL_Reg func[] = { {"unix", global_create}, {NULL, NULL} @@ -87,11 +89,15 @@ int luaopen_socket_unix(lua_State *L) { auxiliar_add2group(L, "unix{master}", "unix{any}"); auxiliar_add2group(L, "unix{client}", "unix{any}"); auxiliar_add2group(L, "unix{server}", "unix{any}"); - /* make sure the function ends up in the package table */ +#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) + lua_pushcfunction(L, global_create); + (void) func; +#else + /* set function into socket namespace */ luaL_openlib(L, "socket", func, 0); + lua_pushcfunction(L, global_create); +#endif /* return the function instead of the 'socket' table */ - lua_pushstring(L, "unix"); - lua_gettable(L, -2); return 1; } @@ -197,7 +203,7 @@ static const char *unix_trybind(p_unix un, const char *path) { #else err = socket_bind(&un->sock, (SA *) &local, - (socklen_t)(sizeof(local.sun_family) + len)); + sizeof(local.sun_family) + len); #endif if (err != IO_DONE) socket_destroy(&un->sock); return socket_strerror(err); @@ -235,7 +241,7 @@ static const char *unix_tryconnect(p_unix un, const char *path) err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); #else err = socket_connect(&un->sock, (SA *) &remote, - (socklen_t)(sizeof(remote.sun_family) + len), &un->tm); + sizeof(remote.sun_family) + len, &un->tm); #endif if (err != IO_DONE) socket_destroy(&un->sock); return socket_strerror(err); diff --git a/external/lua/luasocket/unix.h b/external/lua/luasocket/unix.h index 86a961b747..8cc7a79324 100644 --- a/external/lua/luasocket/unix.h +++ b/external/lua/luasocket/unix.h @@ -8,11 +8,15 @@ * domain. \*=========================================================================*/ #include "lua.h" -#include "luasocket.h" -#include "luasocket_buffer.h" + +#include "buffer.h" #include "timeout.h" #include "socket.h" +#ifndef UNIX_API +#define UNIX_API extern +#endif + typedef struct t_unix_ { t_socket sock; t_io io; @@ -21,6 +25,6 @@ typedef struct t_unix_ { } t_unix; typedef t_unix *p_unix; -LUASOCKET_API int luaopen_socket_unix(lua_State *L); +UNIX_API int luaopen_socket_unix(lua_State *L); #endif /* UNIX_H */ diff --git a/external/lua/luasocket/url.lua b/external/lua/luasocket/url.lua new file mode 100644 index 0000000000..78095352ea --- /dev/null +++ b/external/lua/luasocket/url.lua @@ -0,0 +1,307 @@ +----------------------------------------------------------------------------- +-- URI parsing, composition and relative URL resolution +-- LuaSocket toolkit. +-- Author: Diego Nehab +----------------------------------------------------------------------------- + +----------------------------------------------------------------------------- +-- Declare module +----------------------------------------------------------------------------- +local string = require("string") +local base = _G +local table = require("table") +local socket = require("socket") + +socket.url = {} +local _M = socket.url + +----------------------------------------------------------------------------- +-- Module version +----------------------------------------------------------------------------- +_M._VERSION = "URL 1.0.3" + +----------------------------------------------------------------------------- +-- Encodes a string into its escaped hexadecimal representation +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +function _M.escape(s) + return (string.gsub(s, "([^A-Za-z0-9_])", function(c) + return string.format("%%%02x", string.byte(c)) + end)) +end + +----------------------------------------------------------------------------- +-- Protects a path segment, to prevent it from interfering with the +-- url parsing. +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +local function make_set(t) + local s = {} + for i,v in base.ipairs(t) do + s[t[i]] = 1 + end + return s +end + +-- these are allowed withing a path segment, along with alphanum +-- other characters must be escaped +local segment_set = make_set { + "-", "_", ".", "!", "~", "*", "'", "(", + ")", ":", "@", "&", "=", "+", "$", ",", +} + +local function protect_segment(s) + return string.gsub(s, "([^A-Za-z0-9_])", function (c) + if segment_set[c] then return c + else return string.format("%%%02x", string.byte(c)) end + end) +end + +----------------------------------------------------------------------------- +-- Encodes a string into its escaped hexadecimal representation +-- Input +-- s: binary string to be encoded +-- Returns +-- escaped representation of string binary +----------------------------------------------------------------------------- +function _M.unescape(s) + return (string.gsub(s, "%%(%x%x)", function(hex) + return string.char(base.tonumber(hex, 16)) + end)) +end + +----------------------------------------------------------------------------- +-- Builds a path from a base path and a relative path +-- Input +-- base_path +-- relative_path +-- Returns +-- corresponding absolute path +----------------------------------------------------------------------------- +local function absolute_path(base_path, relative_path) + if string.sub(relative_path, 1, 1) == "/" then return relative_path end + local path = string.gsub(base_path, "[^/]*$", "") + path = path .. relative_path + path = string.gsub(path, "([^/]*%./)", function (s) + if s ~= "./" then return s else return "" end + end) + path = string.gsub(path, "/%.$", "/") + local reduced + while reduced ~= path do + reduced = path + path = string.gsub(reduced, "([^/]*/%.%./)", function (s) + if s ~= "../../" then return "" else return s end + end) + end + path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) + if s ~= "../.." then return "" else return s end + end) + return path +end + +----------------------------------------------------------------------------- +-- Parses a url and returns a table with all its parts according to RFC 2396 +-- The following grammar describes the names given to the URL parts +-- ::= :///;?# +-- ::= @: +-- ::= [:] +-- :: = {/} +-- Input +-- url: uniform resource locator of request +-- default: table with default values for each field +-- Returns +-- table with the following fields, where RFC naming conventions have +-- been preserved: +-- scheme, authority, userinfo, user, password, host, port, +-- path, params, query, fragment +-- Obs: +-- the leading '/' in {/} is considered part of +----------------------------------------------------------------------------- +function _M.parse(url, default) + -- initialize default parameters + local parsed = {} + for i,v in base.pairs(default or parsed) do parsed[i] = v end + -- empty url is parsed to nil + if not url or url == "" then return nil, "invalid url" end + -- remove whitespace + -- url = string.gsub(url, "%s", "") + -- get fragment + url = string.gsub(url, "#(.*)$", function(f) + parsed.fragment = f + return "" + end) + -- get scheme + url = string.gsub(url, "^([%w][%w%+%-%.]*)%:", + function(s) parsed.scheme = s; return "" end) + -- get authority + url = string.gsub(url, "^//([^/]*)", function(n) + parsed.authority = n + return "" + end) + -- get query string + url = string.gsub(url, "%?(.*)", function(q) + parsed.query = q + return "" + end) + -- get params + url = string.gsub(url, "%;(.*)", function(p) + parsed.params = p + return "" + end) + -- path is whatever was left + if url ~= "" then parsed.path = url end + local authority = parsed.authority + if not authority then return parsed end + authority = string.gsub(authority,"^([^@]*)@", + function(u) parsed.userinfo = u; return "" end) + authority = string.gsub(authority, ":([^:%]]*)$", + function(p) parsed.port = p; return "" end) + if authority ~= "" then + -- IPv6? + parsed.host = string.match(authority, "^%[(.+)%]$") or authority + end + local userinfo = parsed.userinfo + if not userinfo then return parsed end + userinfo = string.gsub(userinfo, ":([^:]*)$", + function(p) parsed.password = p; return "" end) + parsed.user = userinfo + return parsed +end + +----------------------------------------------------------------------------- +-- Rebuilds a parsed URL from its components. +-- Components are protected if any reserved or unallowed characters are found +-- Input +-- parsed: parsed URL, as returned by parse +-- Returns +-- a stringing with the corresponding URL +----------------------------------------------------------------------------- +function _M.build(parsed) + local ppath = _M.parse_path(parsed.path or "") + local url = _M.build_path(ppath) + if parsed.params then url = url .. ";" .. parsed.params end + if parsed.query then url = url .. "?" .. parsed.query end + local authority = parsed.authority + if parsed.host then + authority = parsed.host + if string.find(authority, ":") then -- IPv6? + authority = "[" .. authority .. "]" + end + if parsed.port then authority = authority .. ":" .. parsed.port end + local userinfo = parsed.userinfo + if parsed.user then + userinfo = parsed.user + if parsed.password then + userinfo = userinfo .. ":" .. parsed.password + end + end + if userinfo then authority = userinfo .. "@" .. authority end + end + if authority then url = "//" .. authority .. url end + if parsed.scheme then url = parsed.scheme .. ":" .. url end + if parsed.fragment then url = url .. "#" .. parsed.fragment end + -- url = string.gsub(url, "%s", "") + return url +end + +----------------------------------------------------------------------------- +-- Builds a absolute URL from a base and a relative URL according to RFC 2396 +-- Input +-- base_url +-- relative_url +-- Returns +-- corresponding absolute url +----------------------------------------------------------------------------- +function _M.absolute(base_url, relative_url) + if base.type(base_url) == "table" then + base_parsed = base_url + base_url = _M.build(base_parsed) + else + base_parsed = _M.parse(base_url) + end + local relative_parsed = _M.parse(relative_url) + if not base_parsed then return relative_url + elseif not relative_parsed then return base_url + elseif relative_parsed.scheme then return relative_url + else + relative_parsed.scheme = base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority = base_parsed.authority + if not relative_parsed.path then + relative_parsed.path = base_parsed.path + if not relative_parsed.params then + relative_parsed.params = base_parsed.params + if not relative_parsed.query then + relative_parsed.query = base_parsed.query + end + end + else + relative_parsed.path = absolute_path(base_parsed.path or "", + relative_parsed.path) + end + end + return _M.build(relative_parsed) + end +end + +----------------------------------------------------------------------------- +-- Breaks a path into its segments, unescaping the segments +-- Input +-- path +-- Returns +-- segment: a table with one entry per segment +----------------------------------------------------------------------------- +function _M.parse_path(path) + local parsed = {} + path = path or "" + --path = string.gsub(path, "%s", "") + string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) + for i = 1, #parsed do + parsed[i] = _M.unescape(parsed[i]) + end + if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end + if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end + return parsed +end + +----------------------------------------------------------------------------- +-- Builds a path component from its segments, escaping protected characters. +-- Input +-- parsed: path segments +-- unsafe: if true, segments are not protected before path is built +-- Returns +-- path: corresponding path stringing +----------------------------------------------------------------------------- +function _M.build_path(parsed, unsafe) + local path = "" + local n = #parsed + if unsafe then + for i = 1, n-1 do + path = path .. parsed[i] + path = path .. "/" + end + if n > 0 then + path = path .. parsed[n] + if parsed.is_directory then path = path .. "/" end + end + else + for i = 1, n-1 do + path = path .. protect_segment(parsed[i]) + path = path .. "/" + end + if n > 0 then + path = path .. protect_segment(parsed[n]) + if parsed.is_directory then path = path .. "/" end + end + end + if parsed.is_absolute then path = "/" .. path end + return path +end + +return _M diff --git a/external/lua/luasocket/usocket.h b/external/lua/luasocket/usocket.h index 8b3241bf3c..45f2f99f7f 100644 --- a/external/lua/luasocket/usocket.h +++ b/external/lua/luasocket/usocket.h @@ -29,11 +29,27 @@ #include /* TCP options (nagle algorithm disable) */ #include +#include #ifndef SO_REUSEPORT #define SO_REUSEPORT SO_REUSEADDR #endif +/* Some platforms use IPV6_JOIN_GROUP instead if + * IPV6_ADD_MEMBERSHIP. The semantics are same, though. */ +#ifndef IPV6_ADD_MEMBERSHIP +#ifdef IPV6_JOIN_GROUP +#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#endif /* IPV6_JOIN_GROUP */ +#endif /* !IPV6_ADD_MEMBERSHIP */ + +/* Same with IPV6_DROP_MEMBERSHIP / IPV6_LEAVE_GROUP. */ +#ifndef IPV6_DROP_MEMBERSHIP +#ifdef IPV6_LEAVE_GROUP +#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP +#endif /* IPV6_LEAVE_GROUP */ +#endif /* !IPV6_DROP_MEMBERSHIP */ + typedef int t_socket; typedef t_socket *p_socket; typedef struct sockaddr_storage t_sockaddr_storage; diff --git a/external/lua/luasocket/wsocket.c b/external/lua/luasocket/wsocket.c index 19b3f11b37..b4a4384f1e 100644 --- a/external/lua/luasocket/wsocket.c +++ b/external/lua/luasocket/wsocket.c @@ -238,8 +238,10 @@ int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent, /*-------------------------------------------------------------------------*\ * Receive with timeout \*-------------------------------------------------------------------------*/ -int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { - int err; +int socket_recv(p_socket ps, char *data, size_t count, size_t *got, + p_timeout tm) +{ + int err, prev = IO_DONE; *got = 0; if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { @@ -250,7 +252,14 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm } if (taken == 0) return IO_CLOSED; err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK) return err; + /* On UDP, a connreset simply means the previous send failed. + * So we try again. + * On TCP, it means our socket is now useless, so the error passes. + * (We will loop again, exiting because the same error will happen) */ + if (err != WSAEWOULDBLOCK) { + if (err != WSAECONNRESET || prev == WSAECONNRESET) return err; + prev = err; + } if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } } @@ -259,8 +268,9 @@ int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm * Recvfrom with timeout \*-------------------------------------------------------------------------*/ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, - SA *addr, socklen_t *len, p_timeout tm) { - int err; + SA *addr, socklen_t *len, p_timeout tm) +{ + int err, prev = IO_DONE; *got = 0; if (*ps == SOCKET_INVALID) return IO_CLOSED; for ( ;; ) { @@ -271,7 +281,14 @@ int socket_recvfrom(p_socket ps, char *data, size_t count, size_t *got, } if (taken == 0) return IO_CLOSED; err = WSAGetLastError(); - if (err != WSAEWOULDBLOCK) return err; + /* On UDP, a connreset simply means the previous send failed. + * So we try again. + * On TCP, it means our socket is now useless, so the error passes. + * (We will loop again, exiting because the same error will happen) */ + if (err != WSAEWOULDBLOCK) { + if (err != WSAECONNRESET || prev == WSAECONNRESET) return err; + prev = err; + } if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; } } @@ -400,14 +417,18 @@ const char *socket_gaistrerror(int err) { case EAI_MEMORY: return "memory allocation failure"; case EAI_NONAME: return "host or service not provided, or not known"; -// case EAI_OVERFLOW: return "argument buffer overflow"; +#ifdef EAI_OVERFLOW + case EAI_OVERFLOW: return "argument buffer overflow"; +#endif #ifdef EAI_PROTOCOL case EAI_PROTOCOL: return "resolved protocol is unknown"; #endif case EAI_SERVICE: return "service not supported for socket type"; case EAI_SOCKTYPE: return "ai_socktype not supported"; -// case EAI_SYSTEM: return strerror(errno); - default: return gai_strerrorA(err); +#ifdef EAI_SYSTEM + case EAI_SYSTEM: return strerror(errno); +#endif + default: return gai_strerror(err); } } diff --git a/external/lua/luasocket/wsocket.h b/external/lua/luasocket/wsocket.h index 0783b00d84..398664026f 100644 --- a/external/lua/luasocket/wsocket.h +++ b/external/lua/luasocket/wsocket.h @@ -16,10 +16,18 @@ typedef SOCKADDR_STORAGE t_sockaddr_storage; typedef SOCKET t_socket; typedef t_socket *p_socket; +#ifndef IPV6_V6ONLY +#define IPV6_V6ONLY 27 +#endif + #define SOCKET_INVALID (INVALID_SOCKET) #ifndef SO_REUSEPORT #define SO_REUSEPORT SO_REUSEADDR #endif +#ifndef AI_NUMERICSERV +#define AI_NUMERICSERV (0) +#endif + #endif /* WSOCKET_H */ diff --git a/templates/cocos2dx_files.json.REMOVED.git-id b/templates/cocos2dx_files.json.REMOVED.git-id index 5bd936f744..bc724cbad7 100644 --- a/templates/cocos2dx_files.json.REMOVED.git-id +++ b/templates/cocos2dx_files.json.REMOVED.git-id @@ -1 +1 @@ -4dfa7f46c2e06a4b3b95120bea3b8689f31ddad0 \ No newline at end of file +0e57176759699380bff62de2c00626d3fe350774 \ No newline at end of file diff --git a/templates/lua-template-default/frameworks/runtime-src/proj.win32/HelloLua.vcxproj b/templates/lua-template-default/frameworks/runtime-src/proj.win32/HelloLua.vcxproj index ed405aed3a..fc144ea9a9 100644 --- a/templates/lua-template-default/frameworks/runtime-src/proj.win32/HelloLua.vcxproj +++ b/templates/lua-template-default/frameworks/runtime-src/proj.win32/HelloLua.vcxproj @@ -104,14 +104,7 @@ - if not exist "$(OutDir)" mkdir "$(OutDir)" -if exist "$(OutDir)\Resource" rd /s /q "$(OutDir)\Resource" -mkdir "$(OutDir)\Resource" -mkdir "$(OutDir)\Resource\src" -mkdir "$(OutDir)\Resource\res" -xcopy "$(ProjectDir)..\..\cocos2d-x\cocos\scripting\lua-bindings\script" "$(OutDir)\Resource" /e /Y -xcopy "$(ProjectDir)..\..\..\src" "$(OutDir)\Resource\src" /e /Y -xcopy "$(ProjectDir)..\..\..\res" "$(OutDir)\Resource\res" /e /Y + xcopy "$(ProjectDir)..\..\cocos2d-x\cocos\scripting\lua-bindings\script" "$(ProjectDir)..\..\..\" /e /Y copy files @@ -158,14 +151,7 @@ xcopy /Y /Q "$(EngineRoot)external\websockets\prebuilt\win32\*.*" "$(OutDir)" - if not exist "$(OutDir)" mkdir "$(OutDir)" -if exist "$(OutDir)\Resource" rd /s /q "$(OutDir)\Resource" -mkdir "$(OutDir)\Resource" -mkdir "$(OutDir)\Resource\src" -mkdir "$(OutDir)\Resource\res" -xcopy "$(ProjectDir)..\..\cocos2d-x\cocos\scripting\lua-bindings\script" "$(OutDir)\Resource" /e /Y -xcopy "$(ProjectDir)..\..\..\src" "$(OutDir)\Resource\src" /e /Y -xcopy "$(ProjectDir)..\..\..\res" "$(OutDir)\Resource\res" /e /Y + xcopy "$(ProjectDir)..\..\cocos2d-x\cocos\scripting\lua-bindings\script" "$(ProjectDir)..\..\..\" /e /Y copy files @@ -226,4 +212,4 @@ xcopy /Y /Q "$(EngineRoot)external\websockets\prebuilt\win32\*.*" "$(OutDir)" - + \ No newline at end of file diff --git a/templates/lua-template-default/frameworks/runtime-src/proj.win32/HelloLua.vcxproj.user b/templates/lua-template-default/frameworks/runtime-src/proj.win32/HelloLua.vcxproj.user index 16617e63da..87053a96af 100644 --- a/templates/lua-template-default/frameworks/runtime-src/proj.win32/HelloLua.vcxproj.user +++ b/templates/lua-template-default/frameworks/runtime-src/proj.win32/HelloLua.vcxproj.user @@ -2,8 +2,8 @@ false - $(OutDir)/Resource - $(OutDir)/Resource + $(ProjectDir)..\..\.. + $(ProjectDir)..\..\.. WindowsLocalDebugger WindowsLocalDebugger diff --git a/tests/lua-empty-test/project/proj.win32/lua-empty-test.vcxproj b/tests/lua-empty-test/project/proj.win32/lua-empty-test.vcxproj index f8f6d94ae9..54542c8dd0 100644 --- a/tests/lua-empty-test/project/proj.win32/lua-empty-test.vcxproj +++ b/tests/lua-empty-test/project/proj.win32/lua-empty-test.vcxproj @@ -104,13 +104,8 @@ MachineX86 - if not exist "$(OutDir)" mkdir "$(OutDir)" -if exist "$(OutDir)\lua-empty-test-res" rd /s /q "$(OutDir)\lua-empty-test-res" -mkdir "$(OutDir)\lua-empty-test-res\res" -mkdir "$(OutDir)\lua-empty-test-res\src" -xcopy "$(ProjectDir)..\..\..\..\cocos\scripting\lua-bindings\script" "$(OutDir)\lua-empty-test-res" /e /Y -xcopy "$(ProjectDir)..\..\src" "$(OutDir)\lua-empty-test-res\src" /e /Y -xcopy "$(ProjectDir)..\..\res" "$(OutDir)\lua-empty-test-res\res" /e /Y + xcopy "$(ProjectDir)..\..\..\..\cocos\scripting\lua-bindings\script" "$(ProjectDir)..\..\" /e /Y +xcopy "$(ProjectDir)..\..\..\..\external\lua\luasocket\*.lua" "$(ProjectDir)..\..\" /e /Y if not exist "$(OutDir)" mkdir "$(OutDir)" @@ -163,13 +158,8 @@ xcopy /Y /Q "$(ProjectDir)..\..\..\..\external\websockets\prebuilt\win32\*.*" "$ - if not exist "$(OutDir)" mkdir "$(OutDir)" -if exist "$(OutDir)\lua-empty-test-res" rd /s /q "$(OutDir)\lua-empty-test-res" -mkdir "$(OutDir)\lua-empty-test-res\res" -mkdir "$(OutDir)\lua-empty-test-res\src" -xcopy "$(ProjectDir)..\..\..\..\cocos\scripting\lua-bindings\script" "$(OutDir)\lua-empty-test-res" /e /Y -xcopy "$(ProjectDir)..\..\src" "$(OutDir)\lua-empty-test-res\src" /e /Y -xcopy "$(ProjectDir)..\..\res" "$(OutDir)\lua-empty-test-res\res" /e /Y + xcopy "$(ProjectDir)..\..\..\..\cocos\scripting\lua-bindings\script" "$(ProjectDir)..\..\" /e /Y +xcopy "$(ProjectDir)..\..\..\..\external\lua\luasocket\*.lua" "$(ProjectDir)..\..\" /e /Y diff --git a/tests/lua-empty-test/project/proj.win32/lua-empty-test.vcxproj.user b/tests/lua-empty-test/project/proj.win32/lua-empty-test.vcxproj.user index a53adf3b0e..759c8a2b28 100644 --- a/tests/lua-empty-test/project/proj.win32/lua-empty-test.vcxproj.user +++ b/tests/lua-empty-test/project/proj.win32/lua-empty-test.vcxproj.user @@ -1,11 +1,11 @@  - $(OutDir)/lua-empty-test-res + $(ProjectDir)..\.. WindowsLocalDebugger - $(OutDir)/lua-empty-test-res + $(ProjectDir)..\.. WindowsLocalDebugger \ No newline at end of file diff --git a/tests/lua-tests/project/proj.win32/lua-tests.win32.vcxproj b/tests/lua-tests/project/proj.win32/lua-tests.win32.vcxproj index c302683476..b600b502ab 100644 --- a/tests/lua-tests/project/proj.win32/lua-tests.win32.vcxproj +++ b/tests/lua-tests/project/proj.win32/lua-tests.win32.vcxproj @@ -104,14 +104,8 @@ - if not exist "$(OutDir)" mkdir "$(OutDir)" -if exist "$(OutDir)\lua-tests-res" rd /s /q "$(OutDir)\lua-tests-res" -mkdir "$(OutDir)\lua-tests-res" -mkdir "$(OutDir)\lua-tests-res\src" -xcopy "$(ProjectDir)..\..\..\..\cocos\scripting\lua-bindings\script" "$(OutDir)\lua-tests-res" /e /Y -xcopy "$(ProjectDir)..\..\src" "$(OutDir)\lua-tests-res\src" /e /Y -xcopy "$(ProjectDir)..\..\..\cpp-tests\Resources" "$(OutDir)\lua-tests-res" /e /Y -xcopy "$(ProjectDir)..\..\res" "$(OutDir)\lua-tests-res" /e /Y + xcopy "$(ProjectDir)..\..\..\..\cocos\scripting\lua-bindings\script" "$(ProjectDir)..\.." /e /Y +xcopy "$(ProjectDir)..\..\..\cpp-tests\Resources" "$(ProjectDir)..\..\res" /e /Y copy files @@ -158,14 +152,8 @@ xcopy /Y /Q "$(EngineRoot)external\websockets\prebuilt\win32\*.*" "$(OutDir)" - if not exist "$(OutDir)" mkdir "$(OutDir)" -if exist "$(OutDir)\lua-tests-res" rd /s /q "$(OutDir)\lua-tests-res" -mkdir "$(OutDir)\lua-tests-res" -mkdir "$(OutDir)\lua-tests-res\src" -xcopy "$(ProjectDir)..\..\..\..\cocos\scripting\lua-bindings\script" "$(OutDir)\lua-tests-res" /e /Y -xcopy "$(ProjectDir)..\..\src" "$(OutDir)\lua-tests-res\src" /e /Y -xcopy "$(ProjectDir)..\..\..\cpp-tests\Resources" "$(OutDir)\lua-tests-res" /e /Y -xcopy "$(ProjectDir)..\..\res" "$(OutDir)\lua-tests-res" /e /Y + xcopy "$(ProjectDir)..\..\..\..\cocos\scripting\lua-bindings\script" "$(ProjectDir)..\.." /e /Y +xcopy "$(ProjectDir)..\..\..\cpp-tests\Resources" "$(ProjectDir)..\..\res" /e /Y copy files @@ -221,4 +209,4 @@ xcopy /Y /Q "$(EngineRoot)external\websockets\prebuilt\win32\*.*" "$(OutDir)" - + \ No newline at end of file diff --git a/tests/lua-tests/project/proj.win32/lua-tests.win32.vcxproj.user b/tests/lua-tests/project/proj.win32/lua-tests.win32.vcxproj.user index e03bdd0e1f..d95ebfe30b 100644 --- a/tests/lua-tests/project/proj.win32/lua-tests.win32.vcxproj.user +++ b/tests/lua-tests/project/proj.win32/lua-tests.win32.vcxproj.user @@ -2,8 +2,8 @@ false - $(OutDir)/lua-tests-res - $(OutDir)/lua-tests-res + $(ProjectDir)..\.. + $(ProjectDir)..\.. WindowsLocalDebugger WindowsLocalDebugger From 21a21c2d3dd0e59f0f1b45665225e45790157b23 Mon Sep 17 00:00:00 2001 From: samuele3hu Date: Thu, 20 Mar 2014 18:09:52 +0800 Subject: [PATCH 2/2] close #4400: Update the anrroid.mk for lua-bindings --- cocos/scripting/lua-bindings/Android.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cocos/scripting/lua-bindings/Android.mk b/cocos/scripting/lua-bindings/Android.mk index 134c453f88..f63d208705 100644 --- a/cocos/scripting/lua-bindings/Android.mk +++ b/cocos/scripting/lua-bindings/Android.mk @@ -41,16 +41,15 @@ LOCAL_SRC_FILES := manual/CCLuaBridge.cpp \ ../../../external/lua/tolua/tolua_push.c \ ../../../external/lua/tolua/tolua_to.c \ ../../../external/lua/luasocket/auxiliar.c \ - ../../../external/lua/luasocket/luasocket_buffer.c \ + ../../../external/lua/luasocket/buffer.c \ ../../../external/lua/luasocket/except.c \ ../../../external/lua/luasocket/inet.c \ - ../../../external/lua/luasocket/luasocket_io.c \ + ../../../external/lua/luasocket/io.c \ ../../../external/lua/luasocket/luasocket.c \ ../../../external/lua/luasocket/mime.c \ ../../../external/lua/luasocket/options.c \ ../../../external/lua/luasocket/select.c \ ../../../external/lua/luasocket/serial.c \ - ../../../external/lua/luasocket/socket_scripts.c \ ../../../external/lua/luasocket/tcp.c \ ../../../external/lua/luasocket/timeout.c \ ../../../external/lua/luasocket/udp.c \