初始化提交
This commit is contained in:
		
							
								
								
									
										162
									
								
								Plugins/slua_unreal/External/luasocket/auxiliar.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								Plugins/slua_unreal/External/luasocket/auxiliar.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | ||||
| /*=========================================================================*\ | ||||
| * Auxiliar routines for class hierarchy manipulation | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include "auxiliar.h" | ||||
|  | ||||
| namespace NS_SLUA { | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Exported functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes the module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int auxiliar_open(lua_State *L) { | ||||
|     (void) L; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Creates a new class with given methods | ||||
| * Methods whose names start with __ are passed directly to the metatable. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func) { | ||||
|     luaL_newmetatable(L, classname); /* mt */ | ||||
|     /* create __index table to place methods */ | ||||
|     lua_pushstring(L, "__index");    /* mt,"__index" */ | ||||
|     lua_newtable(L);                 /* mt,"__index",it */  | ||||
|     /* put class name into class metatable */ | ||||
|     lua_pushstring(L, "class");      /* mt,"__index",it,"class" */ | ||||
|     lua_pushstring(L, classname);    /* mt,"__index",it,"class",classname */ | ||||
|     lua_rawset(L, -3);               /* mt,"__index",it */ | ||||
|     /* pass all methods that start with _ to the metatable, and all others | ||||
|      * to the index table */ | ||||
|     for (; func->name; func++) {     /* mt,"__index",it */ | ||||
|         lua_pushstring(L, func->name); | ||||
|         lua_pushcfunction(L, func->func); | ||||
|         lua_rawset(L, func->name[0] == '_' ? -5: -3); | ||||
|     } | ||||
|     lua_rawset(L, -3);               /* mt */ | ||||
|     lua_pop(L, 1); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Prints the value of a class in a nice way | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int auxiliar_tostring(lua_State *L) { | ||||
|     char buf[32]; | ||||
|     if (!lua_getmetatable(L, 1)) goto error; | ||||
|     lua_pushstring(L, "__index"); | ||||
|     lua_gettable(L, -2); | ||||
|     if (!lua_istable(L, -1)) goto error; | ||||
|     lua_pushstring(L, "class"); | ||||
|     lua_gettable(L, -2); | ||||
|     if (!lua_isstring(L, -1)) goto error; | ||||
|     sprintf(buf, "%p", lua_touserdata(L, 1)); | ||||
|     lua_pushfstring(L, "%s: %s", lua_tostring(L, -1), buf); | ||||
|     return 1; | ||||
| error: | ||||
|     lua_pushstring(L, "invalid object passed to 'auxiliar.c:__tostring'"); | ||||
|     lua_error(L); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Insert class into group | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void auxiliar_add2group(lua_State *L, const char *classname, const char *groupname) { | ||||
|     luaL_getmetatable(L, classname); | ||||
|     lua_pushstring(L, groupname); | ||||
|     lua_pushboolean(L, 1); | ||||
|     lua_rawset(L, -3); | ||||
|     lua_pop(L, 1); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Make sure argument is a boolean | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int auxiliar_checkboolean(lua_State *L, int objidx) { | ||||
|     if (!lua_isboolean(L, objidx)) | ||||
|         auxiliar_typeerror(L, objidx, lua_typename(L, LUA_TBOOLEAN)); | ||||
|     return lua_toboolean(L, objidx); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Return userdata pointer if object belongs to a given class, abort with  | ||||
| * error otherwise | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx) { | ||||
|     void *data = auxiliar_getclassudata(L, classname, objidx); | ||||
|     if (!data) { | ||||
|         char msg[45]; | ||||
|         sprintf(msg, "%.35s expected", classname); | ||||
|         luaL_argerror(L, objidx, msg); | ||||
|     } | ||||
|     return data; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Return userdata pointer if object belongs to a given group, abort with  | ||||
| * error otherwise | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx) { | ||||
|     void *data = auxiliar_getgroupudata(L, groupname, objidx); | ||||
|     if (!data) { | ||||
|         char msg[45]; | ||||
|         sprintf(msg, "%.35s expected", groupname); | ||||
|         luaL_argerror(L, objidx, msg); | ||||
|     } | ||||
|     return data; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Set object class | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void auxiliar_setclass(lua_State *L, const char *classname, int objidx) { | ||||
|     luaL_getmetatable(L, classname); | ||||
|     if (objidx < 0) objidx--; | ||||
|     lua_setmetatable(L, objidx); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Get a userdata pointer if object belongs to a given group. Return NULL  | ||||
| * otherwise | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx) { | ||||
|     if (!lua_getmetatable(L, objidx)) | ||||
|         return NULL; | ||||
|     lua_pushstring(L, groupname); | ||||
|     lua_rawget(L, -2); | ||||
|     if (lua_isnil(L, -1)) { | ||||
|         lua_pop(L, 2); | ||||
|         return NULL; | ||||
|     } else { | ||||
|         lua_pop(L, 2); | ||||
|         return lua_touserdata(L, objidx); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Get a userdata pointer if object belongs to a given class. Return NULL  | ||||
| * otherwise | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void *auxiliar_getclassudata(lua_State *L, const char *classname, int objidx) { | ||||
|     return luaL_checkudata(L, objidx, classname); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Throws error when argument does not have correct type. | ||||
| * Used to be part of lauxlib in Lua 5.1, was dropped from 5.2. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int auxiliar_typeerror (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); | ||||
| } | ||||
|  | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										51
									
								
								Plugins/slua_unreal/External/luasocket/auxiliar.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								Plugins/slua_unreal/External/luasocket/auxiliar.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| #ifndef AUXILIAR_H | ||||
| #define AUXILIAR_H | ||||
| /*=========================================================================*\ | ||||
| * Auxiliar routines for class hierarchy manipulation | ||||
| * LuaSocket toolkit (but completely independent of other LuaSocket modules) | ||||
| * | ||||
| * A LuaSocket class is a name associated with Lua metatables. A LuaSocket  | ||||
| * group is a name associated with a class. A class can belong to any number  | ||||
| * of groups. This module provides the functionality to: | ||||
| * | ||||
| *   - create new classes  | ||||
| *   - add classes to groups  | ||||
| *   - set the class of objects | ||||
| *   - check if an object belongs to a given class or group | ||||
| *   - get the userdata associated to objects | ||||
| *   - print objects in a pretty way | ||||
| * | ||||
| * LuaSocket class names follow the convention <module>{<class>}. Modules | ||||
| * can define any number of classes and groups. The module tcp.c, for | ||||
| * example, defines the classes tcp{master}, tcp{client} and tcp{server} and | ||||
| * the groups tcp{client,server} and tcp{any}. Module functions can then | ||||
| * perform type-checking on their arguments by either class or group. | ||||
| * | ||||
| * LuaSocket metatables define the __index metamethod as being a table. This | ||||
| * table has one field for each method supported by the class, and a field | ||||
| * "class" with the class name. | ||||
| * | ||||
| * The mapping from class name to the corresponding metatable and the | ||||
| * reverse mapping are done using lauxlib.  | ||||
| \*=========================================================================*/ | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| namespace NS_SLUA { | ||||
|  | ||||
| int auxiliar_open(lua_State *L); | ||||
| void auxiliar_newclass(lua_State *L, const char *classname, luaL_Reg *func); | ||||
| void auxiliar_add2group(lua_State *L, const char *classname, const char *group); | ||||
| void auxiliar_setclass(lua_State *L, const char *classname, int objidx); | ||||
| void *auxiliar_checkclass(lua_State *L, const char *classname, int objidx); | ||||
| void *auxiliar_checkgroup(lua_State *L, const char *groupname, int objidx); | ||||
| void *auxiliar_getclassudata(lua_State *L, const char *groupname, int objidx); | ||||
| void *auxiliar_getgroupudata(lua_State *L, const char *groupname, int objidx); | ||||
| int auxiliar_checkboolean(lua_State *L, int objidx); | ||||
| int auxiliar_tostring(lua_State *L); | ||||
| int auxiliar_typeerror(lua_State *L, int narg, const char *tname); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* AUXILIAR_H */ | ||||
							
								
								
									
										280
									
								
								Plugins/slua_unreal/External/luasocket/buffer.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								Plugins/slua_unreal/External/luasocket/buffer.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,280 @@ | ||||
| /*=========================================================================*\ | ||||
| * Input/Output interface for Lua programs | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "buffer.h" | ||||
|  | ||||
| namespace NS_SLUA { | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes | ||||
| \*=========================================================================*/ | ||||
| static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b); | ||||
| static int recvline(p_buffer buf, luaL_Buffer *b); | ||||
| static int recvall(p_buffer buf, luaL_Buffer *b); | ||||
| static int buffer_get(p_buffer buf, const char **data, size_t *count); | ||||
| static void buffer_skip(p_buffer buf, size_t count); | ||||
| static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent); | ||||
|  | ||||
| /* min and max macros */ | ||||
| #ifndef MIN | ||||
| #define MIN(x, y) ((x) < (y) ? x : y) | ||||
| #endif | ||||
| #ifndef MAX | ||||
| #define MAX(x, y) ((x) > (y) ? x : y) | ||||
| #endif | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Exported functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int buffer_open(lua_State *L) { | ||||
|     (void) L; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes C structure  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void buffer_init(p_buffer buf, p_io io, p_timeout tm) { | ||||
|     buf->first = buf->last = 0; | ||||
|     buf->io = io; | ||||
|     buf->tm = tm; | ||||
|     buf->received = buf->sent = 0; | ||||
|     buf->birthday = timeout_gettime(); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * object:getstats() interface | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int buffer_meth_getstats(lua_State *L, p_buffer buf) { | ||||
|     lua_pushnumber(L, (lua_Number) buf->received); | ||||
|     lua_pushnumber(L, (lua_Number) buf->sent); | ||||
|     lua_pushnumber(L, timeout_gettime() - buf->birthday); | ||||
|     return 3; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * object:setstats() interface | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int buffer_meth_setstats(lua_State *L, p_buffer buf) { | ||||
|     buf->received = (long) luaL_optnumber(L, 2, (lua_Number) buf->received);  | ||||
|     buf->sent = (long) luaL_optnumber(L, 3, (lua_Number) buf->sent);  | ||||
|     if (lua_isnumber(L, 4)) buf->birthday = timeout_gettime() - lua_tonumber(L, 4); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * object:send() interface | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int buffer_meth_send(lua_State *L, p_buffer buf) { | ||||
|     int top = lua_gettop(L); | ||||
|     int err = IO_DONE; | ||||
|     size_t size = 0, sent = 0; | ||||
|     const char *data = luaL_checklstring(L, 2, &size); | ||||
|     long start = (long) luaL_optnumber(L, 3, 1); | ||||
|     long end = (long) luaL_optnumber(L, 4, -1); | ||||
| #ifdef LUASOCKET_DEBUG | ||||
|     p_timeout tm = timeout_markstart(buf->tm); | ||||
| #endif | ||||
|     if (start < 0) start = (long) (size+start+1); | ||||
|     if (end < 0) end = (long) (size+end+1); | ||||
|     if (start < 1) start = (long) 1; | ||||
|     if (end > (long) size) end = (long) size; | ||||
|     if (start <= end) err = sendraw(buf, data+start-1, end-start+1, &sent); | ||||
|     /* check if there was an error */ | ||||
|     if (err != IO_DONE) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, buf->io->error(buf->io->ctx, err));  | ||||
|         lua_pushnumber(L, (lua_Number) (sent+start-1)); | ||||
|     } else { | ||||
|         lua_pushnumber(L, (lua_Number) (sent+start-1)); | ||||
|         lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|     } | ||||
| #ifdef LUASOCKET_DEBUG | ||||
|     /* push time elapsed during operation as the last return value */ | ||||
|     lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); | ||||
| #endif | ||||
|     return lua_gettop(L) - top; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * object:receive() interface | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int buffer_meth_receive(lua_State *L, p_buffer buf) { | ||||
|     int err = IO_DONE, top = lua_gettop(L); | ||||
|     luaL_Buffer b; | ||||
|     size_t size; | ||||
|     const char *part = luaL_optlstring(L, 3, "", &size); | ||||
| #ifdef LUASOCKET_DEBUG | ||||
|     p_timeout tm = timeout_markstart(buf->tm); | ||||
| #endif | ||||
|     /* initialize buffer with optional extra prefix  | ||||
|      * (useful for concatenating previous partial results) */ | ||||
|     luaL_buffinit(L, &b); | ||||
|     luaL_addlstring(&b, part, size); | ||||
|     /* receive new patterns */ | ||||
|     if (!lua_isnumber(L, 2)) { | ||||
|         const char *p= luaL_optstring(L, 2, "*l"); | ||||
|         if (p[0] == '*' && p[1] == 'l') err = recvline(buf, &b); | ||||
|         else if (p[0] == '*' && p[1] == 'a') err = recvall(buf, &b);  | ||||
|         else luaL_argcheck(L, 0, 2, "invalid receive pattern"); | ||||
|     /* get a fixed number of bytes (minus what was already partially  | ||||
|      * received) */ | ||||
|     } else { | ||||
|         double n = lua_tonumber(L, 2);  | ||||
|         size_t wanted = (size_t) n; | ||||
|         luaL_argcheck(L, n >= 0, 2, "invalid receive pattern"); | ||||
|         if (size == 0 || wanted > size) | ||||
|             err = recvraw(buf, wanted-size, &b); | ||||
|     } | ||||
|     /* check if there was an error */ | ||||
|     if (err != IO_DONE) { | ||||
|         /* we can't push anyting in the stack before pushing the | ||||
|          * contents of the buffer. this is the reason for the complication */ | ||||
|         luaL_pushresult(&b); | ||||
|         lua_pushstring(L, buf->io->error(buf->io->ctx, err));  | ||||
|         lua_pushvalue(L, -2);  | ||||
|         lua_pushnil(L); | ||||
|         lua_replace(L, -4); | ||||
|     } else { | ||||
|         luaL_pushresult(&b); | ||||
|         lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|     } | ||||
| #ifdef LUASOCKET_DEBUG | ||||
|     /* push time elapsed during operation as the last return value */ | ||||
|     lua_pushnumber(L, timeout_gettime() - timeout_getstart(tm)); | ||||
| #endif | ||||
|     return lua_gettop(L) - top; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Determines if there is any data in the read buffer | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int buffer_isempty(p_buffer buf) { | ||||
|     return buf->first >= buf->last; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Sends a block of data (unbuffered) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #define STEPSIZE 8192 | ||||
| static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) { | ||||
|     p_io io = buf->io; | ||||
|     p_timeout tm = buf->tm; | ||||
|     size_t total = 0; | ||||
|     int err = IO_DONE; | ||||
|     while (total < count && err == IO_DONE) { | ||||
|         size_t done = 0; | ||||
|         size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE; | ||||
|         err = io->send(io->ctx, data+total, step, &done, tm); | ||||
|         total += done; | ||||
|     } | ||||
|     *sent = total; | ||||
|     buf->sent += total; | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Reads a fixed number of bytes (buffered) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int recvraw(p_buffer buf, size_t wanted, luaL_Buffer *b) { | ||||
|     int err = IO_DONE; | ||||
|     size_t total = 0; | ||||
|     while (err == IO_DONE) { | ||||
|         size_t count; const char *data; | ||||
|         err = buffer_get(buf, &data, &count); | ||||
|         count = MIN(count, wanted - total); | ||||
|         luaL_addlstring(b, data, count); | ||||
|         buffer_skip(buf, count); | ||||
|         total += count; | ||||
|         if (total >= wanted) break; | ||||
|     } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Reads everything until the connection is closed (buffered) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int recvall(p_buffer buf, luaL_Buffer *b) { | ||||
|     int err = IO_DONE; | ||||
|     size_t total = 0; | ||||
|     while (err == IO_DONE) { | ||||
|         const char *data; size_t count; | ||||
|         err = buffer_get(buf, &data, &count); | ||||
|         total += count; | ||||
|         luaL_addlstring(b, data, count); | ||||
|         buffer_skip(buf, count); | ||||
|     } | ||||
|     if (err == IO_CLOSED) { | ||||
|         if (total > 0) return IO_DONE; | ||||
|         else return IO_CLOSED; | ||||
|     } else return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Reads a line terminated by a CR LF pair or just by a LF. The CR and LF  | ||||
| * are not returned by the function and are discarded from the buffer | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int recvline(p_buffer buf, luaL_Buffer *b) { | ||||
|     int err = IO_DONE; | ||||
|     while (err == IO_DONE) { | ||||
|         size_t count, pos; const char *data; | ||||
|         err = buffer_get(buf, &data, &count); | ||||
|         pos = 0; | ||||
|         while (pos < count && data[pos] != '\n') { | ||||
|             /* we ignore all \r's */ | ||||
|             if (data[pos] != '\r') luaL_addchar(b, data[pos]); | ||||
|             pos++; | ||||
|         } | ||||
|         if (pos < count) { /* found '\n' */ | ||||
|             buffer_skip(buf, pos+1); /* skip '\n' too */ | ||||
|             break; /* we are done */ | ||||
|         } else /* reached the end of the buffer */ | ||||
|             buffer_skip(buf, pos); | ||||
|     } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Skips a given number of bytes from read buffer. No data is read from the | ||||
| * transport layer | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static void buffer_skip(p_buffer buf, size_t count) { | ||||
|     buf->received += count; | ||||
|     buf->first += count; | ||||
|     if (buffer_isempty(buf))  | ||||
|         buf->first = buf->last = 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Return any data available in buffer, or get more data from transport layer | ||||
| * if buffer is empty | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int buffer_get(p_buffer buf, const char **data, size_t *count) { | ||||
|     int err = IO_DONE; | ||||
|     p_io io = buf->io; | ||||
|     p_timeout tm = buf->tm; | ||||
|     if (buffer_isempty(buf)) { | ||||
|         size_t got; | ||||
|         err = io->recv(io->ctx, buf->data, BUF_SIZE, &got, tm); | ||||
|         buf->first = 0; | ||||
|         buf->last = got; | ||||
|     } | ||||
|     *count = buf->last - buf->first; | ||||
|     *data = buf->data + buf->first; | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										49
									
								
								Plugins/slua_unreal/External/luasocket/buffer.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								Plugins/slua_unreal/External/luasocket/buffer.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| #ifndef BUF_H | ||||
| #define BUF_H  | ||||
| /*=========================================================================*\ | ||||
| * Input/Output interface for Lua programs | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * Line patterns require buffering. Reading one character at a time involves | ||||
| * too many system calls and is very slow. This module implements the | ||||
| * LuaSocket interface for input/output on connected objects, as seen by  | ||||
| * Lua programs.  | ||||
| * | ||||
| * Input is buffered. Output is *not* buffered because there was no simple | ||||
| * way of making sure the buffered output data would ever be sent. | ||||
| * | ||||
| * The module is built on top of the I/O abstraction defined in io.h and the | ||||
| * timeout management is done with the timeout.h interface. | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
|  | ||||
| #include "io.h" | ||||
| #include "timeout.h" | ||||
|  | ||||
| /* buffer size in bytes */ | ||||
| #define BUF_SIZE 8192 | ||||
|  | ||||
| namespace NS_SLUA { | ||||
|  | ||||
| /* buffer control structure */ | ||||
| typedef struct t_buffer_ { | ||||
|     double birthday;        /* throttle support info: creation time, */ | ||||
|     size_t sent, received;  /* bytes sent, and bytes received */ | ||||
|     p_io io;                /* IO driver used for this buffer */ | ||||
|     p_timeout tm;           /* timeout management for this buffer */ | ||||
|     size_t first, last;     /* index of first and last bytes of stored data */ | ||||
|     char data[BUF_SIZE];    /* storage space for buffer data */ | ||||
| } t_buffer; | ||||
| typedef t_buffer *p_buffer; | ||||
|  | ||||
| int buffer_open(lua_State *L); | ||||
| void buffer_init(p_buffer buf, p_io io, p_timeout tm); | ||||
| int buffer_meth_send(lua_State *L, p_buffer buf); | ||||
| int buffer_meth_receive(lua_State *L, p_buffer buf); | ||||
| int buffer_meth_getstats(lua_State *L, p_buffer buf); | ||||
| int buffer_meth_setstats(lua_State *L, p_buffer buf); | ||||
| int buffer_isempty(p_buffer buf); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* BUF_H */ | ||||
							
								
								
									
										105
									
								
								Plugins/slua_unreal/External/luasocket/except.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								Plugins/slua_unreal/External/luasocket/except.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | ||||
| /*=========================================================================*\ | ||||
| * Simple exception support | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "except.h" | ||||
|  | ||||
| namespace NS_SLUA { | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes. | ||||
| \*=========================================================================*/ | ||||
| static int global_protect(lua_State *L); | ||||
| static int global_newtry(lua_State *L); | ||||
| static int protected_(lua_State *L); | ||||
| static int finalize(lua_State *L); | ||||
| static int do_nothing(lua_State *L); | ||||
|  | ||||
| /* except functions */ | ||||
| static luaL_Reg except_func[] = { | ||||
|     {"newtry",    global_newtry}, | ||||
|     {"protect",   global_protect}, | ||||
|     {NULL,        NULL} | ||||
| }; | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Try factory | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static void wrap(lua_State *L) { | ||||
|     lua_newtable(L); | ||||
|     lua_pushnumber(L, 1); | ||||
|     lua_pushvalue(L, -3); | ||||
|     lua_settable(L, -3); | ||||
|     lua_insert(L, -2); | ||||
|     lua_pop(L, 1); | ||||
| } | ||||
|  | ||||
| static int finalize(lua_State *L) { | ||||
|     if (!lua_toboolean(L, 1)) { | ||||
|         lua_pushvalue(L, lua_upvalueindex(1)); | ||||
|         lua_pcall(L, 0, 0, 0); | ||||
|         lua_settop(L, 2); | ||||
|         wrap(L); | ||||
|         lua_error(L); | ||||
|         return 0; | ||||
|     } else return lua_gettop(L); | ||||
| } | ||||
|  | ||||
| static int do_nothing(lua_State *L) {  | ||||
|     (void) L; | ||||
|     return 0;  | ||||
| } | ||||
|  | ||||
| static int global_newtry(lua_State *L) { | ||||
|     lua_settop(L, 1); | ||||
|     if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing); | ||||
|     lua_pushcclosure(L, finalize, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Protect factory | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unwrap(lua_State *L) { | ||||
|     if (lua_istable(L, -1)) { | ||||
|         lua_pushnumber(L, 1); | ||||
|         lua_gettable(L, -2); | ||||
|         lua_pushnil(L); | ||||
|         lua_insert(L, -2); | ||||
|         return 1; | ||||
|     } else return 0; | ||||
| } | ||||
|  | ||||
| static int protected_(lua_State *L) { | ||||
|     lua_pushvalue(L, lua_upvalueindex(1)); | ||||
|     lua_insert(L, 1); | ||||
|     if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) { | ||||
|         if (unwrap(L)) return 2; | ||||
|         else lua_error(L); | ||||
|         return 0; | ||||
|     } else return lua_gettop(L); | ||||
| } | ||||
|  | ||||
| static int global_protect(lua_State *L) { | ||||
|     lua_pushcclosure(L, protected_, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Init module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int except_open(lua_State *L) { | ||||
| #if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) | ||||
|     luaL_setfuncs(L, except_func, 0); | ||||
| #else | ||||
|     luaL_openlib(L, NULL, except_func, 0); | ||||
| #endif | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										37
									
								
								Plugins/slua_unreal/External/luasocket/except.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Plugins/slua_unreal/External/luasocket/except.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| #ifndef EXCEPT_H | ||||
| #define EXCEPT_H | ||||
| /*=========================================================================*\ | ||||
| * Exception control | ||||
| * LuaSocket toolkit (but completely independent from other modules) | ||||
| * | ||||
| * This provides support for simple exceptions in Lua. During the | ||||
| * development of the HTTP/FTP/SMTP support, it became aparent that | ||||
| * error checking was taking a substantial amount of the coding. These | ||||
| * function greatly simplify the task of checking errors. | ||||
| * | ||||
| * The main idea is that functions should return nil as its first return | ||||
| * value when it finds an error, and return an error message (or value) | ||||
| * following nil. In case of success, as long as the first value is not nil, | ||||
| * the other values don't matter. | ||||
| * | ||||
| * The idea is to nest function calls with the "try" function. This function | ||||
| * checks the first value, and calls "error" on the second if the first is | ||||
| * nil. Otherwise, it returns all values it received.  | ||||
| * | ||||
| * The protect function returns a new function that behaves exactly like the | ||||
| * function it receives, but the new function doesn't throw exceptions: it | ||||
| * returns nil followed by the error message instead. | ||||
| * | ||||
| * With these two function, it's easy to write functions that throw | ||||
| * exceptions on error, but that don't interrupt the user script.  | ||||
| \*=========================================================================*/ | ||||
|  | ||||
| #include "lua.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| int except_open(lua_State *L); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										287
									
								
								Plugins/slua_unreal/External/luasocket/ftp.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								Plugins/slua_unreal/External/luasocket/ftp.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,287 @@ | ||||
| R"-++**++-( | ||||
| ------------------------------------------------------------------- | ||||
| -- 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 | ||||
| )-++**++-"; | ||||
							
								
								
									
										106
									
								
								Plugins/slua_unreal/External/luasocket/headers.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								Plugins/slua_unreal/External/luasocket/headers.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,106 @@ | ||||
| R"-++**++-( | ||||
| --------------------------------------------------- | ||||
| -- Canonic header field capitalization | ||||
| -- LuaSocket toolkit. | ||||
| -- Author: Diego Nehab | ||||
| ----------------------------------------------------------------------------- | ||||
| local socket = require("socket") | ||||
| socket.headers = {} | ||||
| local _M = socket.headers | ||||
|  | ||||
| _M.canonic = { | ||||
|     ["accept"] = "Accept", | ||||
|     ["accept-charset"] = "Accept-Charset", | ||||
|     ["accept-encoding"] = "Accept-Encoding", | ||||
|     ["accept-language"] = "Accept-Language", | ||||
|     ["accept-ranges"] = "Accept-Ranges", | ||||
|     ["action"] = "Action", | ||||
|     ["alternate-recipient"] = "Alternate-Recipient", | ||||
|     ["age"] = "Age", | ||||
|     ["allow"] = "Allow", | ||||
|     ["arrival-date"] = "Arrival-Date", | ||||
|     ["authorization"] = "Authorization", | ||||
|     ["bcc"] = "Bcc", | ||||
|     ["cache-control"] = "Cache-Control", | ||||
|     ["cc"] = "Cc", | ||||
|     ["comments"] = "Comments", | ||||
|     ["connection"] = "Connection", | ||||
|     ["content-description"] = "Content-Description", | ||||
|     ["content-disposition"] = "Content-Disposition", | ||||
|     ["content-encoding"] = "Content-Encoding", | ||||
|     ["content-id"] = "Content-ID", | ||||
|     ["content-language"] = "Content-Language", | ||||
|     ["content-length"] = "Content-Length", | ||||
|     ["content-location"] = "Content-Location", | ||||
|     ["content-md5"] = "Content-MD5", | ||||
|     ["content-range"] = "Content-Range", | ||||
|     ["content-transfer-encoding"] = "Content-Transfer-Encoding", | ||||
|     ["content-type"] = "Content-Type", | ||||
|     ["cookie"] = "Cookie", | ||||
|     ["date"] = "Date", | ||||
|     ["diagnostic-code"] = "Diagnostic-Code", | ||||
|     ["dsn-gateway"] = "DSN-Gateway", | ||||
|     ["etag"] = "ETag", | ||||
|     ["expect"] = "Expect", | ||||
|     ["expires"] = "Expires", | ||||
|     ["final-log-id"] = "Final-Log-ID", | ||||
|     ["final-recipient"] = "Final-Recipient", | ||||
|     ["from"] = "From", | ||||
|     ["host"] = "Host", | ||||
|     ["if-match"] = "If-Match", | ||||
|     ["if-modified-since"] = "If-Modified-Since", | ||||
|     ["if-none-match"] = "If-None-Match", | ||||
|     ["if-range"] = "If-Range", | ||||
|     ["if-unmodified-since"] = "If-Unmodified-Since", | ||||
|     ["in-reply-to"] = "In-Reply-To", | ||||
|     ["keywords"] = "Keywords", | ||||
|     ["last-attempt-date"] = "Last-Attempt-Date", | ||||
|     ["last-modified"] = "Last-Modified", | ||||
|     ["location"] = "Location", | ||||
|     ["max-forwards"] = "Max-Forwards", | ||||
|     ["message-id"] = "Message-ID", | ||||
|     ["mime-version"] = "MIME-Version", | ||||
|     ["original-envelope-id"] = "Original-Envelope-ID", | ||||
|     ["original-recipient"] = "Original-Recipient", | ||||
|     ["pragma"] = "Pragma", | ||||
|     ["proxy-authenticate"] = "Proxy-Authenticate", | ||||
|     ["proxy-authorization"] = "Proxy-Authorization", | ||||
|     ["range"] = "Range", | ||||
|     ["received"] = "Received", | ||||
|     ["received-from-mta"] = "Received-From-MTA", | ||||
|     ["references"] = "References", | ||||
|     ["referer"] = "Referer", | ||||
|     ["remote-mta"] = "Remote-MTA", | ||||
|     ["reply-to"] = "Reply-To", | ||||
|     ["reporting-mta"] = "Reporting-MTA", | ||||
|     ["resent-bcc"] = "Resent-Bcc", | ||||
|     ["resent-cc"] = "Resent-Cc", | ||||
|     ["resent-date"] = "Resent-Date", | ||||
|     ["resent-from"] = "Resent-From", | ||||
|     ["resent-message-id"] = "Resent-Message-ID", | ||||
|     ["resent-reply-to"] = "Resent-Reply-To", | ||||
|     ["resent-sender"] = "Resent-Sender", | ||||
|     ["resent-to"] = "Resent-To", | ||||
|     ["retry-after"] = "Retry-After", | ||||
|     ["return-path"] = "Return-Path", | ||||
|     ["sender"] = "Sender", | ||||
|     ["server"] = "Server", | ||||
|     ["smtp-remote-recipient"] = "SMTP-Remote-Recipient", | ||||
|     ["status"] = "Status", | ||||
|     ["subject"] = "Subject", | ||||
|     ["te"] = "TE", | ||||
|     ["to"] = "To", | ||||
|     ["trailer"] = "Trailer", | ||||
|     ["transfer-encoding"] = "Transfer-Encoding", | ||||
|     ["upgrade"] = "Upgrade", | ||||
|     ["user-agent"] = "User-Agent", | ||||
|     ["vary"] = "Vary", | ||||
|     ["via"] = "Via", | ||||
|     ["warning"] = "Warning", | ||||
|     ["will-retry-until"] = "Will-Retry-Until", | ||||
|     ["www-authenticate"] = "WWW-Authenticate", | ||||
|     ["x-mailer"] = "X-Mailer", | ||||
| } | ||||
|  | ||||
| return _M | ||||
| )-++**++-"; | ||||
							
								
								
									
										356
									
								
								Plugins/slua_unreal/External/luasocket/http.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										356
									
								
								Plugins/slua_unreal/External/luasocket/http.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,356 @@ | ||||
| R"-++**++-( | ||||
| ----------------------------------------------------------------------------- | ||||
| -- 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 | ||||
| )-++**++-"; | ||||
							
								
								
									
										544
									
								
								Plugins/slua_unreal/External/luasocket/inet.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										544
									
								
								Plugins/slua_unreal/External/luasocket/inet.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,544 @@ | ||||
| /*=========================================================================*\ | ||||
| * Internet domain functions | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "inet.h" | ||||
|  | ||||
|  #ifdef _WIN32 | ||||
| #define gai_strerror gai_strerrorA | ||||
| #endif | ||||
|  | ||||
| namespace NS_SLUA { | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes. | ||||
| \*=========================================================================*/ | ||||
| static int inet_global_toip(lua_State *L); | ||||
| static int inet_global_getaddrinfo(lua_State *L); | ||||
| static int inet_global_tohostname(lua_State *L); | ||||
| static int inet_global_getnameinfo(lua_State *L); | ||||
| static void inet_pushresolved(lua_State *L, struct hostent *hp); | ||||
| static int inet_global_gethostname(lua_State *L); | ||||
|  | ||||
| /* DNS functions */ | ||||
| static luaL_Reg inet_func[] = { | ||||
|     { "toip", inet_global_toip}, | ||||
|     { "getaddrinfo", inet_global_getaddrinfo}, | ||||
|     { "tohostname", inet_global_tohostname}, | ||||
|     { "getnameinfo", inet_global_getnameinfo}, | ||||
|     { "gethostname", inet_global_gethostname}, | ||||
|     { NULL, NULL} | ||||
| }; | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Exported functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| 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, inet_func, 0); | ||||
| #else | ||||
|     luaL_openlib(L, NULL, inet_func, 0); | ||||
| #endif | ||||
|     lua_settable(L, -3); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Global Lua functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Returns all information provided by the resolver given a host name | ||||
| * or ip address | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int inet_gethost(const char *address, struct hostent **hp) { | ||||
|     struct in_addr addr; | ||||
|     if (inet_aton(address, &addr)) | ||||
|         return socket_gethostbyaddr((char *) &addr, sizeof(addr), hp); | ||||
|     else | ||||
|         return socket_gethostbyname(address, hp); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Returns all information provided by the resolver given a host name | ||||
| * or ip address | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int inet_global_tohostname(lua_State *L) { | ||||
|     const char *address = luaL_checkstring(L, 1); | ||||
|     struct hostent *hp = NULL; | ||||
|     int err = inet_gethost(address, &hp); | ||||
|     if (err != IO_DONE) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_hoststrerror(err)); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushstring(L, hp->h_name); | ||||
|     inet_pushresolved(L, hp); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| static int inet_global_getnameinfo(lua_State *L) { | ||||
|     char hbuf[NI_MAXHOST]; | ||||
|     char sbuf[NI_MAXSERV]; | ||||
|     int i, ret; | ||||
|     struct addrinfo hints; | ||||
|     struct addrinfo *resolved, *iter; | ||||
|     const char *host = luaL_optstring(L, 1, NULL); | ||||
|     const char *serv = luaL_optstring(L, 2, NULL); | ||||
|  | ||||
|     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; | ||||
|  | ||||
|     ret = getaddrinfo(host, serv, &hints, &resolved); | ||||
|     if (ret != 0) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_gaistrerror(ret)); | ||||
|         return 2; | ||||
|     } | ||||
|  | ||||
|     lua_newtable(L); | ||||
|     for (i = 1, iter = resolved; iter; i++, iter = iter->ai_next) { | ||||
|         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, hbuf); | ||||
|             lua_settable(L, -3); | ||||
|         } | ||||
|     } | ||||
|     freeaddrinfo(resolved); | ||||
|  | ||||
|     if (serv) { | ||||
|         lua_pushstring(L, sbuf); | ||||
|         return 2; | ||||
|     } else { | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Returns all information provided by the resolver given a host name | ||||
| * or ip address | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int inet_global_toip(lua_State *L) | ||||
| { | ||||
|     const char *address = luaL_checkstring(L, 1); | ||||
|     struct hostent *hp = NULL; | ||||
|     int err = inet_gethost(address, &hp); | ||||
|     if (err != IO_DONE) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_hoststrerror(err)); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushstring(L, inet_ntoa(*((struct in_addr *) hp->h_addr))); | ||||
|     inet_pushresolved(L, hp); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| int inet_optfamily(lua_State* L, int narg, const char* def) | ||||
| { | ||||
|     static const char* optname[] = { "unspec", "inet", "inet6", NULL }; | ||||
|     static int optvalue[] = { PF_UNSPEC, PF_INET, PF_INET6, 0 }; | ||||
|  | ||||
|     return optvalue[luaL_checkoption(L, narg, def, optname)]; | ||||
| } | ||||
|  | ||||
| int inet_optsocktype(lua_State* L, int narg, const char* def) | ||||
| { | ||||
|     static const char* optname[] = { "stream", "dgram", NULL }; | ||||
|     static int optvalue[] = { SOCK_STREAM, SOCK_DGRAM, 0 }; | ||||
|  | ||||
|     return optvalue[luaL_checkoption(L, narg, def, optname)]; | ||||
| } | ||||
|  | ||||
| static int inet_global_getaddrinfo(lua_State *L) | ||||
| { | ||||
|     const char *hostname = luaL_checkstring(L, 1); | ||||
|     struct addrinfo *iterator = NULL, *resolved = NULL; | ||||
|     struct addrinfo hints; | ||||
|     int i = 1, ret = 0; | ||||
|     memset(&hints, 0, sizeof(hints)); | ||||
|     hints.ai_socktype = SOCK_STREAM; | ||||
|     hints.ai_family = PF_UNSPEC; | ||||
|     ret = getaddrinfo(hostname, NULL, &hints, &resolved); | ||||
|     if (ret != 0) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_gaistrerror(ret)); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_newtable(L); | ||||
|     for (iterator = resolved; iterator; iterator = iterator->ai_next) { | ||||
|         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) { | ||||
|             case AF_INET: | ||||
|                 lua_pushliteral(L, "family"); | ||||
|                 lua_pushliteral(L, "inet"); | ||||
|                 lua_settable(L, -3); | ||||
|                 break; | ||||
|             case AF_INET6: | ||||
|                 lua_pushliteral(L, "family"); | ||||
|                 lua_pushliteral(L, "inet6"); | ||||
|                 lua_settable(L, -3); | ||||
|                 break; | ||||
|         } | ||||
|         lua_pushliteral(L, "addr"); | ||||
|         lua_pushstring(L, hbuf); | ||||
|         lua_settable(L, -3); | ||||
|         lua_settable(L, -3); | ||||
|         i++; | ||||
|     } | ||||
|     freeaddrinfo(resolved); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Gets the host name | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int inet_global_gethostname(lua_State *L) | ||||
| { | ||||
|     char name[257]; | ||||
|     name[256] = '\0'; | ||||
|     if (gethostname(name, 256) < 0) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_strerror(errno)); | ||||
|         return 2; | ||||
|     } else { | ||||
|         lua_pushstring(L, name); | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Lua methods | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Retrieves socket peer name | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int inet_meth_getpeername(lua_State *L, p_socket ps, int family) | ||||
| { | ||||
|     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; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Retrieves socket local name | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int inet_meth_getsockname(lua_State *L, p_socket ps, int family) | ||||
| { | ||||
|     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; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Passes all resolver information to Lua as a table | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static void inet_pushresolved(lua_State *L, struct hostent *hp) | ||||
| { | ||||
|     char **alias; | ||||
|     struct in_addr **addr; | ||||
|     int i, resolved; | ||||
|     lua_newtable(L); resolved = lua_gettop(L); | ||||
|     lua_pushstring(L, "name"); | ||||
|     lua_pushstring(L, hp->h_name); | ||||
|     lua_settable(L, resolved); | ||||
|     lua_pushstring(L, "ip"); | ||||
|     lua_pushstring(L, "alias"); | ||||
|     i = 1; | ||||
|     alias = hp->h_aliases; | ||||
|     lua_newtable(L); | ||||
|     if (alias) { | ||||
|         while (*alias) { | ||||
|             lua_pushnumber(L, i); | ||||
|             lua_pushstring(L, *alias); | ||||
|             lua_settable(L, -3); | ||||
|             i++; alias++; | ||||
|         } | ||||
|     } | ||||
|     lua_settable(L, resolved); | ||||
|     i = 1; | ||||
|     lua_newtable(L); | ||||
|     addr = (struct in_addr **) hp->h_addr_list; | ||||
|     if (addr) { | ||||
|         while (*addr) { | ||||
|             lua_pushnumber(L, i); | ||||
|             lua_pushstring(L, inet_ntoa(**addr)); | ||||
|             lua_settable(L, -3); | ||||
|             i++; addr++; | ||||
|         } | ||||
|     } | ||||
|     lua_settable(L, resolved); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Tries to create a new inet socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *inet_trycreate(p_socket ps, int family, int type) { | ||||
|     return socket_strerror(socket_create(ps, family, type, 0)); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * "Disconnects" a DGRAM socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm) | ||||
| { | ||||
|     switch (family) { | ||||
|         case PF_INET: { | ||||
|             struct sockaddr_in sin; | ||||
|             memset((char *) &sin, 0, sizeof(sin)); | ||||
|             sin.sin_family = AF_UNSPEC; | ||||
|             sin.sin_addr.s_addr = INADDR_ANY; | ||||
|             return socket_strerror(socket_connect(ps, (SA *) &sin,  | ||||
|                 sizeof(sin), tm)); | ||||
|         } | ||||
|         case PF_INET6: { | ||||
|             struct sockaddr_in6 sin6; | ||||
|             struct in6_addr addrany = IN6ADDR_ANY_INIT;  | ||||
|             memset((char *) &sin6, 0, sizeof(sin6)); | ||||
|             sin6.sin6_family = AF_UNSPEC; | ||||
|             sin6.sin6_addr = addrany; | ||||
|             return socket_strerror(socket_connect(ps, (SA *) &sin6,  | ||||
|                 sizeof(sin6), tm)); | ||||
|         } | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Tries to connect to remote address (address, port) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| 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; | ||||
|     const char *err = NULL; | ||||
|     /* try resolving */ | ||||
|     err = socket_gaistrerror(getaddrinfo(address, serv, | ||||
|                 connecthints, &resolved)); | ||||
|     if (err != NULL) { | ||||
|         if (resolved) freeaddrinfo(resolved); | ||||
|         return err; | ||||
|     } | ||||
|     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)); | ||||
|         /* if success, break out of loop */ | ||||
|         if (err == NULL) break; | ||||
|     } | ||||
|     freeaddrinfo(resolved); | ||||
|     /* here, if err is set, we failed */ | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Tries to accept a socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *inet_tryaccept(p_socket server, int family, p_socket client,  | ||||
|     p_timeout tm) | ||||
| { | ||||
| 	socklen_t len; | ||||
| 	t_sockaddr_storage addr; | ||||
| 	if (family == PF_INET6) { | ||||
| 		len = sizeof(struct sockaddr_in6); | ||||
| 	} else { | ||||
| 		len = sizeof(struct sockaddr_in); | ||||
| 	} | ||||
| 	return socket_strerror(socket_accept(server, client, (SA *) &addr,  | ||||
|         &len, tm)); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Tries to bind socket to (address, port) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *inet_trybind(p_socket ps, const char *address, const char *serv, | ||||
|         struct addrinfo *bindhints) | ||||
| { | ||||
|     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) { | ||||
|         if (resolved) freeaddrinfo(resolved); | ||||
|         return err; | ||||
|     } | ||||
|     /* iterate over resolved addresses until one is good */ | ||||
|     for (iterator = resolved; iterator; iterator = iterator->ai_next) { | ||||
|         if(sock == SOCKET_INVALID) { | ||||
|             err = socket_strerror(socket_create(&sock, iterator->ai_family, | ||||
|                         iterator->ai_socktype, iterator->ai_protocol)); | ||||
|             if(err) | ||||
|                 continue; | ||||
|         } | ||||
|         /* try binding to local address */ | ||||
|         err = socket_strerror(socket_bind(&sock, | ||||
|             (SA *) iterator->ai_addr, | ||||
|             (socklen_t) iterator->ai_addrlen)); | ||||
|  | ||||
|         /* keep trying unless bind succeeded */ | ||||
|         if (err) { | ||||
|             if(sock != *ps) | ||||
|                 socket_destroy(&sock); | ||||
|         } else { | ||||
|             /* remember what we connected to, particularly the family */ | ||||
|             *bindhints = *iterator; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     /* cleanup and return error */ | ||||
|     freeaddrinfo(resolved); | ||||
|     *ps = sock; | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Some systems do not provide these so that we provide our own.  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #ifdef LUASOCKET_INET_ATON | ||||
| int inet_aton(const char *cp, struct in_addr *inp) | ||||
| { | ||||
|     unsigned int a = 0, b = 0, c = 0, d = 0; | ||||
|     int n = 0, r; | ||||
|     unsigned long int addr = 0; | ||||
|     r = sscanf(cp, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n); | ||||
|     if (r == 0 || n == 0) return 0; | ||||
|     cp += n; | ||||
|     if (*cp) return 0; | ||||
|     if (a > 255 || b > 255 || c > 255 || d > 255) return 0; | ||||
|     if (inp) { | ||||
|         addr += a; addr <<= 8; | ||||
|         addr += b; addr <<= 8; | ||||
|         addr += c; addr <<= 8; | ||||
|         addr += d; | ||||
|         inp->s_addr = htonl(addr); | ||||
|     } | ||||
|     return 1; | ||||
| } | ||||
| #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 | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										54
									
								
								Plugins/slua_unreal/External/luasocket/inet.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								Plugins/slua_unreal/External/luasocket/inet.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| #ifndef INET_H  | ||||
| #define INET_H  | ||||
| /*=========================================================================*\ | ||||
| * Internet domain functions | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * This module implements the creation and connection of internet domain | ||||
| * sockets, on top of the socket.h interface, and the interface of with the | ||||
| * resolver.  | ||||
| * | ||||
| * The function inet_aton is provided for the platforms where it is not | ||||
| * available. The module also implements the interface of the internet | ||||
| * getpeername and getsockname functions as seen by Lua programs. | ||||
| * | ||||
| * The Lua functions toip and tohostname are also implemented here. | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
| #include "socket.h" | ||||
| #include "timeout.h" | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| #define LUASOCKET_INET_ATON | ||||
| #endif | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| int inet_open(lua_State *L); | ||||
|  | ||||
| const char *inet_trycreate(p_socket ps, int family, int type); | ||||
| 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); | ||||
| const char *inet_trydisconnect(p_socket ps, int family, p_timeout tm); | ||||
| const char *inet_tryaccept(p_socket server, int family, p_socket client, p_timeout tm); | ||||
|  | ||||
| int inet_meth_getpeername(lua_State *L, p_socket ps, int family); | ||||
| 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 LUASOCKET_INET_ATON | ||||
| int inet_aton(const char *cp, struct in_addr *inp); | ||||
| #endif | ||||
|  | ||||
| #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 | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* INET_H */ | ||||
							
								
								
									
										34
									
								
								Plugins/slua_unreal/External/luasocket/io.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Plugins/slua_unreal/External/luasocket/io.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| /*=========================================================================*\ | ||||
| * Input/Output abstraction | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include "io.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Exported functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes C structure | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx) { | ||||
|     io->send = send; | ||||
|     io->recv = recv; | ||||
|     io->error = error; | ||||
|     io->ctx = ctx; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * I/O error strings | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *io_strerror(int err) { | ||||
|     switch (err) { | ||||
|         case IO_DONE: return NULL; | ||||
|         case IO_CLOSED: return "closed"; | ||||
|         case IO_TIMEOUT: return "timeout"; | ||||
|         default: return "unknown error";  | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										69
									
								
								Plugins/slua_unreal/External/luasocket/io.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								Plugins/slua_unreal/External/luasocket/io.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| #ifndef IO_H | ||||
| #define IO_H | ||||
| /*=========================================================================*\ | ||||
| * Input/Output abstraction | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * This module defines the interface that LuaSocket expects from the | ||||
| * transport layer for streamed input/output. The idea is that if any | ||||
| * transport implements this interface, then the buffer.c functions | ||||
| * automatically work on it. | ||||
| * | ||||
| * The module socket.h implements this interface, and thus the module tcp.h | ||||
| * is very simple. | ||||
| \*=========================================================================*/ | ||||
| #include <stdio.h> | ||||
| #include "lua.h" | ||||
|  | ||||
| #include "timeout.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /* IO error codes */ | ||||
| enum { | ||||
|     IO_DONE = 0,        /* operation completed successfully */ | ||||
|     IO_TIMEOUT = -1,    /* operation timed out */ | ||||
|     IO_CLOSED = -2,     /* the connection has been closed */ | ||||
| 	IO_UNKNOWN = -3      | ||||
| }; | ||||
|  | ||||
| /* interface to error message function */ | ||||
| typedef const char *(*p_error) ( | ||||
|     void *ctx,          /* context needed by send */ | ||||
|     int err             /* error code */ | ||||
| ); | ||||
|  | ||||
| /* interface to send function */ | ||||
| typedef int (*p_send) ( | ||||
|     void *ctx,          /* context needed by send */ | ||||
|     const char *data,   /* pointer to buffer with data to send */ | ||||
|     size_t count,       /* number of bytes to send from buffer */ | ||||
|     size_t *sent,       /* number of bytes sent uppon return */ | ||||
|     p_timeout tm        /* timeout control */ | ||||
| ); | ||||
|  | ||||
| /* interface to recv function */ | ||||
| typedef int (*p_recv) ( | ||||
|     void *ctx,          /* context needed by recv */ | ||||
|     char *data,         /* pointer to buffer where data will be writen */ | ||||
|     size_t count,       /* number of bytes to receive into buffer */ | ||||
|     size_t *got,        /* number of bytes received uppon return */ | ||||
|     p_timeout tm        /* timeout control */ | ||||
| ); | ||||
|  | ||||
| /* IO driver definition */ | ||||
| typedef struct t_io_ { | ||||
|     void *ctx;          /* context needed by send/recv */ | ||||
|     p_send send;        /* send function pointer */ | ||||
|     p_recv recv;        /* receive function pointer */ | ||||
|     p_error error;      /* strerror function */ | ||||
| } t_io; | ||||
| typedef t_io *p_io; | ||||
|  | ||||
| void io_init(p_io io, p_send send, p_recv recv, p_error error, void *ctx); | ||||
| const char *io_strerror(int err); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* IO_H */ | ||||
|  | ||||
							
								
								
									
										300
									
								
								Plugins/slua_unreal/External/luasocket/ltn12.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								Plugins/slua_unreal/External/luasocket/ltn12.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,300 @@ | ||||
| R"-++**++-( | ||||
| ----------------------------------------------------------------------------- | ||||
| -- 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 | ||||
| )-++**++-"; | ||||
							
								
								
									
										130
									
								
								Plugins/slua_unreal/External/luasocket/luasocket.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								Plugins/slua_unreal/External/luasocket/luasocket.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | ||||
| /*=========================================================================*\ | ||||
| * LuaSocket toolkit | ||||
| * Networking support for the Lua language | ||||
| * Diego Nehab | ||||
| * 26/11/1999 | ||||
| * | ||||
| * This library is part of an  effort to progressively increase the network | ||||
| * connectivity  of  the Lua  language.  The  Lua interface  to  networking | ||||
| * functions follows the Sockets API  closely, trying to simplify all tasks | ||||
| * involved in setting up both  client and server connections. The provided | ||||
| * IO routines, however, follow the Lua  style, being very similar  to the | ||||
| * standard Lua read and write functions. | ||||
| \*=========================================================================*/ | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Standard include files | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * LuaSocket includes | ||||
| \*=========================================================================*/ | ||||
| #include "luasocket.h" | ||||
| #include "auxiliar.h" | ||||
| #include "except.h" | ||||
| #include "timeout.h" | ||||
| #include "buffer.h" | ||||
| #include "inet.h" | ||||
| #include "tcp.h" | ||||
| #include "udp.h" | ||||
| #include "select.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Internal function prototypes | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int global_skip(lua_State *L); | ||||
| static int global_unload(lua_State *L); | ||||
| static int base_open(lua_State *L); | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Modules and functions | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static const luaL_Reg luasocket_mod[] = { | ||||
|     {"auxiliar", auxiliar_open}, | ||||
|     {"except", except_open}, | ||||
|     {"timeout", timeout_open}, | ||||
|     {"buffer", buffer_open}, | ||||
|     {"inet", inet_open}, | ||||
|     {"tcp", tcp_open}, | ||||
|     {"udp", udp_open}, | ||||
|     {"select", select_open}, | ||||
|     {NULL, NULL} | ||||
| }; | ||||
|  | ||||
| static luaL_Reg luasocket_func[] = { | ||||
|     {"skip",      global_skip}, | ||||
|     {"__unload",  global_unload}, | ||||
|     {NULL,        NULL} | ||||
| }; | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Skip a few arguments | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int global_skip(lua_State *L) { | ||||
|     int amount = luaL_checkinteger(L, 1); | ||||
|     int ret = lua_gettop(L) - amount - 1; | ||||
|     return ret >= 0 ? ret : 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Unloads the library | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int global_unload(lua_State *L) { | ||||
|     (void) L; | ||||
|     socket_close(); | ||||
|     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, luasocket_func, 0); | ||||
| #else | ||||
|         luaL_openlib(L, "socket", luasocket_func, 0); | ||||
| #endif | ||||
| #ifdef LUASOCKET_DEBUG | ||||
|         lua_pushstring(L, "_DEBUG"); | ||||
|         lua_pushboolean(L, 1); | ||||
|         lua_rawset(L, -3); | ||||
| #endif | ||||
|         /* make version string available to scripts */ | ||||
|         lua_pushstring(L, "_VERSION"); | ||||
|         lua_pushstring(L, LUASOCKET_VERSION); | ||||
|         lua_rawset(L, -3); | ||||
|         return 1; | ||||
|     } else { | ||||
|         lua_pushstring(L, "unable to initialize library"); | ||||
|         lua_error(L); | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes all library modules. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| LUASOCKET_API int luaopen_socket_core(lua_State *L) { | ||||
|     int i; | ||||
|     base_open(L); | ||||
|     for (i = 0; luasocket_mod[i].name; i++) luasocket_mod[i].func(L); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										33
									
								
								Plugins/slua_unreal/External/luasocket/luasocket.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Plugins/slua_unreal/External/luasocket/luasocket.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| #ifndef LUASOCKET_H | ||||
| #define LUASOCKET_H | ||||
| /*=========================================================================*\ | ||||
| * LuaSocket toolkit | ||||
| * Networking support for the Lua language | ||||
| * Diego Nehab | ||||
| * 9/11/1999 | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Current socket library version | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #define LUASOCKET_VERSION    "LuaSocket 3.0-rc1" | ||||
| #define LUASOCKET_COPYRIGHT  "Copyright (C) 1999-2013 Diego Nehab" | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * This macro prefixes all exported API functions | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #ifndef LUASOCKET_API | ||||
| #define LUASOCKET_API extern | ||||
| #endif | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes the library. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| LUASOCKET_API int luaopen_socket_core(lua_State *L); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* LUASOCKET_H */ | ||||
							
								
								
									
										94
									
								
								Plugins/slua_unreal/External/luasocket/mbox.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								Plugins/slua_unreal/External/luasocket/mbox.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | ||||
| R"-++**++-( | ||||
| 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 | ||||
| )-++**++-"; | ||||
							
								
								
									
										742
									
								
								Plugins/slua_unreal/External/luasocket/mime.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										742
									
								
								Plugins/slua_unreal/External/luasocket/mime.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,742 @@ | ||||
| /*=========================================================================*\ | ||||
| * MIME support functions | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501) | ||||
| #include "compat-5.1.h" | ||||
| #endif | ||||
|  | ||||
| #include "mime.h" | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| #pragma clang diagnostic push | ||||
| #pragma clang diagnostic ignored "-Wchar-subscripts" | ||||
| #endif | ||||
|  | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Don't want to trust escape character constants | ||||
| \*=========================================================================*/ | ||||
| typedef unsigned char UC; | ||||
| static const char CRLF[] = "\r\n"; | ||||
| static const char EQCRLF[] = "=\r\n"; | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes. | ||||
| \*=========================================================================*/ | ||||
| static int mime_global_wrp(lua_State *L); | ||||
| static int mime_global_b64(lua_State *L); | ||||
| static int mime_global_unb64(lua_State *L); | ||||
| static int mime_global_qp(lua_State *L); | ||||
| static int mime_global_unqp(lua_State *L); | ||||
| static int mime_global_qpwrp(lua_State *L); | ||||
| static int mime_global_eol(lua_State *L); | ||||
| static int mime_global_dot(lua_State *L); | ||||
|  | ||||
| static size_t dot(int c, size_t state, luaL_Buffer *buffer); | ||||
| static void b64setup(UC *base); | ||||
| static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | ||||
| static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer); | ||||
| static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | ||||
|  | ||||
| static void qpsetup(UC *cl, UC *unbase); | ||||
| static void qpquote(UC c, luaL_Buffer *buffer); | ||||
| static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | ||||
| static size_t qpencode(UC c, UC *input, size_t size,  | ||||
|         const char *marker, luaL_Buffer *buffer); | ||||
| static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); | ||||
|  | ||||
| /* code support functions */ | ||||
| static luaL_Reg mine_func[] = { | ||||
|     { "dot", mime_global_dot }, | ||||
|     { "b64", mime_global_b64 }, | ||||
|     { "eol", mime_global_eol }, | ||||
|     { "qp", mime_global_qp }, | ||||
|     { "qpwrp", mime_global_qpwrp }, | ||||
|     { "unb64", mime_global_unb64 }, | ||||
|     { "unqp", mime_global_unqp }, | ||||
|     { "wrp", mime_global_wrp }, | ||||
|     { NULL, NULL } | ||||
| }; | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Quoted-printable globals | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static UC qpclass[256]; | ||||
| static UC qpbase[] = "0123456789ABCDEF"; | ||||
| static UC qpunbase[256]; | ||||
| enum {QP_PLAIN, QP_QUOTED, QP_CR, QP_IF_LAST}; | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Base64 globals | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static const UC b64base[] = | ||||
|         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | ||||
| static UC b64unbase[256]; | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Exported functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| MIME_API int luaopen_mime_core(lua_State *L) | ||||
| { | ||||
| #if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) | ||||
|     lua_newtable(L); | ||||
|     luaL_setfuncs(L, mine_func, 0); | ||||
| #else | ||||
|     luaL_openlib(L, "mime", mine_func, 0); | ||||
| #endif | ||||
|     /* make version string available to scripts */ | ||||
|     lua_pushstring(L, "_VERSION"); | ||||
|     lua_pushstring(L, MIME_VERSION); | ||||
|     lua_rawset(L, -3); | ||||
|     /* initialize lookup tables */ | ||||
|     qpsetup(qpclass, qpunbase); | ||||
|     b64setup(b64unbase); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Global Lua functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Incrementaly breaks a string into lines. The string can have CRLF breaks. | ||||
| * A, n = wrp(l, B, length) | ||||
| * A is a copy of B, broken into lines of at most 'length' bytes.  | ||||
| * 'l' is how many bytes are left for the first line of B.  | ||||
| * 'n' is the number of bytes left in the last line of A.  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int mime_global_wrp(lua_State *L) | ||||
| { | ||||
|     size_t size = 0; | ||||
|     int left = (int) luaL_checknumber(L, 1); | ||||
|     const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); | ||||
|     const UC *last = input + size; | ||||
|     int length = (int) luaL_optnumber(L, 3, 76); | ||||
|     luaL_Buffer buffer; | ||||
|     /* end of input black-hole */ | ||||
|     if (!input) { | ||||
|         /* if last line has not been terminated, add a line break */ | ||||
|         if (left < length) lua_pushstring(L, CRLF); | ||||
|         /* otherwise, we are done */ | ||||
|         else lua_pushnil(L); | ||||
|         lua_pushnumber(L, length); | ||||
|         return 2; | ||||
|     }  | ||||
|     luaL_buffinit(L, &buffer); | ||||
|     while (input < last) { | ||||
|         switch (*input) { | ||||
|             case '\r': | ||||
|                 break; | ||||
|             case '\n': | ||||
|                 luaL_addstring(&buffer, CRLF); | ||||
|                 left = length; | ||||
|                 break; | ||||
|             default: | ||||
|                 if (left <= 0) { | ||||
|                     left = length; | ||||
|                     luaL_addstring(&buffer, CRLF); | ||||
|                 } | ||||
|                 luaL_addchar(&buffer, *input); | ||||
|                 left--; | ||||
|                 break; | ||||
|         } | ||||
|         input++; | ||||
|     } | ||||
|     luaL_pushresult(&buffer); | ||||
|     lua_pushnumber(L, left); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Fill base64 decode map.  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static void b64setup(UC *unbase)  | ||||
| { | ||||
|     int i; | ||||
|     for (i = 0; i <= 255; i++) unbase[i] = (UC) 255; | ||||
|     for (i = 0; i < 64; i++) unbase[b64base[i]] = (UC) i; | ||||
|     unbase['='] = 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Acumulates bytes in input buffer until 3 bytes are available.  | ||||
| * Translate the 3 bytes into Base64 form and append to buffer. | ||||
| * Returns new number of bytes in buffer. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static size_t b64encode(UC c, UC *input, size_t size,  | ||||
|         luaL_Buffer *buffer) | ||||
| { | ||||
|     input[size++] = c; | ||||
|     if (size == 3) { | ||||
|         UC code[4]; | ||||
|         unsigned long value = 0; | ||||
|         value += input[0]; value <<= 8; | ||||
|         value += input[1]; value <<= 8; | ||||
|         value += input[2];  | ||||
|         code[3] = b64base[value & 0x3f]; value >>= 6; | ||||
|         code[2] = b64base[value & 0x3f]; value >>= 6; | ||||
|         code[1] = b64base[value & 0x3f]; value >>= 6; | ||||
|         code[0] = b64base[value]; | ||||
|         luaL_addlstring(buffer, (char *) code, 4); | ||||
|         size = 0; | ||||
|     } | ||||
|     return size; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Encodes the Base64 last 1 or 2 bytes and adds padding '='  | ||||
| * Result, if any, is appended to buffer. | ||||
| * Returns 0. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static size_t b64pad(const UC *input, size_t size,  | ||||
|         luaL_Buffer *buffer) | ||||
| { | ||||
|     unsigned long value = 0; | ||||
|     UC code[4] = {'=', '=', '=', '='}; | ||||
|     switch (size) { | ||||
|         case 1: | ||||
|             value = input[0] << 4; | ||||
|             code[1] = b64base[value & 0x3f]; value >>= 6; | ||||
|             code[0] = b64base[value]; | ||||
|             luaL_addlstring(buffer, (char *) code, 4); | ||||
|             break; | ||||
|         case 2: | ||||
|             value = input[0]; value <<= 8;  | ||||
|             value |= input[1]; value <<= 2; | ||||
|             code[2] = b64base[value & 0x3f]; value >>= 6; | ||||
|             code[1] = b64base[value & 0x3f]; value >>= 6; | ||||
|             code[0] = b64base[value]; | ||||
|             luaL_addlstring(buffer, (char *) code, 4); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Acumulates bytes in input buffer until 4 bytes are available.  | ||||
| * Translate the 4 bytes from Base64 form and append to buffer. | ||||
| * Returns new number of bytes in buffer. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static size_t b64decode(UC c, UC *input, size_t size,  | ||||
|         luaL_Buffer *buffer) | ||||
| { | ||||
|     /* ignore invalid characters */ | ||||
|     if (b64unbase[c] > 64) return size; | ||||
|     input[size++] = c; | ||||
|     /* decode atom */ | ||||
|     if (size == 4) { | ||||
|         UC decoded[3]; | ||||
|         int valid, value = 0; | ||||
|         value =  b64unbase[input[0]]; value <<= 6; | ||||
|         value |= b64unbase[input[1]]; value <<= 6; | ||||
|         value |= b64unbase[input[2]]; value <<= 6; | ||||
|         value |= b64unbase[input[3]]; | ||||
|         decoded[2] = (UC) (value & 0xff); value >>= 8; | ||||
|         decoded[1] = (UC) (value & 0xff); value >>= 8; | ||||
|         decoded[0] = (UC) value; | ||||
|         /* take care of paddding */ | ||||
|         valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3;  | ||||
|         luaL_addlstring(buffer, (char *) decoded, valid); | ||||
|         return 0; | ||||
|     /* need more data */ | ||||
|     } else return size; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Incrementally applies the Base64 transfer content encoding to a string | ||||
| * A, B = b64(C, D) | ||||
| * A is the encoded version of the largest prefix of C .. D that is | ||||
| * divisible by 3. B has the remaining bytes of C .. D, *without* encoding. | ||||
| * The easiest thing would be to concatenate the two strings and  | ||||
| * encode the result, but we can't afford that or Lua would dupplicate | ||||
| * every chunk we received. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int mime_global_b64(lua_State *L) | ||||
| { | ||||
|     UC atom[3]; | ||||
|     size_t isize = 0, asize = 0; | ||||
|     const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); | ||||
|     const UC *last = input + isize; | ||||
|     luaL_Buffer buffer; | ||||
|     /* end-of-input blackhole */ | ||||
|     if (!input) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|         return 2; | ||||
|     } | ||||
|     /* make sure we don't confuse buffer stuff with arguments */ | ||||
|     lua_settop(L, 2); | ||||
|     /* process first part of the input */ | ||||
|     luaL_buffinit(L, &buffer); | ||||
|     while (input < last)  | ||||
|         asize = b64encode(*input++, atom, asize, &buffer); | ||||
|     input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | ||||
|     /* if second part is nil, we are done */ | ||||
|     if (!input) { | ||||
|         size_t osize = 0; | ||||
|         asize = b64pad(atom, asize, &buffer); | ||||
|         luaL_pushresult(&buffer); | ||||
|         /* if the output is empty  and the input is nil, return nil */ | ||||
|         lua_tolstring(L, -1, &osize); | ||||
|         if (osize == 0) lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|         return 2; | ||||
|     } | ||||
|     /* otherwise process the second part */ | ||||
|     last = input + isize; | ||||
|     while (input < last)  | ||||
|         asize = b64encode(*input++, atom, asize, &buffer); | ||||
|     luaL_pushresult(&buffer); | ||||
|     lua_pushlstring(L, (char *) atom, asize); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Incrementally removes the Base64 transfer content encoding from a string | ||||
| * A, B = b64(C, D) | ||||
| * A is the encoded version of the largest prefix of C .. D that is | ||||
| * divisible by 4. B has the remaining bytes of C .. D, *without* encoding. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int mime_global_unb64(lua_State *L) | ||||
| { | ||||
|     UC atom[4]; | ||||
|     size_t isize = 0, asize = 0; | ||||
|     const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); | ||||
|     const UC *last = input + isize; | ||||
|     luaL_Buffer buffer; | ||||
|     /* end-of-input blackhole */ | ||||
|     if (!input) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|         return 2; | ||||
|     } | ||||
|     /* make sure we don't confuse buffer stuff with arguments */ | ||||
|     lua_settop(L, 2); | ||||
|     /* process first part of the input */ | ||||
|     luaL_buffinit(L, &buffer); | ||||
|     while (input < last)  | ||||
|         asize = b64decode(*input++, atom, asize, &buffer); | ||||
|     input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | ||||
|     /* if second is nil, we are done */ | ||||
|     if (!input) { | ||||
|         size_t osize = 0; | ||||
|         luaL_pushresult(&buffer); | ||||
|         /* if the output is empty  and the input is nil, return nil */ | ||||
|         lua_tolstring(L, -1, &osize); | ||||
|         if (osize == 0) lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|         return 2; | ||||
|     } | ||||
|     /* otherwise, process the rest of the input */ | ||||
|     last = input + isize; | ||||
|     while (input < last)  | ||||
|         asize = b64decode(*input++, atom, asize, &buffer); | ||||
|     luaL_pushresult(&buffer); | ||||
|     lua_pushlstring(L, (char *) atom, asize); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Quoted-printable encoding scheme | ||||
| * all (except CRLF in text) can be =XX | ||||
| * CLRL in not text must be =XX=XX | ||||
| * 33 through 60 inclusive can be plain | ||||
| * 62 through 126 inclusive can be plain | ||||
| * 9 and 32 can be plain, unless in the end of a line, where must be =XX | ||||
| * encoded lines must be no longer than 76 not counting CRLF | ||||
| * soft line-break are =CRLF | ||||
| * To encode one byte, we need to see the next two.  | ||||
| * Worst case is when we see a space, and wonder if a CRLF is comming | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Split quoted-printable characters into classes | ||||
| * Precompute reverse map for encoding | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static void qpsetup(UC *cl, UC *unbase) | ||||
| { | ||||
|     int i; | ||||
|     for (i = 0; i < 256; i++) cl[i] = QP_QUOTED; | ||||
|     for (i = 33; i <= 60; i++) cl[i] = QP_PLAIN; | ||||
|     for (i = 62; i <= 126; i++) cl[i] = QP_PLAIN; | ||||
|     cl['\t'] = QP_IF_LAST;  | ||||
|     cl[' '] = QP_IF_LAST; | ||||
|     cl['\r'] = QP_CR; | ||||
|     for (i = 0; i < 256; i++) unbase[i] = 255; | ||||
|     unbase['0'] = 0; unbase['1'] = 1; unbase['2'] = 2; | ||||
|     unbase['3'] = 3; unbase['4'] = 4; unbase['5'] = 5; | ||||
|     unbase['6'] = 6; unbase['7'] = 7; unbase['8'] = 8; | ||||
|     unbase['9'] = 9; unbase['A'] = 10; unbase['a'] = 10; | ||||
|     unbase['B'] = 11; unbase['b'] = 11; unbase['C'] = 12; | ||||
|     unbase['c'] = 12; unbase['D'] = 13; unbase['d'] = 13; | ||||
|     unbase['E'] = 14; unbase['e'] = 14; unbase['F'] = 15; | ||||
|     unbase['f'] = 15; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Output one character in form =XX | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static void qpquote(UC c, luaL_Buffer *buffer) | ||||
| { | ||||
|     luaL_addchar(buffer, '='); | ||||
|     luaL_addchar(buffer, qpbase[c >> 4]); | ||||
|     luaL_addchar(buffer, qpbase[c & 0x0F]); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Accumulate characters until we are sure about how to deal with them. | ||||
| * Once we are sure, output to the buffer, in the correct form.  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static size_t qpencode(UC c, UC *input, size_t size,  | ||||
|         const char *marker, luaL_Buffer *buffer) | ||||
| { | ||||
|     input[size++] = c; | ||||
|     /* deal with all characters we can have */ | ||||
|     while (size > 0) { | ||||
|         switch (qpclass[input[0]]) { | ||||
|             /* might be the CR of a CRLF sequence */ | ||||
|             case QP_CR: | ||||
|                 if (size < 2) return size; | ||||
|                 if (input[1] == '\n') { | ||||
|                     luaL_addstring(buffer, marker); | ||||
|                     return 0; | ||||
|                 } else qpquote(input[0], buffer); | ||||
|                 break; | ||||
|             /* might be a space and that has to be quoted if last in line */ | ||||
|             case QP_IF_LAST: | ||||
|                 if (size < 3) return size; | ||||
|                 /* if it is the last, quote it and we are done */ | ||||
|                 if (input[1] == '\r' && input[2] == '\n') { | ||||
|                     qpquote(input[0], buffer); | ||||
|                     luaL_addstring(buffer, marker); | ||||
|                     return 0; | ||||
|                 } else luaL_addchar(buffer, input[0]); | ||||
|                 break; | ||||
|                 /* might have to be quoted always */ | ||||
|             case QP_QUOTED: | ||||
|                 qpquote(input[0], buffer); | ||||
|                 break; | ||||
|                 /* might never have to be quoted */ | ||||
|             default: | ||||
|                 luaL_addchar(buffer, input[0]); | ||||
|                 break; | ||||
|         } | ||||
|         input[0] = input[1]; input[1] = input[2]; | ||||
|         size--; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Deal with the final characters  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) | ||||
| { | ||||
|     size_t i; | ||||
|     for (i = 0; i < size; i++) { | ||||
|         if (qpclass[input[i]] == QP_PLAIN) luaL_addchar(buffer, input[i]); | ||||
|         else qpquote(input[i], buffer); | ||||
|     } | ||||
|     if (size > 0) luaL_addstring(buffer, EQCRLF); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Incrementally converts a string to quoted-printable | ||||
| * A, B = qp(C, D, marker) | ||||
| * Marker is the text to be used to replace CRLF sequences found in A. | ||||
| * A is the encoded version of the largest prefix of C .. D that  | ||||
| * can be encoded without doubts.  | ||||
| * B has the remaining bytes of C .. D, *without* encoding. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int mime_global_qp(lua_State *L) | ||||
| { | ||||
|  | ||||
|     size_t asize = 0, isize = 0; | ||||
|     UC atom[3]; | ||||
|     const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); | ||||
|     const UC *last = input + isize; | ||||
|     const char *marker = luaL_optstring(L, 3, CRLF); | ||||
|     luaL_Buffer buffer; | ||||
|     /* end-of-input blackhole */ | ||||
|     if (!input) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|         return 2; | ||||
|     } | ||||
|     /* make sure we don't confuse buffer stuff with arguments */ | ||||
|     lua_settop(L, 3); | ||||
|     /* process first part of input */ | ||||
|     luaL_buffinit(L, &buffer); | ||||
|     while (input < last) | ||||
|         asize = qpencode(*input++, atom, asize, marker, &buffer); | ||||
|     input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | ||||
|     /* if second part is nil, we are done */ | ||||
|     if (!input) { | ||||
|         asize = qppad(atom, asize, &buffer); | ||||
|         luaL_pushresult(&buffer); | ||||
|         if (!(*lua_tostring(L, -1))) lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|         return 2; | ||||
|     } | ||||
|     /* otherwise process rest of input */ | ||||
|     last = input + isize; | ||||
|     while (input < last) | ||||
|         asize = qpencode(*input++, atom, asize, marker, &buffer); | ||||
|     luaL_pushresult(&buffer); | ||||
|     lua_pushlstring(L, (char *) atom, asize); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Accumulate characters until we are sure about how to deal with them. | ||||
| * Once we are sure, output the to the buffer, in the correct form.  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer) { | ||||
|     int d; | ||||
|     input[size++] = c; | ||||
|     /* deal with all characters we can deal */ | ||||
|     switch (input[0]) { | ||||
|         /* if we have an escape character */ | ||||
|         case '=':  | ||||
|             if (size < 3) return size;  | ||||
|             /* eliminate soft line break */ | ||||
|             if (input[1] == '\r' && input[2] == '\n') return 0; | ||||
|             /* decode quoted representation */ | ||||
|             c = qpunbase[input[1]]; d = qpunbase[input[2]]; | ||||
|             /* if it is an invalid, do not decode */ | ||||
|             if (c > 15 || d > 15) luaL_addlstring(buffer, (char *)input, 3); | ||||
|             else luaL_addchar(buffer, (char) ((c << 4) + d)); | ||||
|             return 0; | ||||
|         case '\r': | ||||
|             if (size < 2) return size;  | ||||
|             if (input[1] == '\n') luaL_addlstring(buffer, (char *)input, 2); | ||||
|             return 0; | ||||
|         default: | ||||
|             if (input[0] == '\t' || (input[0] > 31 && input[0] < 127)) | ||||
|                 luaL_addchar(buffer, input[0]); | ||||
|             return 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Incrementally decodes a string in quoted-printable | ||||
| * A, B = qp(C, D) | ||||
| * A is the decoded version of the largest prefix of C .. D that  | ||||
| * can be decoded without doubts.  | ||||
| * B has the remaining bytes of C .. D, *without* decoding. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int mime_global_unqp(lua_State *L) | ||||
| { | ||||
|     size_t asize = 0, isize = 0; | ||||
|     UC atom[3]; | ||||
|     const UC *input = (UC *) luaL_optlstring(L, 1, NULL, &isize); | ||||
|     const UC *last = input + isize; | ||||
|     luaL_Buffer buffer; | ||||
|     /* end-of-input blackhole */ | ||||
|     if (!input) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|         return 2; | ||||
|     } | ||||
|     /* make sure we don't confuse buffer stuff with arguments */ | ||||
|     lua_settop(L, 2); | ||||
|     /* process first part of input */ | ||||
|     luaL_buffinit(L, &buffer); | ||||
|     while (input < last) | ||||
|         asize = qpdecode(*input++, atom, asize, &buffer); | ||||
|     input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | ||||
|     /* if second part is nil, we are done */ | ||||
|     if (!input) { | ||||
|         luaL_pushresult(&buffer); | ||||
|         if (!(*lua_tostring(L, -1))) lua_pushnil(L); | ||||
|         lua_pushnil(L); | ||||
|         return 2; | ||||
|     }  | ||||
|     /* otherwise process rest of input */ | ||||
|     last = input + isize; | ||||
|     while (input < last) | ||||
|         asize = qpdecode(*input++, atom, asize, &buffer); | ||||
|     luaL_pushresult(&buffer); | ||||
|     lua_pushlstring(L, (char *) atom, asize); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Incrementally breaks a quoted-printed string into lines | ||||
| * A, n = qpwrp(l, B, length) | ||||
| * A is a copy of B, broken into lines of at most 'length' bytes.  | ||||
| * 'l' is how many bytes are left for the first line of B.  | ||||
| * 'n' is the number of bytes left in the last line of A.  | ||||
| * There are two complications: lines can't be broken in the middle | ||||
| * of an encoded =XX, and there might be line breaks already | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int mime_global_qpwrp(lua_State *L) | ||||
| { | ||||
|     size_t size = 0; | ||||
|     int left = (int) luaL_checknumber(L, 1); | ||||
|     const UC *input = (UC *) luaL_optlstring(L, 2, NULL, &size); | ||||
|     const UC *last = input + size; | ||||
|     int length = (int) luaL_optnumber(L, 3, 76); | ||||
|     luaL_Buffer buffer; | ||||
|     /* end-of-input blackhole */ | ||||
|     if (!input) { | ||||
|         if (left < length) lua_pushstring(L, EQCRLF); | ||||
|         else lua_pushnil(L); | ||||
|         lua_pushnumber(L, length); | ||||
|         return 2; | ||||
|     } | ||||
|     /* process all input */ | ||||
|     luaL_buffinit(L, &buffer); | ||||
|     while (input < last) { | ||||
|         switch (*input) { | ||||
|             case '\r': | ||||
|                 break; | ||||
|             case '\n': | ||||
|                 left = length; | ||||
|                 luaL_addstring(&buffer, CRLF); | ||||
|                 break; | ||||
|             case '=': | ||||
|                 if (left <= 3) { | ||||
|                     left = length; | ||||
|                     luaL_addstring(&buffer, EQCRLF); | ||||
|                 }  | ||||
|                 luaL_addchar(&buffer, *input); | ||||
|                 left--; | ||||
|                 break; | ||||
|             default:  | ||||
|                 if (left <= 1) { | ||||
|                     left = length; | ||||
|                     luaL_addstring(&buffer, EQCRLF); | ||||
|                 } | ||||
|                 luaL_addchar(&buffer, *input); | ||||
|                 left--; | ||||
|                 break; | ||||
|         } | ||||
|         input++; | ||||
|     } | ||||
|     luaL_pushresult(&buffer); | ||||
|     lua_pushnumber(L, left); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Here is what we do: \n, and \r are considered candidates for line | ||||
| * break. We issue *one* new line marker if any of them is seen alone, or | ||||
| * followed by a different one. That is, \n\n and \r\r will issue two | ||||
| * end of line markers each, but \r\n, \n\r etc will only issue *one* | ||||
| * marker.  This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as | ||||
| * probably other more obscure conventions. | ||||
| * | ||||
| * c is the current character being processed | ||||
| * last is the previous character | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #define eolcandidate(c) (c == '\r' || c == '\n') | ||||
| static int eolprocess(int c, int last, const char *marker,  | ||||
|         luaL_Buffer *buffer) | ||||
| { | ||||
|     if (eolcandidate(c)) { | ||||
|         if (eolcandidate(last)) { | ||||
|             if (c == last) luaL_addstring(buffer, marker); | ||||
|             return 0; | ||||
|         } else { | ||||
|             luaL_addstring(buffer, marker); | ||||
|             return c; | ||||
|         } | ||||
|     } else { | ||||
|         luaL_addchar(buffer, (char) c); | ||||
|         return 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Converts a string to uniform EOL convention.  | ||||
| * A, n = eol(o, B, marker) | ||||
| * A is the converted version of the largest prefix of B that can be | ||||
| * converted unambiguously. 'o' is the context returned by the previous  | ||||
| * call. 'n' is the new context. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int mime_global_eol(lua_State *L) | ||||
| { | ||||
|     int ctx = luaL_checkinteger(L, 1); | ||||
|     size_t isize = 0; | ||||
|     const char *input = luaL_optlstring(L, 2, NULL, &isize); | ||||
|     const char *last = input + isize; | ||||
|     const char *marker = luaL_optstring(L, 3, CRLF); | ||||
|     luaL_Buffer buffer; | ||||
|     luaL_buffinit(L, &buffer); | ||||
|     /* end of input blackhole */ | ||||
|     if (!input) { | ||||
|        lua_pushnil(L); | ||||
|        lua_pushnumber(L, 0); | ||||
|        return 2; | ||||
|     } | ||||
|     /* process all input */ | ||||
|     while (input < last) | ||||
|         ctx = eolprocess(*input++, ctx, marker, &buffer); | ||||
|     luaL_pushresult(&buffer); | ||||
|     lua_pushnumber(L, ctx); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Takes one byte and stuff it if needed.  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static size_t dot(int c, size_t state, luaL_Buffer *buffer) | ||||
| { | ||||
|     luaL_addchar(buffer, (char) c); | ||||
|     switch (c) { | ||||
|         case '\r':  | ||||
|             return 1; | ||||
|         case '\n':  | ||||
|             return (state == 1)? 2: 0;  | ||||
|         case '.':   | ||||
|             if (state == 2)  | ||||
|                 luaL_addchar(buffer, '.'); | ||||
|         default: | ||||
|             return 0; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Incrementally applies smtp stuffing to a string | ||||
| * A, n = dot(l, D) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int mime_global_dot(lua_State *L) | ||||
| { | ||||
|     size_t isize = 0, state = (size_t) luaL_checknumber(L, 1); | ||||
|     const char *input = luaL_optlstring(L, 2, NULL, &isize); | ||||
|     const char *last = input + isize; | ||||
|     luaL_Buffer buffer; | ||||
|     /* end-of-input blackhole */ | ||||
|     if (!input) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushnumber(L, 2); | ||||
|         return 2; | ||||
|     } | ||||
|     /* process all input */ | ||||
|     luaL_buffinit(L, &buffer); | ||||
|     while (input < last)  | ||||
|         state = dot(*input++, state, &buffer); | ||||
|     luaL_pushresult(&buffer); | ||||
|     lua_pushnumber(L, (lua_Number) state); | ||||
|     return 2; | ||||
| } | ||||
|  | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| #pragma clang diagnostic pop | ||||
| #endif | ||||
							
								
								
									
										33
									
								
								Plugins/slua_unreal/External/luasocket/mime.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Plugins/slua_unreal/External/luasocket/mime.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| #ifndef MIME_H  | ||||
| #define MIME_H  | ||||
| /*=========================================================================*\ | ||||
| * Core MIME support | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * This module provides functions to implement transfer content encodings | ||||
| * and formatting conforming to RFC 2045. It is used by mime.lua, which | ||||
| * provide a higher level interface to this functionality.  | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Current MIME library version | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #define MIME_VERSION    "MIME 1.0.3" | ||||
| #define MIME_COPYRIGHT  "Copyright (C) 2004-2013 Diego Nehab" | ||||
| #define MIME_AUTHORS    "Diego Nehab" | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * This macro prefixes all exported API functions | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #ifndef MIME_API | ||||
| #define MIME_API extern | ||||
| #endif | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| MIME_API int luaopen_mime_core(lua_State *L); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* MIME_H */ | ||||
							
								
								
									
										92
									
								
								Plugins/slua_unreal/External/luasocket/mime.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								Plugins/slua_unreal/External/luasocket/mime.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,92 @@ | ||||
| R"-++**++-( | ||||
| ------------------------------------------------------------------- | ||||
| -- 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 | ||||
| )-++**++-"; | ||||
							
								
								
									
										367
									
								
								Plugins/slua_unreal/External/luasocket/options.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										367
									
								
								Plugins/slua_unreal/External/luasocket/options.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,367 @@ | ||||
| /*=========================================================================*\ | ||||
| * Common option interface  | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <string.h>  | ||||
|  | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "auxiliar.h" | ||||
| #include "options.h" | ||||
| #include "inet.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * 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,  | ||||
|         void *val, int* len); | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Exported functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Calls appropriate option handler | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps) | ||||
| { | ||||
|     const char *name = luaL_checkstring(L, 2);      /* obj, name, ... */ | ||||
|     while (opt->name && strcmp(name, opt->name)) | ||||
|         opt++; | ||||
|     if (!opt->func) { | ||||
|         char msg[45]; | ||||
|         sprintf(msg, "unsupported option `%.35s'", name); | ||||
|         luaL_argerror(L, 2, msg); | ||||
|     } | ||||
|     return opt->func(L, ps); | ||||
| } | ||||
|  | ||||
| int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps) | ||||
| { | ||||
|     const char *name = luaL_checkstring(L, 2);      /* obj, name, ... */ | ||||
|     while (opt->name && strcmp(name, opt->name)) | ||||
|         opt++; | ||||
|     if (!opt->func) { | ||||
|         char msg[45]; | ||||
|         sprintf(msg, "unsupported option `%.35s'", name); | ||||
|         luaL_argerror(L, 2, msg); | ||||
|     } | ||||
|     return opt->func(L, ps); | ||||
| } | ||||
|  | ||||
| /* enables reuse of local address */ | ||||
| int opt_set_reuseaddr(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);  | ||||
| } | ||||
|  | ||||
| int opt_get_reuseaddr(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEADDR);  | ||||
| } | ||||
|  | ||||
| /* enables reuse of local port */ | ||||
| int opt_set_reuseport(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEPORT);  | ||||
| } | ||||
|  | ||||
| int opt_get_reuseport(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_getboolean(L, ps, SOL_SOCKET, SO_REUSEPORT);  | ||||
| } | ||||
|  | ||||
| /* disables the Naggle algorithm */ | ||||
| int opt_set_tcp_nodelay(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY);  | ||||
| } | ||||
|  | ||||
| int opt_get_tcp_nodelay(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_getboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); | ||||
| } | ||||
|  | ||||
| int opt_set_keepalive(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);  | ||||
| } | ||||
|  | ||||
| int opt_get_keepalive(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_getboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE);  | ||||
| } | ||||
|  | ||||
| int opt_set_dontroute(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); | ||||
| } | ||||
|  | ||||
| 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); | ||||
| } | ||||
|  | ||||
| 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 */ | ||||
|     if (!lua_istable(L, 3)) auxiliar_typeerror(L,3,lua_typename(L, LUA_TTABLE)); | ||||
|     lua_pushstring(L, "on"); | ||||
|     lua_gettable(L, 3); | ||||
|     if (!lua_isboolean(L, -1))  | ||||
|         luaL_argerror(L, 3, "boolean 'on' field expected"); | ||||
|     li.l_onoff = (u_short) lua_toboolean(L, -1); | ||||
|     lua_pushstring(L, "timeout"); | ||||
|     lua_gettable(L, 3); | ||||
|     if (!lua_isnumber(L, -1))  | ||||
|         luaL_argerror(L, 3, "number 'timeout' field expected"); | ||||
|     li.l_linger = (u_short) lua_tonumber(L, -1); | ||||
|     return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li)); | ||||
| } | ||||
|  | ||||
| int opt_get_linger(lua_State *L, p_socket ps) | ||||
| { | ||||
|     struct linger li;                      /* obj, name */ | ||||
|     int len = sizeof(li); | ||||
|     int err = opt_get(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, &len); | ||||
|     if (err) | ||||
|         return err; | ||||
|     lua_newtable(L); | ||||
|     lua_pushboolean(L, li.l_onoff); | ||||
|     lua_setfield(L, -2, "on"); | ||||
|     lua_pushinteger(L, li.l_linger); | ||||
|     lua_setfield(L, -2, "timeout"); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_setint(L, ps, IPPROTO_IP, IP_MULTICAST_TTL); | ||||
| } | ||||
|  | ||||
| int opt_set_ip_multicast_if(lua_State *L, p_socket ps) | ||||
| { | ||||
|     const char *address = luaL_checkstring(L, 3);    /* obj, name, ip */ | ||||
|     struct in_addr val; | ||||
|     val.s_addr = htonl(INADDR_ANY); | ||||
|     if (strcmp(address, "*") && !inet_aton(address, &val)) | ||||
|         luaL_argerror(L, 3, "ip expected"); | ||||
|     return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_IF,  | ||||
|         (char *) &val, sizeof(val)); | ||||
| } | ||||
|  | ||||
| int opt_get_ip_multicast_if(lua_State *L, p_socket ps) | ||||
| { | ||||
|     struct in_addr val; | ||||
|     socklen_t len = sizeof(val); | ||||
|     if (getsockopt(*ps, IPPROTO_IP, IP_MULTICAST_IF, (char *) &val, &len) < 0) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, "getsockopt failed"); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushstring(L, inet_ntoa(val)); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| int opt_set_ip_add_membership(lua_State *L, p_socket ps) | ||||
| { | ||||
|     return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); | ||||
| } | ||||
|  | ||||
| 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); | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Auxiliar functions | ||||
| \*=========================================================================*/ | ||||
| static int opt_setmembership(lua_State *L, p_socket ps, int level, int name) | ||||
| { | ||||
|     struct ip_mreq val;                   /* obj, name, table */ | ||||
|     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_aton(lua_tostring(L, -1), &val.imr_multiaddr))  | ||||
|         luaL_argerror(L, 3, "invalid 'multiaddr' ip address"); | ||||
|     lua_pushstring(L, "interface"); | ||||
|     lua_gettable(L, 3); | ||||
|     if (!lua_isstring(L, -1))  | ||||
|         luaL_argerror(L, 3, "string 'interface' field expected"); | ||||
|     val.imr_interface.s_addr = htonl(INADDR_ANY); | ||||
|     if (strcmp(lua_tostring(L, -1), "*") && | ||||
|             !inet_aton(lua_tostring(L, -1), &val.imr_interface))  | ||||
|         luaL_argerror(L, 3, "invalid 'interface' ip address"); | ||||
|     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) | ||||
| { | ||||
|     socklen_t socklen = *len; | ||||
|     if (getsockopt(*ps, level, name, (char *) val, &socklen) < 0) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, "getsockopt failed"); | ||||
|         return 2; | ||||
|     } | ||||
|     *len = socklen; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static  | ||||
| int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len) | ||||
| { | ||||
|     if (setsockopt(*ps, level, name, (char *) val, len) < 0) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, "setsockopt failed"); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| static int opt_getboolean(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_pushboolean(L, val); | ||||
|     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)); | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										64
									
								
								Plugins/slua_unreal/External/luasocket/options.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Plugins/slua_unreal/External/luasocket/options.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| #ifndef OPTIONS_H | ||||
| #define OPTIONS_H | ||||
| /*=========================================================================*\ | ||||
| * Common option interface  | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * This module provides a common interface to socket options, used mainly by | ||||
| * modules UDP and TCP.  | ||||
| \*=========================================================================*/ | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "socket.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /* option registry */ | ||||
| typedef struct t_opt { | ||||
|   const char *name; | ||||
|   int (*func)(lua_State *L, p_socket ps); | ||||
| } t_opt; | ||||
| typedef t_opt *p_opt; | ||||
|  | ||||
| /* supported options for setoption */ | ||||
| int opt_set_dontroute(lua_State *L, p_socket ps); | ||||
| int opt_set_broadcast(lua_State *L, p_socket ps); | ||||
| int opt_set_reuseaddr(lua_State *L, p_socket ps); | ||||
| int opt_set_tcp_nodelay(lua_State *L, p_socket ps); | ||||
| int opt_set_keepalive(lua_State *L, p_socket ps); | ||||
| int opt_set_linger(lua_State *L, p_socket ps); | ||||
| int opt_set_reuseaddr(lua_State *L, p_socket ps); | ||||
| int opt_set_reuseport(lua_State *L, p_socket ps); | ||||
| int opt_set_ip_multicast_if(lua_State *L, p_socket ps); | ||||
| 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 */ | ||||
| int opt_get_reuseaddr(lua_State *L, p_socket ps); | ||||
| int opt_get_tcp_nodelay(lua_State *L, p_socket ps); | ||||
| int opt_get_keepalive(lua_State *L, p_socket ps); | ||||
| 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); | ||||
| int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										224
									
								
								Plugins/slua_unreal/External/luasocket/select.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										224
									
								
								Plugins/slua_unreal/External/luasocket/select.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,224 @@ | ||||
| /*=========================================================================*\ | ||||
| * Select implementation | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "socket.h" | ||||
| #include "timeout.h" | ||||
| #include "select.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes. | ||||
| \*=========================================================================*/ | ||||
| static t_socket getfd(lua_State *L); | ||||
| static int dirty(lua_State *L); | ||||
| static void collect_fd(lua_State *L, int tab, int itab,  | ||||
|         fd_set *set, t_socket *max_fd); | ||||
| static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set); | ||||
| static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,  | ||||
|         int itab, int tab, int start); | ||||
| static void make_assoc(lua_State *L, int tab); | ||||
| static int global_select(lua_State *L); | ||||
|  | ||||
| /* functions in library namespace */ | ||||
| static luaL_Reg select_func[] = { | ||||
|     {"select", global_select}, | ||||
|     {NULL,     NULL} | ||||
| }; | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Exported functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| 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, select_func, 0); | ||||
| #else | ||||
|     luaL_openlib(L, NULL, select_func, 0); | ||||
| #endif | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Global Lua functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Waits for a set of sockets until a condition is met or timeout. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int global_select(lua_State *L) { | ||||
|     int rtab, wtab, itab, ret, ndirty; | ||||
|     t_socket max_fd = SOCKET_INVALID; | ||||
|     fd_set rset, wset; | ||||
|     t_timeout tm; | ||||
|     double t = luaL_optnumber(L, 3, -1); | ||||
|     FD_ZERO(&rset); FD_ZERO(&wset); | ||||
|     lua_settop(L, 3); | ||||
|     lua_newtable(L); itab = lua_gettop(L); | ||||
|     lua_newtable(L); rtab = lua_gettop(L); | ||||
|     lua_newtable(L); wtab = lua_gettop(L); | ||||
|     collect_fd(L, 1, itab, &rset, &max_fd); | ||||
|     collect_fd(L, 2, itab, &wset, &max_fd); | ||||
|     ndirty = check_dirty(L, 1, rtab, &rset); | ||||
|     t = ndirty > 0? 0.0: t; | ||||
|     timeout_init(&tm, t, -1); | ||||
|     timeout_markstart(&tm); | ||||
|     ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm); | ||||
|     if (ret > 0 || ndirty > 0) { | ||||
|         return_fd(L, &rset, max_fd+1, itab, rtab, ndirty); | ||||
|         return_fd(L, &wset, max_fd+1, itab, wtab, 0); | ||||
|         make_assoc(L, rtab); | ||||
|         make_assoc(L, wtab); | ||||
|         return 2; | ||||
|     } else if (ret == 0) { | ||||
|         lua_pushstring(L, "timeout"); | ||||
|         return 3; | ||||
|     } else { | ||||
|         luaL_error(L, "select failed"); | ||||
|         return 3; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal functions | ||||
| \*=========================================================================*/ | ||||
| static t_socket getfd(lua_State *L) { | ||||
|     t_socket fd = SOCKET_INVALID; | ||||
|     lua_pushstring(L, "getfd"); | ||||
|     lua_gettable(L, -2); | ||||
|     if (!lua_isnil(L, -1)) { | ||||
|         lua_pushvalue(L, -2); | ||||
|         lua_call(L, 1, 1); | ||||
|         if (lua_isnumber(L, -1)) { | ||||
|             double numfd = lua_tonumber(L, -1);  | ||||
|             fd = (numfd >= 0.0)? (t_socket) numfd: SOCKET_INVALID; | ||||
|         } | ||||
|     }  | ||||
|     lua_pop(L, 1); | ||||
|     return fd; | ||||
| } | ||||
|  | ||||
| static int dirty(lua_State *L) { | ||||
|     int is = 0; | ||||
|     lua_pushstring(L, "dirty"); | ||||
|     lua_gettable(L, -2); | ||||
|     if (!lua_isnil(L, -1)) { | ||||
|         lua_pushvalue(L, -2); | ||||
|         lua_call(L, 1, 1); | ||||
|         is = lua_toboolean(L, -1); | ||||
|     }  | ||||
|     lua_pop(L, 1); | ||||
|     return is; | ||||
| } | ||||
|  | ||||
| static void collect_fd(lua_State *L, int tab, int itab,  | ||||
|         fd_set *set, t_socket *max_fd) { | ||||
|     int i = 1, n = 0; | ||||
|     /* nil is the same as an empty table */ | ||||
|     if (lua_isnil(L, tab)) return; | ||||
|     /* otherwise we need it to be a table */ | ||||
|     luaL_checktype(L, tab, LUA_TTABLE); | ||||
|     for ( ;; ) { | ||||
|         t_socket fd; | ||||
|         lua_pushnumber(L, i); | ||||
|         lua_gettable(L, tab); | ||||
|         if (lua_isnil(L, -1)) { | ||||
|             lua_pop(L, 1); | ||||
|             break; | ||||
|         } | ||||
|         /* getfd figures out if this is a socket */ | ||||
|         fd = getfd(L); | ||||
|         if (fd != SOCKET_INVALID) { | ||||
|             /* make sure we don't overflow the fd_set */ | ||||
| #ifdef _WIN32 | ||||
|             if (n >= FD_SETSIZE)  | ||||
|                 luaL_argerror(L, tab, "too many sockets"); | ||||
| #else | ||||
|             if (fd >= FD_SETSIZE)  | ||||
|                 luaL_argerror(L, tab, "descriptor too large for set size"); | ||||
| #endif | ||||
|             FD_SET(fd, set); | ||||
|             n++; | ||||
|             /* keep track of the largest descriptor so far */ | ||||
|             if (*max_fd == SOCKET_INVALID || *max_fd < fd)  | ||||
|                 *max_fd = fd; | ||||
|             /* make sure we can map back from descriptor to the object */ | ||||
|             lua_pushnumber(L, (lua_Number) fd); | ||||
|             lua_pushvalue(L, -2); | ||||
|             lua_settable(L, itab); | ||||
|         } | ||||
|         lua_pop(L, 1); | ||||
|         i = i + 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) { | ||||
|     int ndirty = 0, i = 1; | ||||
|     if (lua_isnil(L, tab))  | ||||
|         return 0; | ||||
|     for ( ;; ) {  | ||||
|         t_socket fd; | ||||
|         lua_pushnumber(L, i); | ||||
|         lua_gettable(L, tab); | ||||
|         if (lua_isnil(L, -1)) { | ||||
|             lua_pop(L, 1); | ||||
|             break; | ||||
|         } | ||||
|         fd = getfd(L); | ||||
|         if (fd != SOCKET_INVALID && dirty(L)) { | ||||
|             lua_pushnumber(L, ++ndirty); | ||||
|             lua_pushvalue(L, -2); | ||||
|             lua_settable(L, dtab); | ||||
|             FD_CLR(fd, set); | ||||
|         } | ||||
|         lua_pop(L, 1); | ||||
|         i = i + 1; | ||||
|     } | ||||
|     return ndirty; | ||||
| } | ||||
|  | ||||
| static void return_fd(lua_State *L, fd_set *set, t_socket max_fd,  | ||||
|         int itab, int tab, int start) { | ||||
|     t_socket fd; | ||||
|     for (fd = 0; fd < max_fd; fd++) { | ||||
|         if (FD_ISSET(fd, set)) { | ||||
|             lua_pushnumber(L, ++start); | ||||
|             lua_pushnumber(L, (lua_Number) fd); | ||||
|             lua_gettable(L, itab); | ||||
|             lua_settable(L, tab); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void make_assoc(lua_State *L, int tab) { | ||||
|     int i = 1, atab; | ||||
|     lua_newtable(L); atab = lua_gettop(L); | ||||
|     for ( ;; ) { | ||||
|         lua_pushnumber(L, i); | ||||
|         lua_gettable(L, tab); | ||||
|         if (!lua_isnil(L, -1)) { | ||||
|             lua_pushnumber(L, i); | ||||
|             lua_pushvalue(L, -2); | ||||
|             lua_settable(L, atab); | ||||
|             lua_pushnumber(L, i); | ||||
|             lua_settable(L, atab); | ||||
|         } else { | ||||
|             lua_pop(L, 1); | ||||
|             break; | ||||
|         } | ||||
|         i = i+1; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										19
									
								
								Plugins/slua_unreal/External/luasocket/select.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Plugins/slua_unreal/External/luasocket/select.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| #ifndef SELECT_H | ||||
| #define SELECT_H | ||||
| /*=========================================================================*\ | ||||
| * Select implementation | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * Each object that can be passed to the select function has to export  | ||||
| * method getfd() which returns the descriptor to be passed to the | ||||
| * underlying select function. Another method, dirty(), should return  | ||||
| * true if there is data ready for reading (required for buffered input). | ||||
| \*=========================================================================*/ | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| int select_open(lua_State *L); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* SELECT_H */ | ||||
							
								
								
									
										200
									
								
								Plugins/slua_unreal/External/luasocket/serial.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								Plugins/slua_unreal/External/luasocket/serial.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,200 @@ | ||||
| /*=========================================================================*\ | ||||
| * Serial stream | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <string.h>  | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
| #include "luasocket.h" | ||||
|  | ||||
| #include "auxiliar.h" | ||||
| #include "socket.h" | ||||
| #include "options.h" | ||||
| #include "unix.h" | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| #include <sys/un.h>  | ||||
| #endif | ||||
|  | ||||
| /* | ||||
| Reuses userdata definition from unix.h, since it is useful for all | ||||
| stream-like objects. | ||||
|  | ||||
| If we stored the serial path for use in error messages or userdata | ||||
| printing, we might need our own userdata definition. | ||||
|  | ||||
| Group usage is semi-inherited from unix.c, but unnecessary since we | ||||
| have only one object type. | ||||
| */ | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes | ||||
| \*=========================================================================*/ | ||||
| static int serial_global_create(lua_State *L); | ||||
| static int serial_meth_send(lua_State *L); | ||||
| static int serial_meth_receive(lua_State *L); | ||||
| static int serial_meth_close(lua_State *L); | ||||
| static int serial_meth_settimeout(lua_State *L); | ||||
| static int serial_meth_getfd(lua_State *L); | ||||
| static int serial_meth_setfd(lua_State *L); | ||||
| static int serial_meth_dirty(lua_State *L); | ||||
| static int serial_meth_getstats(lua_State *L); | ||||
| static int serial_meth_setstats(lua_State *L); | ||||
|  | ||||
| /* serial object methods */ | ||||
| static luaL_Reg serial_methods[] = { | ||||
|     {"__gc",        serial_meth_close}, | ||||
|     {"__tostring",  auxiliar_tostring}, | ||||
|     {"close",       serial_meth_close}, | ||||
|     {"dirty",       serial_meth_dirty}, | ||||
|     {"getfd",       serial_meth_getfd}, | ||||
|     {"getstats",    serial_meth_getstats}, | ||||
|     {"setstats",    serial_meth_setstats}, | ||||
|     {"receive",     serial_meth_receive}, | ||||
|     {"send",        serial_meth_send}, | ||||
|     {"setfd",       serial_meth_setfd}, | ||||
|     {"settimeout",  serial_meth_settimeout}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
| /* 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 serial_func[] = { | ||||
|     {"serial", serial_global_create}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| LUASOCKET_API int luaopen_socket_serial(lua_State *L) { | ||||
|     /* create classes */ | ||||
|     auxiliar_newclass(L, "serial{client}", serial_methods); | ||||
|     /* create class groups */ | ||||
|     auxiliar_add2group(L, "serial{client}", "serial{any}"); | ||||
| #if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) | ||||
|     lua_pushcfunction(L, serial_global_create); | ||||
|     (void)serial_func; | ||||
| #else | ||||
|     /* set function into socket namespace */ | ||||
|     luaL_openlib(L, "socket", serial_func, 0); | ||||
|     lua_pushcfunction(L, serial_global_create); | ||||
| #endif | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Lua methods | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call buffered IO methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int serial_meth_send(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1); | ||||
|     return buffer_meth_send(L, &un->buf); | ||||
| } | ||||
|  | ||||
| static int serial_meth_receive(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1); | ||||
|     return buffer_meth_receive(L, &un->buf); | ||||
| } | ||||
|  | ||||
| static int serial_meth_getstats(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1); | ||||
|     return buffer_meth_getstats(L, &un->buf); | ||||
| } | ||||
|  | ||||
| static int serial_meth_setstats(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "serial{client}", 1); | ||||
|     return buffer_meth_setstats(L, &un->buf); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Select support methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int serial_meth_getfd(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); | ||||
|     lua_pushnumber(L, (int) un->sock); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /* this is very dangerous, but can be handy for those that are brave enough */ | ||||
| static int serial_meth_setfd(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); | ||||
|     un->sock = (t_socket) luaL_checknumber(L, 2);  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int serial_meth_dirty(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); | ||||
|     lua_pushboolean(L, !buffer_isempty(&un->buf)); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Closes socket used by object  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int serial_meth_close(lua_State *L) | ||||
| { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); | ||||
|     socket_destroy(&un->sock); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call tm methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int serial_meth_settimeout(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "serial{any}", 1); | ||||
|     return timeout_meth_settimeout(L, &un->tm); | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Library functions | ||||
| \*=========================================================================*/ | ||||
|  | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Creates a serial object  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int serial_global_create(lua_State *L) { | ||||
| #ifndef _WIN32 | ||||
|     const char* path = luaL_checkstring(L, 1); | ||||
|  | ||||
|     /* allocate unix object */ | ||||
|     p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); | ||||
|  | ||||
|     /* open serial device */ | ||||
|     t_socket sock = open(path, O_NOCTTY|O_RDWR); | ||||
|  | ||||
|     /*printf("open %s on %d\n", path, sock);*/ | ||||
|  | ||||
|     if (sock < 0)  { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_strerror(errno)); | ||||
|         lua_pushnumber(L, errno); | ||||
|         return 3; | ||||
|     } | ||||
|     /* set its type as client object */ | ||||
|     auxiliar_setclass(L, "serial{client}", -1); | ||||
|     /* initialize remaining structure fields */ | ||||
|     socket_setnonblocking(&sock); | ||||
|     un->sock = sock; | ||||
|     io_init(&un->io, (p_send) socket_write, (p_recv) socket_read,  | ||||
|             (p_error) socket_ioerror, &un->sock); | ||||
|     timeout_init(&un->tm, -1, -1); | ||||
|     buffer_init(&un->buf, &un->io, &un->tm); | ||||
|     return 1; | ||||
| #else | ||||
| 	return -1; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										258
									
								
								Plugins/slua_unreal/External/luasocket/smtp.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								Plugins/slua_unreal/External/luasocket/smtp.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,258 @@ | ||||
| R"-++**++-( | ||||
| ----------------------------------------------------------------------------- | ||||
| -- 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 | ||||
| )-++**++-"; | ||||
							
								
								
									
										82
									
								
								Plugins/slua_unreal/External/luasocket/socket.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								Plugins/slua_unreal/External/luasocket/socket.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| #ifndef SOCKET_H | ||||
| #define SOCKET_H | ||||
| /*=========================================================================*\ | ||||
| * Socket compatibilization module | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * BSD Sockets and WinSock are similar, but there are a few irritating | ||||
| * differences. Also, not all *nix platforms behave the same. This module | ||||
| * (and the associated usocket.h and wsocket.h) factor these differences and | ||||
| * creates a interface compatible with the io.h module. | ||||
| \*=========================================================================*/ | ||||
| #include "io.h" | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Platform specific compatibilization | ||||
| \*=========================================================================*/ | ||||
| #ifdef _WIN32 | ||||
| #include "wsocket.h" | ||||
| #else | ||||
| #include "usocket.h" | ||||
| #endif | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * The connect and accept functions accept a timeout and their | ||||
| * implementations are somewhat complicated. We chose to move | ||||
| * the timeout control into this module for these functions in | ||||
| * order to simplify the modules that use them.  | ||||
| \*=========================================================================*/ | ||||
| #include "timeout.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /* we are lazy... */ | ||||
| typedef struct sockaddr SA; | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Functions bellow implement a comfortable platform independent  | ||||
| * interface to sockets | ||||
| \*=========================================================================*/ | ||||
| int socket_open(void); | ||||
| int socket_close(void); | ||||
| void socket_destroy(p_socket ps); | ||||
| void socket_shutdown(p_socket ps, int how);  | ||||
| int socket_sendto(p_socket ps, const char *data, size_t count,  | ||||
|         size_t *sent, SA *addr, socklen_t addr_len, p_timeout tm); | ||||
| int socket_recvfrom(p_socket ps, char *data, size_t count,  | ||||
|         size_t *got, SA *addr, socklen_t *addr_len, p_timeout tm); | ||||
|  | ||||
| void socket_setnonblocking(p_socket ps); | ||||
| void socket_setblocking(p_socket ps); | ||||
|  | ||||
| int socket_waitfd(p_socket ps, int sw, p_timeout tm); | ||||
| int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,  | ||||
|         p_timeout tm); | ||||
|  | ||||
| int socket_connect(p_socket ps, SA *addr, socklen_t addr_len, p_timeout tm);  | ||||
| int socket_create(p_socket ps, int domain, int type, int protocol); | ||||
| int socket_bind(p_socket ps, SA *addr, socklen_t addr_len);  | ||||
| int socket_listen(p_socket ps, int backlog); | ||||
| int socket_accept(p_socket ps, p_socket pa, SA *addr,  | ||||
|         socklen_t *addr_len, p_timeout tm); | ||||
|  | ||||
| const char *socket_hoststrerror(int err); | ||||
| const char *socket_gaistrerror(int err); | ||||
| const char *socket_strerror(int err); | ||||
|  | ||||
| /* these are perfect to use with the io abstraction module  | ||||
|    and the buffered input module */ | ||||
| int socket_send(p_socket ps, const char *data, size_t count,  | ||||
|         size_t *sent, p_timeout tm); | ||||
| int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm); | ||||
| int socket_write(p_socket ps, const char *data, size_t count,  | ||||
|         size_t *sent, p_timeout tm); | ||||
| int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm); | ||||
| const char *socket_ioerror(p_socket ps, int err); | ||||
|  | ||||
| int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp); | ||||
| int socket_gethostbyname(const char *addr, struct hostent **hp); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* SOCKET_H */ | ||||
							
								
								
									
										151
									
								
								Plugins/slua_unreal/External/luasocket/socket.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								Plugins/slua_unreal/External/luasocket/socket.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,151 @@ | ||||
| R"-++**++-( | ||||
| ----------------------------------------------------------------------------- | ||||
| -- 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 | ||||
| )-++**++-"; | ||||
							
								
								
									
										493
									
								
								Plugins/slua_unreal/External/luasocket/tcp.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										493
									
								
								Plugins/slua_unreal/External/luasocket/tcp.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,493 @@ | ||||
| /*=========================================================================*\ | ||||
| * TCP object | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "auxiliar.h" | ||||
| #include "socket.h" | ||||
| #include "inet.h" | ||||
| #include "options.h" | ||||
| #include "tcp.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes | ||||
| \*=========================================================================*/ | ||||
| static int tcp_global_create(lua_State *L); | ||||
| static int tcp_global_create6(lua_State *L); | ||||
| static int tcp_global_connect(lua_State *L); | ||||
| static int tcp_meth_connect(lua_State *L); | ||||
| static int tcp_meth_listen(lua_State *L); | ||||
| static int tcp_meth_getfamily(lua_State *L); | ||||
| static int tcp_meth_bind(lua_State *L); | ||||
| static int tcp_meth_send(lua_State *L); | ||||
| static int tcp_meth_getstats(lua_State *L); | ||||
| static int tcp_meth_setstats(lua_State *L); | ||||
| static int tcp_meth_getsockname(lua_State *L); | ||||
| static int tcp_meth_getpeername(lua_State *L); | ||||
| static int tcp_meth_shutdown(lua_State *L); | ||||
| static int tcp_meth_receive(lua_State *L); | ||||
| static int tcp_meth_accept(lua_State *L); | ||||
| static int tcp_meth_close(lua_State *L); | ||||
| static int tcp_meth_getoption(lua_State *L); | ||||
| static int tcp_meth_setoption(lua_State *L); | ||||
| static int tcp_meth_settimeout(lua_State *L); | ||||
| static int tcp_meth_getfd(lua_State *L); | ||||
| static int tcp_meth_setfd(lua_State *L); | ||||
| static int tcp_meth_dirty(lua_State *L); | ||||
|  | ||||
| /* tcp object methods */ | ||||
| static luaL_Reg tcp_methods[] = { | ||||
|     {"__gc",        tcp_meth_close}, | ||||
|     {"__tostring",  auxiliar_tostring}, | ||||
|     {"accept",      tcp_meth_accept}, | ||||
|     {"bind",        tcp_meth_bind}, | ||||
|     {"close",       tcp_meth_close}, | ||||
|     {"connect",     tcp_meth_connect}, | ||||
|     {"dirty",       tcp_meth_dirty}, | ||||
|     {"getfamily",   tcp_meth_getfamily}, | ||||
|     {"getfd",       tcp_meth_getfd}, | ||||
|     {"getoption",   tcp_meth_getoption}, | ||||
|     {"getpeername", tcp_meth_getpeername}, | ||||
|     {"getsockname", tcp_meth_getsockname}, | ||||
|     {"getstats",    tcp_meth_getstats}, | ||||
|     {"setstats",    tcp_meth_setstats}, | ||||
|     {"listen",      tcp_meth_listen}, | ||||
|     {"receive",     tcp_meth_receive}, | ||||
|     {"send",        tcp_meth_send}, | ||||
|     {"setfd",       tcp_meth_setfd}, | ||||
|     {"setoption",   tcp_meth_setoption}, | ||||
|     {"setpeername", tcp_meth_connect}, | ||||
|     {"setsockname", tcp_meth_bind}, | ||||
|     {"settimeout",  tcp_meth_settimeout}, | ||||
|     {"shutdown",    tcp_meth_shutdown}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
| /* socket option handlers */ | ||||
| static t_opt tcp_optget[] = { | ||||
|     {"keepalive",   opt_get_keepalive}, | ||||
|     {"reuseaddr",   opt_get_reuseaddr}, | ||||
|     {"tcp-nodelay", opt_get_tcp_nodelay}, | ||||
|     {"linger",      opt_get_linger}, | ||||
|     {"error",       opt_get_error}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
| static t_opt tcp_optset[] = { | ||||
|     {"keepalive",   opt_set_keepalive}, | ||||
|     {"reuseaddr",   opt_set_reuseaddr}, | ||||
|     {"tcp-nodelay", opt_set_tcp_nodelay}, | ||||
|     {"ipv6-v6only", opt_set_ip6_v6only}, | ||||
|     {"linger",      opt_set_linger}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
| /* functions in library namespace */ | ||||
| static luaL_Reg tcp_func[] = { | ||||
|     {"tcp", tcp_global_create}, | ||||
|     {"tcp6", tcp_global_create6}, | ||||
|     {"connect", tcp_global_connect}, | ||||
|     {NULL, NULL} | ||||
| }; | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int tcp_open(lua_State *L) | ||||
| { | ||||
|     /* create classes */ | ||||
|     auxiliar_newclass(L, "tcp{master}", tcp_methods); | ||||
|     auxiliar_newclass(L, "tcp{client}", tcp_methods); | ||||
|     auxiliar_newclass(L, "tcp{server}", tcp_methods); | ||||
|     /* create class groups */ | ||||
|     auxiliar_add2group(L, "tcp{master}", "tcp{any}"); | ||||
|     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, tcp_func, 0); | ||||
| #else | ||||
|     luaL_openlib(L, NULL, tcp_func, 0); | ||||
| #endif | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Lua methods | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call buffered IO methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_send(lua_State *L) { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||||
|     return buffer_meth_send(L, &tcp->buf); | ||||
| } | ||||
|  | ||||
| static int tcp_meth_receive(lua_State *L) { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||||
|     return buffer_meth_receive(L, &tcp->buf); | ||||
| } | ||||
|  | ||||
| static int tcp_meth_getstats(lua_State *L) { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||||
|     return buffer_meth_getstats(L, &tcp->buf); | ||||
| } | ||||
|  | ||||
| static int tcp_meth_setstats(lua_State *L) { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||||
|     return buffer_meth_setstats(L, &tcp->buf); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call option handler | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_getoption(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     return opt_meth_getoption(L, tcp_optget, &tcp->sock); | ||||
| } | ||||
|  | ||||
| static int tcp_meth_setoption(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     return opt_meth_setoption(L, tcp_optset, &tcp->sock); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Select support methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_getfd(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     lua_pushnumber(L, (int) tcp->sock); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /* this is very dangerous, but can be handy for those that are brave enough */ | ||||
| static int tcp_meth_setfd(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     tcp->sock = (t_socket) luaL_checknumber(L, 2); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int tcp_meth_dirty(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     lua_pushboolean(L, !buffer_isempty(&tcp->buf)); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Waits for and returns a client object attempting connection to the | ||||
| * server object | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_accept(lua_State *L) | ||||
| { | ||||
|     p_tcp server = (p_tcp) auxiliar_checkclass(L, "tcp{server}", 1); | ||||
|     p_timeout tm = timeout_markstart(&server->tm); | ||||
|     t_socket sock; | ||||
|     const char *err = inet_tryaccept(&server->sock, server->family, &sock, tm); | ||||
|     /* if successful, push client socket */ | ||||
|     if (err == NULL) { | ||||
|         p_tcp clnt = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||||
|         auxiliar_setclass(L, "tcp{client}", -1); | ||||
|         /* initialize structure fields */ | ||||
|         memset(clnt, 0, sizeof(t_tcp)); | ||||
|         socket_setnonblocking(&sock); | ||||
|         clnt->sock = sock; | ||||
|         io_init(&clnt->io, (p_send) socket_send, (p_recv) socket_recv, | ||||
|                 (p_error) socket_ioerror, &clnt->sock); | ||||
|         timeout_init(&clnt->tm, -1, -1); | ||||
|         buffer_init(&clnt->buf, &clnt->io, &clnt->tm); | ||||
|         clnt->family = server->family; | ||||
|         return 1; | ||||
|     } else { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Binds an object to an address | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_bind(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); | ||||
|     const char *address =  luaL_checkstring(L, 2); | ||||
|     const char *port = luaL_checkstring(L, 3); | ||||
|     const char *err; | ||||
|     struct addrinfo bindhints; | ||||
|     memset(&bindhints, 0, sizeof(bindhints)); | ||||
|     bindhints.ai_socktype = SOCK_STREAM; | ||||
|     bindhints.ai_family = tcp->family; | ||||
|     bindhints.ai_flags = AI_PASSIVE; | ||||
|     err = inet_trybind(&tcp->sock, address, port, &bindhints); | ||||
|     if (err) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Turns a master tcp object into a client object. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_connect(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     const char *address =  luaL_checkstring(L, 2); | ||||
|     const char *port = luaL_checkstring(L, 3); | ||||
|     struct addrinfo connecthints; | ||||
|     const char *err; | ||||
|     memset(&connecthints, 0, sizeof(connecthints)); | ||||
|     connecthints.ai_socktype = SOCK_STREAM; | ||||
|     /* 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, &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) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Closes socket used by object | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_close(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     socket_destroy(&tcp->sock); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Returns family as string | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_getfamily(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     if (tcp->family == PF_INET6) { | ||||
|         lua_pushliteral(L, "inet6"); | ||||
|         return 1; | ||||
|     } else { | ||||
|         lua_pushliteral(L, "inet4"); | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Puts the sockt in listen mode | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_listen(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{master}", 1); | ||||
|     int backlog = (int) luaL_optnumber(L, 2, 32); | ||||
|     int err = socket_listen(&tcp->sock, backlog); | ||||
|     if (err != IO_DONE) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_strerror(err)); | ||||
|         return 2; | ||||
|     } | ||||
|     /* turn master object into a server object */ | ||||
|     auxiliar_setclass(L, "tcp{server}", 1); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Shuts the connection down partially | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_shutdown(lua_State *L) | ||||
| { | ||||
|     /* SHUT_RD,  SHUT_WR,  SHUT_RDWR  have  the value 0, 1, 2, so we can use method index directly */ | ||||
|     static const char* methods[] = { "receive", "send", "both", NULL }; | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); | ||||
|     int how = luaL_checkoption(L, 2, "both", methods); | ||||
|     socket_shutdown(&tcp->sock, how); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call inet methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_getpeername(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     return inet_meth_getpeername(L, &tcp->sock, tcp->family); | ||||
| } | ||||
|  | ||||
| static int tcp_meth_getsockname(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     return inet_meth_getsockname(L, &tcp->sock, tcp->family); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call tm methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_meth_settimeout(lua_State *L) | ||||
| { | ||||
|     p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); | ||||
|     return timeout_meth_settimeout(L, &tcp->tm); | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Library functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Creates a master tcp object | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int tcp_create(lua_State *L, int family) { | ||||
|     t_socket sock; | ||||
|     const char *err = inet_trycreate(&sock, family, SOCK_STREAM); | ||||
|     /* try to allocate a system socket */ | ||||
|     if (!err) { | ||||
|         /* allocate tcp object */ | ||||
|         p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||||
|         memset(tcp, 0, sizeof(t_tcp)); | ||||
|         /* set its type as master object */ | ||||
|         auxiliar_setclass(L, "tcp{master}", -1); | ||||
|         /* initialize remaining structure fields */ | ||||
|         socket_setnonblocking(&sock); | ||||
|         if (family == PF_INET6) { | ||||
|             int yes = 1; | ||||
|             setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, | ||||
|                 reinterpret_cast<const char *>(&yes), sizeof(yes)); | ||||
|         } | ||||
|         tcp->sock = sock; | ||||
|         io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, | ||||
|                 (p_error) socket_ioerror, &tcp->sock); | ||||
|         timeout_init(&tcp->tm, -1, -1); | ||||
|         buffer_init(&tcp->buf, &tcp->io, &tcp->tm); | ||||
|         tcp->family = family; | ||||
|         return 1; | ||||
|     } else { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int tcp_global_create(lua_State *L) { | ||||
|     return tcp_create(L, AF_INET); | ||||
| } | ||||
|  | ||||
| static int tcp_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; | ||||
|     const char *err = NULL; | ||||
|     /* try resolving */ | ||||
|     err = socket_gaistrerror(getaddrinfo(remoteaddr, remoteserv, | ||||
|                 connecthints, &resolved)); | ||||
|     if (err != NULL) { | ||||
|         if (resolved) freeaddrinfo(resolved); | ||||
|         return err; | ||||
|     } | ||||
|     /* 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 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)); | ||||
|             if (err != NULL) { | ||||
|                 freeaddrinfo(resolved); | ||||
|                 return err; | ||||
|             } | ||||
|             tcp->family = iterator->ai_family; | ||||
|             /* all sockets initially non-blocking */ | ||||
|             socket_setnonblocking(&tcp->sock); | ||||
|         } | ||||
|         /* finally try connecting to remote address */ | ||||
|         err = socket_strerror(socket_connect(&tcp->sock, | ||||
|             (SA *) iterator->ai_addr, | ||||
|             (socklen_t) iterator->ai_addrlen, tm)); | ||||
|         /* if success, break out of loop */ | ||||
|         if (err == NULL) break; | ||||
|     } | ||||
|  | ||||
|     freeaddrinfo(resolved); | ||||
|     /* here, if err is set, we failed */ | ||||
|     return err; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static int tcp_global_connect(lua_State *L) { | ||||
|     const char *remoteaddr = luaL_checkstring(L, 1); | ||||
|     const char *remoteserv = luaL_checkstring(L, 2); | ||||
|     const char *localaddr  = luaL_optstring(L, 3, NULL); | ||||
|     const char *localserv  = luaL_optstring(L, 4, "0"); | ||||
|     int family = inet_optfamily(L, 5, "unspec"); | ||||
|     p_tcp tcp = (p_tcp) lua_newuserdata(L, sizeof(t_tcp)); | ||||
|     struct addrinfo bindhints, connecthints; | ||||
|     const char *err = NULL; | ||||
|     /* initialize tcp structure */ | ||||
|     memset(tcp, 0, sizeof(t_tcp)); | ||||
|     io_init(&tcp->io, (p_send) socket_send, (p_recv) socket_recv, | ||||
|             (p_error) socket_ioerror, &tcp->sock); | ||||
|     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; | ||||
|     bindhints.ai_family = family; | ||||
|     bindhints.ai_flags = AI_PASSIVE; | ||||
|     if (localaddr) { | ||||
|         err = inet_trybind(&tcp->sock, localaddr, localserv, &bindhints); | ||||
|         if (err) { | ||||
|             lua_pushnil(L); | ||||
|             lua_pushstring(L, err); | ||||
|             return 2; | ||||
|         } | ||||
|         tcp->family = bindhints.ai_family; | ||||
|     } | ||||
|     /* try to connect to remote address and port */ | ||||
|     memset(&connecthints, 0, sizeof(connecthints)); | ||||
|     connecthints.ai_socktype = SOCK_STREAM; | ||||
|     /* make sure we try to connect only to the same family */ | ||||
|     connecthints.ai_family = bindhints.ai_family; | ||||
|     err = inet_tryconnect(&tcp->sock, &tcp->family, remoteaddr, remoteserv, | ||||
|          &tcp->tm, &connecthints); | ||||
|     if (err) { | ||||
|         socket_destroy(&tcp->sock); | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
|     auxiliar_setclass(L, "tcp{client}", -1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										39
									
								
								Plugins/slua_unreal/External/luasocket/tcp.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								Plugins/slua_unreal/External/luasocket/tcp.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| #ifndef TCP_H | ||||
| #define TCP_H | ||||
| /*=========================================================================*\ | ||||
| * TCP object | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * The tcp.h module is basicly a glue that puts together modules buffer.h, | ||||
| * timeout.h socket.h and inet.h to provide the LuaSocket TCP (AF_INET, | ||||
| * SOCK_STREAM) support. | ||||
| * | ||||
| * Three classes are defined: master, client and server. The master class is | ||||
| * a newly created tcp object, that has not been bound or connected. Server | ||||
| * objects are tcp objects bound to some local address. Client objects are | ||||
| * tcp objects either connected to some address or returned by the accept | ||||
| * method of a server object. | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
|  | ||||
| #include "buffer.h" | ||||
| #include "timeout.h" | ||||
| #include "socket.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| typedef struct t_tcp_ { | ||||
|     t_socket sock; | ||||
|     t_io io; | ||||
|     t_buffer buf; | ||||
|     t_timeout tm; | ||||
|     int family; | ||||
| } t_tcp; | ||||
|  | ||||
| typedef t_tcp *p_tcp; | ||||
|  | ||||
| int tcp_open(lua_State *L); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* TCP_H */ | ||||
							
								
								
									
										225
									
								
								Plugins/slua_unreal/External/luasocket/timeout.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								Plugins/slua_unreal/External/luasocket/timeout.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,225 @@ | ||||
| /*=========================================================================*\ | ||||
| * Timeout management functions | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <stdio.h> | ||||
| #include <limits.h> | ||||
| #include <float.h> | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "auxiliar.h" | ||||
| #include "timeout.h" | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| #include <windows.h> | ||||
| #else | ||||
| #include <time.h> | ||||
| #include <sys/time.h> | ||||
| #endif | ||||
|  | ||||
| /* min and max macros */ | ||||
| #ifndef MIN | ||||
| #define MIN(x, y) ((x) < (y) ? x : y) | ||||
| #endif | ||||
| #ifndef MAX | ||||
| #define MAX(x, y) ((x) > (y) ? x : y) | ||||
| #endif | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes | ||||
| \*=========================================================================*/ | ||||
| static int timeout_lua_gettime(lua_State *L); | ||||
| static int timeout_lua_sleep(lua_State *L); | ||||
|  | ||||
| static luaL_Reg timeout_func[] = { | ||||
|     { "gettime", timeout_lua_gettime }, | ||||
|     { "sleep", timeout_lua_sleep }, | ||||
|     { NULL, NULL } | ||||
| }; | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Exported functions. | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initialize structure | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void timeout_init(p_timeout tm, double block, double total) { | ||||
|     tm->block = block; | ||||
|     tm->total = total; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Determines how much time we have left for the next system call, | ||||
| * if the previous call was successful  | ||||
| * Input | ||||
| *   tm: timeout control structure | ||||
| * Returns | ||||
| *   the number of ms left or -1 if there is no time limit | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| double timeout_get(p_timeout tm) { | ||||
|     if (tm->block < 0.0 && tm->total < 0.0) { | ||||
|         return -1; | ||||
|     } else if (tm->block < 0.0) { | ||||
|         double t = tm->total - timeout_gettime() + tm->start; | ||||
|         return MAX(t, 0.0); | ||||
|     } else if (tm->total < 0.0) { | ||||
|         return tm->block; | ||||
|     } else { | ||||
|         double t = tm->total - timeout_gettime() + tm->start; | ||||
|         return MIN(tm->block, MAX(t, 0.0)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Returns time since start of operation | ||||
| * Input | ||||
| *   tm: timeout control structure | ||||
| * Returns | ||||
| *   start field of structure | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| double timeout_getstart(p_timeout tm) { | ||||
|     return tm->start; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Determines how much time we have left for the next system call, | ||||
| * if the previous call was a failure | ||||
| * Input | ||||
| *   tm: timeout control structure | ||||
| * Returns | ||||
| *   the number of ms left or -1 if there is no time limit | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| double timeout_getretry(p_timeout tm) { | ||||
|     if (tm->block < 0.0 && tm->total < 0.0) { | ||||
|         return -1; | ||||
|     } else if (tm->block < 0.0) { | ||||
|         double t = tm->total - timeout_gettime() + tm->start; | ||||
|         return MAX(t, 0.0); | ||||
|     } else if (tm->total < 0.0) { | ||||
|         double t = tm->block - timeout_gettime() + tm->start; | ||||
|         return MAX(t, 0.0); | ||||
|     } else { | ||||
|         double t = tm->total - timeout_gettime() + tm->start; | ||||
|         return MIN(tm->block, MAX(t, 0.0)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Marks the operation start time in structure  | ||||
| * Input | ||||
| *   tm: timeout control structure | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| p_timeout timeout_markstart(p_timeout tm) { | ||||
|     tm->start = timeout_gettime(); | ||||
|     return tm; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Gets time in s, relative to January 1, 1970 (UTC)  | ||||
| * Returns | ||||
| *   time in s. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #ifdef _WIN32 | ||||
| double timeout_gettime(void) { | ||||
|     FILETIME ft; | ||||
|     double t; | ||||
|     GetSystemTimeAsFileTime(&ft); | ||||
|     /* Windows file time (time since January 1, 1601 (UTC)) */ | ||||
|     t  = ft.dwLowDateTime/1.0e7 + ft.dwHighDateTime*(4294967296.0/1.0e7); | ||||
|     /* convert to Unix Epoch time (time since January 1, 1970 (UTC)) */ | ||||
|     return (t - 11644473600.0); | ||||
| } | ||||
| #else | ||||
| double timeout_gettime(void) { | ||||
|     struct timeval v; | ||||
|     gettimeofday(&v, (struct timezone *) NULL); | ||||
|     /* Unix Epoch time (time since January 1, 1970 (UTC)) */ | ||||
|     return v.tv_sec + v.tv_usec/1.0e6; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int timeout_open(lua_State *L) { | ||||
| #if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) | ||||
|     luaL_setfuncs(L, timeout_func, 0); | ||||
| #else | ||||
|     luaL_openlib(L, NULL, timeout_func, 0); | ||||
| #endif | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Sets timeout values for IO operations | ||||
| * Lua Input: base, time [, mode] | ||||
| *   time: time out value in seconds | ||||
| *   mode: "b" for block timeout, "t" for total timeout. (default: b) | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int timeout_meth_settimeout(lua_State *L, p_timeout tm) { | ||||
|     double t = luaL_optnumber(L, 2, -1); | ||||
|     const char *mode = luaL_optstring(L, 3, "b"); | ||||
|     switch (*mode) { | ||||
|         case 'b': | ||||
|             tm->block = t;  | ||||
|             break; | ||||
|         case 'r': case 't': | ||||
|             tm->total = t; | ||||
|             break; | ||||
|         default: | ||||
|             luaL_argcheck(L, 0, 3, "invalid timeout mode"); | ||||
|             break; | ||||
|     } | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Test support functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Returns the time the system has been up, in secconds. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int timeout_lua_gettime(lua_State *L) | ||||
| { | ||||
|     lua_pushnumber(L, timeout_gettime()); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Sleep for n seconds. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #ifdef _WIN32 | ||||
| int timeout_lua_sleep(lua_State *L) | ||||
| { | ||||
|     double n = luaL_checknumber(L, 1); | ||||
|     if (n < 0.0) n = 0.0; | ||||
|     if (n < DBL_MAX/1000.0) n *= 1000.0; | ||||
|     if (n > INT_MAX) n = INT_MAX; | ||||
|     Sleep((int)n); | ||||
|     return 0; | ||||
| } | ||||
| #else | ||||
| int timeout_lua_sleep(lua_State *L) | ||||
| { | ||||
|     double n = luaL_checknumber(L, 1); | ||||
|     struct timespec t, r; | ||||
|     if (n < 0.0) n = 0.0; | ||||
|     if (n > INT_MAX) n = INT_MAX; | ||||
|     t.tv_sec = (int) n; | ||||
|     n -= t.tv_sec; | ||||
|     t.tv_nsec = (int) (n * 1000000000); | ||||
|     if (t.tv_nsec >= 1000000000) t.tv_nsec = 999999999; | ||||
|     while (nanosleep(&t, &r) != 0) { | ||||
|         t.tv_sec = r.tv_sec; | ||||
|         t.tv_nsec = r.tv_nsec; | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										32
									
								
								Plugins/slua_unreal/External/luasocket/timeout.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								Plugins/slua_unreal/External/luasocket/timeout.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| #ifndef TIMEOUT_H | ||||
| #define TIMEOUT_H | ||||
| /*=========================================================================*\ | ||||
| * Timeout management functions | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /* timeout control structure */ | ||||
| typedef struct t_timeout_ { | ||||
|     double block;          /* maximum time for blocking calls */ | ||||
|     double total;          /* total number of miliseconds for operation */ | ||||
|     double start;          /* time of start of operation */ | ||||
| } t_timeout; | ||||
| typedef t_timeout *p_timeout; | ||||
|  | ||||
| int timeout_open(lua_State *L); | ||||
| void timeout_init(p_timeout tm, double block, double total); | ||||
| double timeout_get(p_timeout tm); | ||||
| double timeout_getretry(p_timeout tm); | ||||
| p_timeout timeout_markstart(p_timeout tm); | ||||
| double timeout_getstart(p_timeout tm); | ||||
| double timeout_gettime(void); | ||||
| int timeout_meth_settimeout(lua_State *L, p_timeout tm); | ||||
|  | ||||
| #define timeout_iszero(tm)   ((tm)->block == 0.0) | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* TIMEOUT_H */ | ||||
							
								
								
									
										128
									
								
								Plugins/slua_unreal/External/luasocket/tp.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								Plugins/slua_unreal/External/luasocket/tp.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | ||||
| R"-++**++-( | ||||
| ----------------------------------------------------------------------------- | ||||
| -- 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 | ||||
| )-++**++-"; | ||||
							
								
								
									
										449
									
								
								Plugins/slua_unreal/External/luasocket/udp.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										449
									
								
								Plugins/slua_unreal/External/luasocket/udp.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,449 @@ | ||||
| /*=========================================================================*\ | ||||
| * UDP object | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "auxiliar.h" | ||||
| #include "socket.h" | ||||
| #include "inet.h" | ||||
| #include "options.h" | ||||
| #include "udp.h" | ||||
|  | ||||
| /* min and max macros */ | ||||
| #ifndef MIN | ||||
| #define MIN(x, y) ((x) < (y) ? x : y) | ||||
| #endif | ||||
| #ifndef MAX | ||||
| #define MAX(x, y) ((x) > (y) ? x : y) | ||||
| #endif | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| #define gai_strerror gai_strerrorA | ||||
| #endif | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes | ||||
| \*=========================================================================*/ | ||||
| static int udp_global_create(lua_State *L); | ||||
| static int udp_global_create6(lua_State *L); | ||||
| static int udp_meth_send(lua_State *L); | ||||
| static int udp_meth_sendto(lua_State *L); | ||||
| static int udp_meth_receive(lua_State *L); | ||||
| static int udp_meth_receivefrom(lua_State *L); | ||||
| static int udp_meth_getfamily(lua_State *L); | ||||
| static int udp_meth_getsockname(lua_State *L); | ||||
| static int udp_meth_getpeername(lua_State *L); | ||||
| static int udp_meth_setsockname(lua_State *L); | ||||
| static int udp_meth_setpeername(lua_State *L); | ||||
| static int udp_meth_close(lua_State *L); | ||||
| static int udp_meth_setoption(lua_State *L); | ||||
| static int udp_meth_getoption(lua_State *L); | ||||
| static int udp_meth_settimeout(lua_State *L); | ||||
| static int udp_meth_getfd(lua_State *L); | ||||
| static int udp_meth_setfd(lua_State *L); | ||||
| static int udp_meth_dirty(lua_State *L); | ||||
|  | ||||
| /* udp object methods */ | ||||
| static luaL_Reg udp_methods[] = { | ||||
|     {"__gc",        udp_meth_close}, | ||||
|     {"__tostring",  auxiliar_tostring}, | ||||
|     {"close",       udp_meth_close}, | ||||
|     {"dirty",       udp_meth_dirty}, | ||||
|     {"getfamily",   udp_meth_getfamily}, | ||||
|     {"getfd",       udp_meth_getfd}, | ||||
|     {"getpeername", udp_meth_getpeername}, | ||||
|     {"getsockname", udp_meth_getsockname}, | ||||
|     {"receive",     udp_meth_receive}, | ||||
|     {"receivefrom", udp_meth_receivefrom}, | ||||
|     {"send",        udp_meth_send}, | ||||
|     {"sendto",      udp_meth_sendto}, | ||||
|     {"setfd",       udp_meth_setfd}, | ||||
|     {"setoption",   udp_meth_setoption}, | ||||
|     {"getoption",   udp_meth_getoption}, | ||||
|     {"setpeername", udp_meth_setpeername}, | ||||
|     {"setsockname", udp_meth_setsockname}, | ||||
|     {"settimeout",  udp_meth_settimeout}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
| /* socket options for setoption */ | ||||
| static t_opt udp_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-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 udp_optget[] = { | ||||
|     {"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 */ | ||||
| static luaL_Reg udp_func[] = { | ||||
|     {"udp", udp_global_create}, | ||||
|     {"udp6", udp_global_create6}, | ||||
|     {NULL, NULL} | ||||
| }; | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int udp_open(lua_State *L) | ||||
| { | ||||
|     /* create classes */ | ||||
|     auxiliar_newclass(L, "udp{connected}", udp_methods); | ||||
|     auxiliar_newclass(L, "udp{unconnected}", udp_methods); | ||||
|     /* create class groups */ | ||||
|     auxiliar_add2group(L, "udp{connected}",   "udp{any}"); | ||||
|     auxiliar_add2group(L, "udp{unconnected}", "udp{any}"); | ||||
|     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, udp_func, 0); | ||||
| #else | ||||
|     luaL_openlib(L, NULL, udp_func, 0); | ||||
| #endif | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Lua methods | ||||
| \*=========================================================================*/ | ||||
| const char *udp_strerror(int err) { | ||||
|     /* a 'closed' error on an unconnected means the target address was not | ||||
|      * accepted by the transport layer */ | ||||
|     if (err == IO_CLOSED) return "refused"; | ||||
|     else return socket_strerror(err); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Send data through connected udp socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_send(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); | ||||
|     p_timeout tm = &udp->tm; | ||||
|     size_t count, sent = 0; | ||||
|     int err; | ||||
|     const char *data = luaL_checklstring(L, 2, &count); | ||||
|     timeout_markstart(tm); | ||||
|     err = socket_send(&udp->sock, data, count, &sent, tm); | ||||
|     if (err != IO_DONE) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, udp_strerror(err)); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushnumber(L, (lua_Number) sent); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Send data through unconnected udp socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_sendto(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); | ||||
|     size_t count, sent = 0; | ||||
|     const char *data = luaL_checklstring(L, 2, &count); | ||||
|     const char *ip = luaL_checkstring(L, 3); | ||||
|     const char *port = luaL_checkstring(L, 4); | ||||
|     p_timeout tm = &udp->tm; | ||||
|     int err; | ||||
|     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)); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushnumber(L, (lua_Number) sent); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Receives data from a UDP socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_receive(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     char buffer[UDP_DATAGRAMSIZE]; | ||||
|     size_t got, count = (size_t) luaL_optnumber(L, 2, sizeof(buffer)); | ||||
|     int err; | ||||
|     p_timeout tm = &udp->tm; | ||||
|     count = MIN(count, sizeof(buffer)); | ||||
|     timeout_markstart(tm); | ||||
|     err = socket_recv(&udp->sock, buffer, count, &got, 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_pushstring(L, udp_strerror(err)); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushlstring(L, buffer, got); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Receives data and sender from a UDP socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_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)); | ||||
|     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_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; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Returns family as string | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_getfamily(lua_State *L) | ||||
| { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     if (udp->family == PF_INET6) { | ||||
|         lua_pushliteral(L, "inet6"); | ||||
|         return 1; | ||||
|     } else { | ||||
|         lua_pushliteral(L, "inet4"); | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Select support methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_getfd(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     lua_pushnumber(L, (int) udp->sock); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /* this is very dangerous, but can be handy for those that are brave enough */ | ||||
| static int udp_meth_setfd(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     udp->sock = (t_socket) luaL_checknumber(L, 2); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int udp_meth_dirty(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     (void) udp; | ||||
|     lua_pushboolean(L, 0); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call inet methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_getpeername(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{connected}", 1); | ||||
|     return inet_meth_getpeername(L, &udp->sock, udp->family); | ||||
| } | ||||
|  | ||||
| static int udp_meth_getsockname(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     return inet_meth_getsockname(L, &udp->sock, udp->family); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call option handler | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_setoption(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     return opt_meth_setoption(L, udp_optset, &udp->sock); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call option handler | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_getoption(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     return opt_meth_getoption(L, udp_optget, &udp->sock); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call tm methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_settimeout(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     return timeout_meth_settimeout(L, &udp->tm); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Turns a master udp object into a client object. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_setpeername(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     p_timeout tm = &udp->tm; | ||||
|     const char *address = luaL_checkstring(L, 2); | ||||
|     int connecting = strcmp(address, "*"); | ||||
|     const char *port = connecting? luaL_checkstring(L, 3): "0"; | ||||
|     struct addrinfo connecthints; | ||||
|     const char *err; | ||||
|     memset(&connecthints, 0, sizeof(connecthints)); | ||||
|     connecthints.ai_socktype = SOCK_DGRAM; | ||||
|     /* make sure we try to connect only to the same family */ | ||||
|     connecthints.ai_family = udp->family; | ||||
|     if (connecting) { | ||||
|         err = inet_tryconnect(&udp->sock, &udp->family, address,  | ||||
|             port, tm, &connecthints); | ||||
|         if (err) { | ||||
|             lua_pushnil(L); | ||||
|             lua_pushstring(L, err); | ||||
|             return 2; | ||||
|         } | ||||
|         auxiliar_setclass(L, "udp{connected}", 1); | ||||
|     } else { | ||||
|         /* we ignore possible errors because Mac OS X always | ||||
|          * returns EAFNOSUPPORT */ | ||||
|         inet_trydisconnect(&udp->sock, udp->family, tm); | ||||
|         auxiliar_setclass(L, "udp{unconnected}", 1); | ||||
|     } | ||||
|     /* change class to connected or unconnected depending on address */ | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Closes socket used by object | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_close(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); | ||||
|     socket_destroy(&udp->sock); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Turns a master object into a server object | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_meth_setsockname(lua_State *L) { | ||||
|     p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1); | ||||
|     const char *address =  luaL_checkstring(L, 2); | ||||
|     const char *port = luaL_checkstring(L, 3); | ||||
|     const char *err; | ||||
|     struct addrinfo bindhints; | ||||
|     memset(&bindhints, 0, sizeof(bindhints)); | ||||
|     bindhints.ai_socktype = SOCK_DGRAM; | ||||
|     bindhints.ai_family = udp->family; | ||||
|     bindhints.ai_flags = AI_PASSIVE; | ||||
|     err = inet_trybind(&udp->sock, address, port, &bindhints); | ||||
|     if (err) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Library functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Creates a master udp object | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int udp_create(lua_State *L, int family) { | ||||
|     t_socket sock; | ||||
|     const char *err = inet_trycreate(&sock, family, SOCK_DGRAM); | ||||
|     /* try to allocate a system socket */ | ||||
|     if (!err) { | ||||
|         /* allocate udp object */ | ||||
|         p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp)); | ||||
|         auxiliar_setclass(L, "udp{unconnected}", -1); | ||||
|         /* initialize remaining structure fields */ | ||||
|         socket_setnonblocking(&sock); | ||||
|         if (family == PF_INET6) { | ||||
|             int yes = 1; | ||||
|             setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, | ||||
|                 reinterpret_cast<const char*>(&yes), sizeof(yes)); | ||||
|         } | ||||
|         udp->sock = sock; | ||||
|         timeout_init(&udp->tm, -1, -1); | ||||
|         udp->family = family; | ||||
|         return 1; | ||||
|     } else { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int udp_global_create(lua_State *L) { | ||||
|     return udp_create(L, AF_INET); | ||||
| } | ||||
|  | ||||
| static int udp_global_create6(lua_State *L) { | ||||
|     return udp_create(L, AF_INET6); | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										36
									
								
								Plugins/slua_unreal/External/luasocket/udp.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Plugins/slua_unreal/External/luasocket/udp.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | ||||
| #ifndef UDP_H | ||||
| #define UDP_H | ||||
| /*=========================================================================*\ | ||||
| * UDP object | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * The udp.h module provides LuaSocket with support for UDP protocol | ||||
| * (AF_INET, SOCK_DGRAM). | ||||
| * | ||||
| * Two classes are defined: connected and unconnected. UDP objects are | ||||
| * originally unconnected. They can be "connected" to a given address  | ||||
| * with a call to the setpeername function. The same function can be used to | ||||
| * break the connection. | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
|  | ||||
| #include "timeout.h" | ||||
| #include "socket.h" | ||||
|  | ||||
| /* can't be larger than wsocket.c MAXCHUNK!!! */ | ||||
| #define UDP_DATAGRAMSIZE 8192 | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| typedef struct t_udp_ { | ||||
|     t_socket sock; | ||||
|     t_timeout tm; | ||||
|     int family; | ||||
| } t_udp; | ||||
| typedef t_udp *p_udp; | ||||
|  | ||||
| int udp_open(lua_State *L); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* UDP_H */ | ||||
							
								
								
									
										363
									
								
								Plugins/slua_unreal/External/luasocket/unix.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										363
									
								
								Plugins/slua_unreal/External/luasocket/unix.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,363 @@ | ||||
| /*=========================================================================*\ | ||||
| * Unix domain socket  | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
|  | ||||
|  | ||||
| #include <string.h>  | ||||
|  | ||||
| #include "lua.h" | ||||
| #include "lauxlib.h" | ||||
|  | ||||
| #include "auxiliar.h" | ||||
| #include "socket.h" | ||||
| #include "options.h" | ||||
| #include "unix.h" | ||||
|  | ||||
| #ifndef _WIN32 | ||||
| #include <sys/un.h>  | ||||
| #endif // _WIN32 | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Internal function prototypes | ||||
| \*=========================================================================*/ | ||||
| static int unix_global_create(lua_State *L); | ||||
| static int unix_meth_connect(lua_State *L); | ||||
| static int unix_meth_listen(lua_State *L); | ||||
| static int unix_meth_bind(lua_State *L); | ||||
| static int unix_meth_send(lua_State *L); | ||||
| static int unix_meth_shutdown(lua_State *L); | ||||
| static int unix_meth_receive(lua_State *L); | ||||
| static int unix_meth_accept(lua_State *L); | ||||
| static int unix_meth_close(lua_State *L); | ||||
| static int unix_meth_setoption(lua_State *L); | ||||
| static int unix_meth_settimeout(lua_State *L); | ||||
| static int unix_meth_getfd(lua_State *L); | ||||
| static int unix_meth_setfd(lua_State *L); | ||||
| static int unix_meth_dirty(lua_State *L); | ||||
| static int unix_meth_getstats(lua_State *L); | ||||
| static int unix_meth_setstats(lua_State *L); | ||||
|  | ||||
| static const char *unix_tryconnect(p_unix un, const char *path); | ||||
| static const char *unix_trybind(p_unix un, const char *path); | ||||
|  | ||||
| /* unix object methods */ | ||||
| static luaL_Reg unix_methods[] = { | ||||
|     {"__gc",        unix_meth_close}, | ||||
|     {"__tostring",  auxiliar_tostring}, | ||||
|     {"accept",      unix_meth_accept}, | ||||
|     {"bind",        unix_meth_bind}, | ||||
|     {"close",       unix_meth_close}, | ||||
|     {"connect",     unix_meth_connect}, | ||||
|     {"dirty",       unix_meth_dirty}, | ||||
|     {"getfd",       unix_meth_getfd}, | ||||
|     {"getstats",    unix_meth_getstats}, | ||||
|     {"setstats",    unix_meth_setstats}, | ||||
|     {"listen",      unix_meth_listen}, | ||||
|     {"receive",     unix_meth_receive}, | ||||
|     {"send",        unix_meth_send}, | ||||
|     {"setfd",       unix_meth_setfd}, | ||||
|     {"setoption",   unix_meth_setoption}, | ||||
|     {"setpeername", unix_meth_connect}, | ||||
|     {"setsockname", unix_meth_bind}, | ||||
|     {"settimeout",  unix_meth_settimeout}, | ||||
|     {"shutdown",    unix_meth_shutdown}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
| /* socket option handlers */ | ||||
| static t_opt unix_optset[] = { | ||||
|     {"keepalive",   opt_set_keepalive}, | ||||
|     {"reuseaddr",   opt_set_reuseaddr}, | ||||
|     {"linger",      opt_set_linger}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
| /* 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 unix_func[] = { | ||||
|     {"unix", unix_global_create}, | ||||
|     {NULL,          NULL} | ||||
| }; | ||||
|  | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int luaopen_socket_unix(lua_State *L) { | ||||
|     /* create classes */ | ||||
|     auxiliar_newclass(L, "unix{master}", unix_methods); | ||||
|     auxiliar_newclass(L, "unix{client}", unix_methods); | ||||
|     auxiliar_newclass(L, "unix{server}", unix_methods); | ||||
|     /* create class groups */ | ||||
|     auxiliar_add2group(L, "unix{master}", "unix{any}"); | ||||
|     auxiliar_add2group(L, "unix{client}", "unix{any}"); | ||||
|     auxiliar_add2group(L, "unix{server}", "unix{any}"); | ||||
| #if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE) | ||||
|     lua_pushcfunction(L, unix_global_create); | ||||
|     (void)unix_func; | ||||
| #else | ||||
|     /* set function into socket namespace */ | ||||
|     luaL_openlib(L, "socket", unix_func, 0); | ||||
|     lua_pushcfunction(L, unix_global_create); | ||||
| #endif | ||||
|     /* return the function instead of the 'socket' table */ | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Lua methods | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call buffered IO methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_meth_send(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); | ||||
|     return buffer_meth_send(L, &un->buf); | ||||
| } | ||||
|  | ||||
| static int unix_meth_receive(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); | ||||
|     return buffer_meth_receive(L, &un->buf); | ||||
| } | ||||
|  | ||||
| static int unix_meth_getstats(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); | ||||
|     return buffer_meth_getstats(L, &un->buf); | ||||
| } | ||||
|  | ||||
| static int unix_meth_setstats(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); | ||||
|     return buffer_meth_setstats(L, &un->buf); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call option handler | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_meth_setoption(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); | ||||
|     return opt_meth_setoption(L, unix_optset, &un->sock); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Select support methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_meth_getfd(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); | ||||
|     lua_pushnumber(L, (int) un->sock); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /* this is very dangerous, but can be handy for those that are brave enough */ | ||||
| static int unix_meth_setfd(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); | ||||
|     un->sock = (t_socket) luaL_checknumber(L, 2);  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static int unix_meth_dirty(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); | ||||
|     lua_pushboolean(L, !buffer_isempty(&un->buf)); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Waits for and returns a client object attempting connection to the  | ||||
| * server object  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_meth_accept(lua_State *L) { | ||||
|     p_unix server = (p_unix) auxiliar_checkclass(L, "unix{server}", 1); | ||||
|     p_timeout tm = timeout_markstart(&server->tm); | ||||
|     t_socket sock; | ||||
|     int err = socket_accept(&server->sock, &sock, NULL, NULL, tm); | ||||
|     /* if successful, push client socket */ | ||||
|     if (err == IO_DONE) { | ||||
|         p_unix clnt = (p_unix) lua_newuserdata(L, sizeof(t_unix)); | ||||
|         auxiliar_setclass(L, "unix{client}", -1); | ||||
|         /* initialize structure fields */ | ||||
|         socket_setnonblocking(&sock); | ||||
|         clnt->sock = sock; | ||||
|         io_init(&clnt->io, (p_send)socket_send, (p_recv)socket_recv,  | ||||
|                 (p_error) socket_ioerror, &clnt->sock); | ||||
|         timeout_init(&clnt->tm, -1, -1); | ||||
|         buffer_init(&clnt->buf, &clnt->io, &clnt->tm); | ||||
|         return 1; | ||||
|     } else { | ||||
|         lua_pushnil(L);  | ||||
|         lua_pushstring(L, socket_strerror(err)); | ||||
|         return 2; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Binds an object to an address  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static const char *unix_trybind(p_unix un, const char *path) { | ||||
| #ifndef _WIN32 | ||||
|     struct sockaddr_un local; | ||||
|     size_t len = strlen(path); | ||||
|     int err; | ||||
|     if (len >= sizeof(local.sun_path)) return "path too long"; | ||||
|     memset(&local, 0, sizeof(local)); | ||||
|     strcpy(local.sun_path, path); | ||||
|     local.sun_family = AF_UNIX; | ||||
| #ifdef UNIX_HAS_SUN_LEN | ||||
|     local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len)  | ||||
|         + len + 1; | ||||
|     err = socket_bind(&un->sock, (SA *) &local, local.sun_len); | ||||
|  | ||||
| #else  | ||||
|     err = socket_bind(&un->sock, (SA *) &local,  | ||||
|             sizeof(local.sun_family) + len); | ||||
| #endif | ||||
|     if (err != IO_DONE) socket_destroy(&un->sock); | ||||
|     return socket_strerror(err);  | ||||
| #else | ||||
| 	return NULL; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static int unix_meth_bind(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); | ||||
|     const char *path =  luaL_checkstring(L, 2); | ||||
|     const char *err = unix_trybind(un, path); | ||||
|     if (err) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Turns a master unix object into a client object. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static const char *unix_tryconnect(p_unix un, const char *path) | ||||
| { | ||||
| #ifndef _WIN32 | ||||
|     struct sockaddr_un remote; | ||||
|     int err; | ||||
|     size_t len = strlen(path); | ||||
|     if (len >= sizeof(remote.sun_path)) return "path too long"; | ||||
|     memset(&remote, 0, sizeof(remote)); | ||||
|     strcpy(remote.sun_path, path); | ||||
|     remote.sun_family = AF_UNIX; | ||||
|     timeout_markstart(&un->tm); | ||||
| #ifdef UNIX_HAS_SUN_LEN | ||||
|     remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len)  | ||||
|         + len + 1; | ||||
|     err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); | ||||
| #else | ||||
|     err = socket_connect(&un->sock, (SA *) &remote,  | ||||
|             sizeof(remote.sun_family) + len, &un->tm); | ||||
| #endif | ||||
|     if (err != IO_DONE) socket_destroy(&un->sock); | ||||
|     return socket_strerror(err); | ||||
| #else | ||||
| 	return NULL; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static int unix_meth_connect(lua_State *L) | ||||
| { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); | ||||
|     const char *path =  luaL_checkstring(L, 2); | ||||
|     const char *err = unix_tryconnect(un, path); | ||||
|     if (err) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, err); | ||||
|         return 2; | ||||
|     } | ||||
|     /* turn master object into a client object */ | ||||
|     auxiliar_setclass(L, "unix{client}", 1); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Closes socket used by object  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_meth_close(lua_State *L) | ||||
| { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); | ||||
|     socket_destroy(&un->sock); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Puts the sockt in listen mode | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_meth_listen(lua_State *L) | ||||
| { | ||||
|     p_unix un = (p_unix) auxiliar_checkclass(L, "unix{master}", 1); | ||||
|     int backlog = (int) luaL_optnumber(L, 2, 32); | ||||
|     int err = socket_listen(&un->sock, backlog); | ||||
|     if (err != IO_DONE) { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_strerror(err)); | ||||
|         return 2; | ||||
|     } | ||||
|     /* turn master object into a server object */ | ||||
|     auxiliar_setclass(L, "unix{server}", 1); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Shuts the connection down partially | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_meth_shutdown(lua_State *L) | ||||
| { | ||||
|     /* SHUT_RD,  SHUT_WR,  SHUT_RDWR  have  the value 0, 1, 2, so we can use method index directly */ | ||||
|     static const char* methods[] = { "receive", "send", "both", NULL }; | ||||
|     p_unix tcp = (p_unix) auxiliar_checkclass(L, "unix{client}", 1); | ||||
|     int how = luaL_checkoption(L, 2, "both", methods); | ||||
|     socket_shutdown(&tcp->sock, how); | ||||
|     lua_pushnumber(L, 1); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Just call tm methods | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_meth_settimeout(lua_State *L) { | ||||
|     p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); | ||||
|     return timeout_meth_settimeout(L, &un->tm); | ||||
| } | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * Library functions | ||||
| \*=========================================================================*/ | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Creates a master unix object  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| static int unix_global_create(lua_State *L) { | ||||
|     t_socket sock; | ||||
|     int err = socket_create(&sock, AF_UNIX, SOCK_STREAM, 0); | ||||
|     /* try to allocate a system socket */ | ||||
|     if (err == IO_DONE) {  | ||||
|         /* allocate unix object */ | ||||
|         p_unix un = (p_unix) lua_newuserdata(L, sizeof(t_unix)); | ||||
|         /* set its type as master object */ | ||||
|         auxiliar_setclass(L, "unix{master}", -1); | ||||
|         /* initialize remaining structure fields */ | ||||
|         socket_setnonblocking(&sock); | ||||
|         un->sock = sock; | ||||
|         io_init(&un->io, (p_send) socket_send, (p_recv) socket_recv,  | ||||
|                 (p_error) socket_ioerror, &un->sock); | ||||
|         timeout_init(&un->tm, -1, -1); | ||||
|         buffer_init(&un->buf, &un->io, &un->tm); | ||||
|         return 1; | ||||
|     } else { | ||||
|         lua_pushnil(L); | ||||
|         lua_pushstring(L, socket_strerror(err)); | ||||
|         return 2; | ||||
|     } | ||||
| } | ||||
|  | ||||
| } // end NS_SLUA | ||||
							
								
								
									
										34
									
								
								Plugins/slua_unreal/External/luasocket/unix.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Plugins/slua_unreal/External/luasocket/unix.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| #ifndef UNIX_H | ||||
| #define UNIX_H | ||||
| /*=========================================================================*\ | ||||
| * Unix domain object | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * This module is just an example of how to extend LuaSocket with a new  | ||||
| * domain. | ||||
| \*=========================================================================*/ | ||||
| #include "lua.h" | ||||
|  | ||||
| #include "buffer.h" | ||||
| #include "timeout.h" | ||||
| #include "socket.h" | ||||
|  | ||||
| #ifndef UNIX_API | ||||
| #define UNIX_API extern | ||||
| #endif | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| typedef struct t_unix_ { | ||||
|     t_socket sock; | ||||
|     t_io io; | ||||
|     t_buffer buf; | ||||
|     t_timeout tm; | ||||
| } t_unix; | ||||
| typedef t_unix *p_unix; | ||||
|  | ||||
| UNIX_API int luaopen_socket_unix(lua_State *L); | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* UNIX_H */ | ||||
							
								
								
									
										309
									
								
								Plugins/slua_unreal/External/luasocket/url.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								Plugins/slua_unreal/External/luasocket/url.lua.inc
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,309 @@ | ||||
| R"-++**++-( | ||||
| ----------------------------------------------------------------------------- | ||||
| -- URI parsing, composition and relative URL resolution | ||||
| -- LuaSocket toolkit. | ||||
| -- Author: Diego Nehab | ||||
| ----------------------------------------------------------------------------- | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Declare module | ||||
| ----------------------------------------------------------------------------- | ||||
| local string = require("string") | ||||
| local base = _G | ||||
| local table = require("table") | ||||
| local socket = require("socket") | ||||
|  | ||||
| socket.url = {} | ||||
| local _M = socket.url | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Module version | ||||
| ----------------------------------------------------------------------------- | ||||
| _M._VERSION = "URL 1.0.3" | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Encodes a string into its escaped hexadecimal representation | ||||
| -- Input | ||||
| --   s: binary string to be encoded | ||||
| -- Returns | ||||
| --   escaped representation of string binary | ||||
| ----------------------------------------------------------------------------- | ||||
| function _M.escape(s) | ||||
|     return (string.gsub(s, "([^A-Za-z0-9_])", function(c) | ||||
|         return string.format("%%%02x", string.byte(c)) | ||||
|     end)) | ||||
| end | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Protects a path segment, to prevent it from interfering with the | ||||
| -- url parsing. | ||||
| -- Input | ||||
| --   s: binary string to be encoded | ||||
| -- Returns | ||||
| --   escaped representation of string binary | ||||
| ----------------------------------------------------------------------------- | ||||
| local function make_set(t) | ||||
|     local s = {} | ||||
|     for i,v in base.ipairs(t) do | ||||
|         s[t[i]] = 1 | ||||
|     end | ||||
|     return s | ||||
| end | ||||
|  | ||||
| -- these are allowed withing a path segment, along with alphanum | ||||
| -- other characters must be escaped | ||||
| local segment_set = make_set { | ||||
|     "-", "_", ".", "!", "~", "*", "'", "(", | ||||
|     ")", ":", "@", "&", "=", "+", "$", ",", | ||||
| } | ||||
|  | ||||
| local function protect_segment(s) | ||||
|     return string.gsub(s, "([^A-Za-z0-9_])", function (c) | ||||
|         if segment_set[c] then return c | ||||
|         else return string.format("%%%02x", string.byte(c)) end | ||||
|     end) | ||||
| end | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Encodes a string into its escaped hexadecimal representation | ||||
| -- Input | ||||
| --   s: binary string to be encoded | ||||
| -- Returns | ||||
| --   escaped representation of string binary | ||||
| ----------------------------------------------------------------------------- | ||||
| function _M.unescape(s) | ||||
|     return (string.gsub(s, "%%(%x%x)", function(hex) | ||||
|         return string.char(base.tonumber(hex, 16)) | ||||
|     end)) | ||||
| end | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Builds a path from a base path and a relative path | ||||
| -- Input | ||||
| --   base_path | ||||
| --   relative_path | ||||
| -- Returns | ||||
| --   corresponding absolute path | ||||
| ----------------------------------------------------------------------------- | ||||
| local function absolute_path(base_path, relative_path) | ||||
|     if string.sub(relative_path, 1, 1) == "/" then return relative_path end | ||||
|     local path = string.gsub(base_path, "[^/]*$", "") | ||||
|     path = path .. relative_path | ||||
|     path = string.gsub(path, "([^/]*%./)", function (s) | ||||
|         if s ~= "./" then return s else return "" end | ||||
|     end) | ||||
|     path = string.gsub(path, "/%.$", "/") | ||||
|     local reduced | ||||
|     while reduced ~= path do | ||||
|         reduced = path | ||||
|         path = string.gsub(reduced, "([^/]*/%.%./)", function (s) | ||||
|             if s ~= "../../" then return "" else return s end | ||||
|         end) | ||||
|     end | ||||
|     path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) | ||||
|         if s ~= "../.." then return "" else return s end | ||||
|     end) | ||||
|     return path | ||||
| end | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Parses a url and returns a table with all its parts according to RFC 2396 | ||||
| -- The following grammar describes the names given to the URL parts | ||||
| -- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment> | ||||
| -- <authority> ::= <userinfo>@<host>:<port> | ||||
| -- <userinfo> ::= <user>[:<password>] | ||||
| -- <path> :: = {<segment>/}<segment> | ||||
| -- Input | ||||
| --   url: uniform resource locator of request | ||||
| --   default: table with default values for each field | ||||
| -- Returns | ||||
| --   table with the following fields, where RFC naming conventions have | ||||
| --   been preserved: | ||||
| --     scheme, authority, userinfo, user, password, host, port, | ||||
| --     path, params, query, fragment | ||||
| -- Obs: | ||||
| --   the leading '/' in {/<path>} is considered part of <path> | ||||
| ----------------------------------------------------------------------------- | ||||
| function _M.parse(url, default) | ||||
|     -- initialize default parameters | ||||
|     local parsed = {} | ||||
|     for i,v in base.pairs(default or parsed) do parsed[i] = v end | ||||
|     -- empty url is parsed to nil | ||||
|     if not url or url == "" then return nil, "invalid url" end | ||||
|     -- remove whitespace | ||||
|     -- url = string.gsub(url, "%s", "") | ||||
|     -- get fragment | ||||
|     url = string.gsub(url, "#(.*)$", function(f) | ||||
|         parsed.fragment = f | ||||
|         return "" | ||||
|     end) | ||||
|     -- get scheme | ||||
|     url = string.gsub(url, "^([%w][%w%+%-%.]*)%:", | ||||
|         function(s) parsed.scheme = s; return "" end) | ||||
|     -- get authority | ||||
|     url = string.gsub(url, "^//([^/]*)", function(n) | ||||
|         parsed.authority = n | ||||
|         return "" | ||||
|     end) | ||||
|     -- get query string | ||||
|     url = string.gsub(url, "%?(.*)", function(q) | ||||
|         parsed.query = q | ||||
|         return "" | ||||
|     end) | ||||
|     -- get params | ||||
|     url = string.gsub(url, "%;(.*)", function(p) | ||||
|         parsed.params = p | ||||
|         return "" | ||||
|     end) | ||||
|     -- path is whatever was left | ||||
|     if url ~= "" then parsed.path = url end | ||||
|     local authority = parsed.authority | ||||
|     if not authority then return parsed end | ||||
|     authority = string.gsub(authority,"^([^@]*)@", | ||||
|         function(u) parsed.userinfo = u; return "" end) | ||||
|     authority = string.gsub(authority, ":([^:%]]*)$", | ||||
|         function(p) parsed.port = p; return "" end) | ||||
|     if authority ~= "" then  | ||||
|         -- IPv6? | ||||
|         parsed.host = string.match(authority, "^%[(.+)%]$") or authority  | ||||
|     end | ||||
|     local userinfo = parsed.userinfo | ||||
|     if not userinfo then return parsed end | ||||
|     userinfo = string.gsub(userinfo, ":([^:]*)$", | ||||
|         function(p) parsed.password = p; return "" end) | ||||
|     parsed.user = userinfo | ||||
|     return parsed | ||||
| end | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Rebuilds a parsed URL from its components. | ||||
| -- Components are protected if any reserved or unallowed characters are found | ||||
| -- Input | ||||
| --   parsed: parsed URL, as returned by parse | ||||
| -- Returns | ||||
| --   a stringing with the corresponding URL | ||||
| ----------------------------------------------------------------------------- | ||||
| function _M.build(parsed) | ||||
|     local ppath = _M.parse_path(parsed.path or "") | ||||
|     local url = _M.build_path(ppath) | ||||
|     if parsed.params then url = url .. ";" .. parsed.params end | ||||
|     if parsed.query then url = url .. "?" .. parsed.query end | ||||
|     local authority = parsed.authority | ||||
|     if parsed.host then | ||||
|         authority = parsed.host | ||||
|         if string.find(authority, ":") then -- IPv6? | ||||
|             authority = "[" .. authority .. "]" | ||||
|         end | ||||
|         if parsed.port then authority = authority .. ":" .. parsed.port end | ||||
|         local userinfo = parsed.userinfo | ||||
|         if parsed.user then | ||||
|             userinfo = parsed.user | ||||
|             if parsed.password then | ||||
|                 userinfo = userinfo .. ":" .. parsed.password | ||||
|             end | ||||
|         end | ||||
|         if userinfo then authority = userinfo .. "@" .. authority end | ||||
|     end | ||||
|     if authority then url = "//" .. authority .. url end | ||||
|     if parsed.scheme then url = parsed.scheme .. ":" .. url end | ||||
|     if parsed.fragment then url = url .. "#" .. parsed.fragment end | ||||
|     -- url = string.gsub(url, "%s", "") | ||||
|     return url | ||||
| end | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Builds a absolute URL from a base and a relative URL according to RFC 2396 | ||||
| -- Input | ||||
| --   base_url | ||||
| --   relative_url | ||||
| -- Returns | ||||
| --   corresponding absolute url | ||||
| ----------------------------------------------------------------------------- | ||||
| function _M.absolute(base_url, relative_url) | ||||
|     if base.type(base_url) == "table" then | ||||
|         base_parsed = base_url | ||||
|         base_url = _M.build(base_parsed) | ||||
|     else | ||||
|         base_parsed = _M.parse(base_url) | ||||
|     end | ||||
|     local relative_parsed = _M.parse(relative_url) | ||||
|     if not base_parsed then return relative_url | ||||
|     elseif not relative_parsed then return base_url | ||||
|     elseif relative_parsed.scheme then return relative_url | ||||
|     else | ||||
|         relative_parsed.scheme = base_parsed.scheme | ||||
|         if not relative_parsed.authority then | ||||
|             relative_parsed.authority = base_parsed.authority | ||||
|             if not relative_parsed.path then | ||||
|                 relative_parsed.path = base_parsed.path | ||||
|                 if not relative_parsed.params then | ||||
|                     relative_parsed.params = base_parsed.params | ||||
|                     if not relative_parsed.query then | ||||
|                         relative_parsed.query = base_parsed.query | ||||
|                     end | ||||
|                 end | ||||
|             else     | ||||
|                 relative_parsed.path = absolute_path(base_parsed.path or "", | ||||
|                     relative_parsed.path) | ||||
|             end | ||||
|         end | ||||
|         return _M.build(relative_parsed) | ||||
|     end | ||||
| end | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Breaks a path into its segments, unescaping the segments | ||||
| -- Input | ||||
| --   path | ||||
| -- Returns | ||||
| --   segment: a table with one entry per segment | ||||
| ----------------------------------------------------------------------------- | ||||
| function _M.parse_path(path) | ||||
|     local parsed = {} | ||||
|     path = path or "" | ||||
|     --path = string.gsub(path, "%s", "") | ||||
|     string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) | ||||
|     for i = 1, #parsed do | ||||
|         parsed[i] = _M.unescape(parsed[i]) | ||||
|     end | ||||
|     if string.sub(path, 1, 1) == "/" then parsed.is_absolute = 1 end | ||||
|     if string.sub(path, -1, -1) == "/" then parsed.is_directory = 1 end | ||||
|     return parsed | ||||
| end | ||||
|  | ||||
| ----------------------------------------------------------------------------- | ||||
| -- Builds a path component from its segments, escaping protected characters. | ||||
| -- Input | ||||
| --   parsed: path segments | ||||
| --   unsafe: if true, segments are not protected before path is built | ||||
| -- Returns | ||||
| --   path: corresponding path stringing | ||||
| ----------------------------------------------------------------------------- | ||||
| function _M.build_path(parsed, unsafe) | ||||
|     local path = "" | ||||
|     local n = #parsed | ||||
|     if unsafe then | ||||
|         for i = 1, n-1 do | ||||
|             path = path .. parsed[i] | ||||
|             path = path .. "/" | ||||
|         end | ||||
|         if n > 0 then | ||||
|             path = path .. parsed[n] | ||||
|             if parsed.is_directory then path = path .. "/" end | ||||
|         end | ||||
|     else | ||||
|         for i = 1, n-1 do | ||||
|             path = path .. protect_segment(parsed[i]) | ||||
|             path = path .. "/" | ||||
|         end | ||||
|         if n > 0 then | ||||
|             path = path .. protect_segment(parsed[n]) | ||||
|             if parsed.is_directory then path = path .. "/" end | ||||
|         end | ||||
|     end | ||||
|     if parsed.is_absolute then path = "/" .. path end | ||||
|     return path | ||||
| end | ||||
|  | ||||
| return _M | ||||
| )-++**++-"; | ||||
							
								
								
									
										457
									
								
								Plugins/slua_unreal/External/luasocket/usocket.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										457
									
								
								Plugins/slua_unreal/External/luasocket/usocket.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,457 @@ | ||||
| /*=========================================================================*\ | ||||
| * Socket compatibilization module for Unix | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * The code is now interrupt-safe. | ||||
| * The penalty of calling select to avoid busy-wait is only paid when | ||||
| * the I/O call fail in the first place.  | ||||
| \*=========================================================================*/ | ||||
| #include <string.h>  | ||||
| #include <signal.h> | ||||
|  | ||||
| #include "socket.h" | ||||
|  | ||||
| #ifndef _WIN32 | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Wait for readable/writable/connected socket with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #ifndef SOCKET_SELECT | ||||
| #include <sys/poll.h> | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| #define WAITFD_R        POLLIN | ||||
| #define WAITFD_W        POLLOUT | ||||
| #define WAITFD_C        (POLLIN|POLLOUT) | ||||
| int socket_waitfd(p_socket ps, int sw, p_timeout tm) { | ||||
|     int ret; | ||||
|     struct pollfd pfd; | ||||
|     pfd.fd = *ps; | ||||
|     pfd.events = sw; | ||||
|     pfd.revents = 0; | ||||
|     if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */ | ||||
|     do { | ||||
|         int t = (int)(timeout_getretry(tm)*1e3); | ||||
|         ret = poll(&pfd, 1, t >= 0? t: -1); | ||||
|     } while (ret == -1 && errno == EINTR); | ||||
|     if (ret == -1) return errno; | ||||
|     if (ret == 0) return IO_TIMEOUT; | ||||
|     if (sw == WAITFD_C && (pfd.revents & (POLLIN|POLLERR))) return IO_CLOSED; | ||||
|     return IO_DONE; | ||||
| } | ||||
| #else | ||||
|  | ||||
| #define WAITFD_R        1 | ||||
| #define WAITFD_W        2 | ||||
| #define WAITFD_C        (WAITFD_R|WAITFD_W) | ||||
|  | ||||
| int socket_waitfd(p_socket ps, int sw, p_timeout tm) { | ||||
|     int ret; | ||||
|     fd_set rfds, wfds, *rp, *wp; | ||||
|     struct timeval tv, *tp; | ||||
|     double t; | ||||
|     if (*ps >= FD_SETSIZE) return EINVAL; | ||||
|     if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */ | ||||
|     do { | ||||
|         /* must set bits within loop, because select may have modifed them */ | ||||
|         rp = wp = NULL; | ||||
|         if (sw & WAITFD_R) { FD_ZERO(&rfds); FD_SET(*ps, &rfds); rp = &rfds; } | ||||
|         if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } | ||||
|         t = timeout_getretry(tm); | ||||
|         tp = NULL; | ||||
|         if (t >= 0.0) { | ||||
|             tv.tv_sec = (int)t; | ||||
|             tv.tv_usec = (int)((t-tv.tv_sec)*1.0e6); | ||||
|             tp = &tv; | ||||
|         } | ||||
|         ret = select(*ps+1, rp, wp, NULL, tp); | ||||
|     } while (ret == -1 && errno == EINTR); | ||||
|     if (ret == -1) return errno; | ||||
|     if (ret == 0) return IO_TIMEOUT; | ||||
|     if (sw == WAITFD_C && FD_ISSET(*ps, &rfds)) return IO_CLOSED; | ||||
|     return IO_DONE; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_open(void) { | ||||
|     /* instals a handler to ignore sigpipe or it will crash us */ | ||||
|     signal(SIGPIPE, SIG_IGN); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Close module  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_close(void) { | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Close and inutilize socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void socket_destroy(p_socket ps) { | ||||
|     if (*ps != SOCKET_INVALID) { | ||||
|         socket_setblocking(ps); | ||||
|         close(*ps); | ||||
|         *ps = SOCKET_INVALID; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Select with timeout control | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,  | ||||
|         p_timeout tm) { | ||||
|     int ret; | ||||
|     do { | ||||
|         struct timeval tv; | ||||
|         double t = timeout_getretry(tm); | ||||
|         tv.tv_sec = (int) t; | ||||
|         tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); | ||||
|         /* timeout = 0 means no wait */ | ||||
|         ret = select(n, rfds, wfds, efds, t >= 0.0 ? &tv: NULL); | ||||
|     } while (ret < 0 && errno == EINTR); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Creates and sets up a socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_create(p_socket ps, int domain, int type, int protocol) { | ||||
|     *ps = socket(domain, type, protocol); | ||||
|     if (*ps != SOCKET_INVALID) return IO_DONE;  | ||||
|     else return errno;  | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Binds or returns error message | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_bind(p_socket ps, SA *addr, socklen_t len) { | ||||
|     int err = IO_DONE; | ||||
|     socket_setblocking(ps); | ||||
|     if (bind(*ps, addr, len) < 0) err = errno;  | ||||
|     socket_setnonblocking(ps); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| *  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_listen(p_socket ps, int backlog) { | ||||
|     int err = IO_DONE;  | ||||
|     socket_setblocking(ps); | ||||
|     if (listen(*ps, backlog)) err = errno;  | ||||
|     socket_setnonblocking(ps); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| *  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void socket_shutdown(p_socket ps, int how) { | ||||
|     socket_setblocking(ps); | ||||
|     shutdown(*ps, how); | ||||
|     socket_setnonblocking(ps); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Connects or returns error message | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { | ||||
|     int err; | ||||
|     /* avoid calling on closed sockets */ | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     /* call connect until done or failed without being interrupted */ | ||||
|     do if (connect(*ps, addr, len) == 0) return IO_DONE; | ||||
|     while ((err = errno) == EINTR); | ||||
|     /* if connection failed immediately, return error code */ | ||||
|     if (err != EINPROGRESS && err != EAGAIN) return err;  | ||||
|     /* zero timeout case optimization */ | ||||
|     if (timeout_iszero(tm)) return IO_TIMEOUT; | ||||
|     /* wait until we have the result of the connection attempt or timeout */ | ||||
|     err = socket_waitfd(ps, WAITFD_C, tm); | ||||
|     if (err == IO_CLOSED) { | ||||
|         if (recv(*ps, (char *) &err, 0, 0) == 0) return IO_DONE; | ||||
|         else return errno; | ||||
|     } else return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Accept with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len, p_timeout tm) { | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED;  | ||||
|     for ( ;; ) { | ||||
|         int err; | ||||
|         if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; | ||||
|         err = errno; | ||||
|         if (err == EINTR) continue; | ||||
|         if (err != EAGAIN && err != ECONNABORTED) return err; | ||||
|         if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; | ||||
|     } | ||||
|     /* can't reach here */ | ||||
|     return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Send with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_send(p_socket ps, const char *data, size_t count,  | ||||
|         size_t *sent, p_timeout tm) | ||||
| { | ||||
|     int err; | ||||
|     *sent = 0; | ||||
|     /* avoid making system calls on closed sockets */ | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     /* loop until we send something or we give up on error */ | ||||
|     for ( ;; ) { | ||||
|         long put = (long) send(*ps, data, count, 0); | ||||
|         /* if we sent anything, we are done */ | ||||
|         if (put >= 0) { | ||||
|             *sent = put; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         err = errno; | ||||
|         /* EPIPE means the connection was closed */ | ||||
|         if (err == EPIPE) return IO_CLOSED; | ||||
|         /* we call was interrupted, just try again */ | ||||
|         if (err == EINTR) continue; | ||||
|         /* if failed fatal reason, report error */ | ||||
|         if (err != EAGAIN) return err; | ||||
|         /* wait until we can send something or we timeout */ | ||||
|         if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; | ||||
|     } | ||||
|     /* can't reach here */ | ||||
|     return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Sendto with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,  | ||||
|         SA *addr, socklen_t len, p_timeout tm) | ||||
| { | ||||
|     int err; | ||||
|     *sent = 0; | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     for ( ;; ) { | ||||
|         long put = (long) sendto(*ps, data, count, 0, addr, len);   | ||||
|         if (put >= 0) { | ||||
|             *sent = put; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         err = errno; | ||||
|         if (err == EPIPE) return IO_CLOSED; | ||||
|         if (err == EINTR) continue; | ||||
|         if (err != EAGAIN) return err; | ||||
|         if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; | ||||
|     } | ||||
|     return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Receive with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_recv(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { | ||||
|     int err; | ||||
|     *got = 0; | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     for ( ;; ) { | ||||
|         long taken = (long) recv(*ps, data, count, 0); | ||||
|         if (taken > 0) { | ||||
|             *got = taken; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         err = errno; | ||||
|         if (taken == 0) return IO_CLOSED; | ||||
|         if (err == EINTR) continue; | ||||
|         if (err != EAGAIN) return err;  | ||||
|         if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;  | ||||
|     } | ||||
|     return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * 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; | ||||
|     *got = 0; | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     for ( ;; ) { | ||||
|         long taken = (long) recvfrom(*ps, data, count, 0, addr, len); | ||||
|         if (taken > 0) { | ||||
|             *got = taken; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         err = errno; | ||||
|         if (taken == 0) return IO_CLOSED; | ||||
|         if (err == EINTR) continue; | ||||
|         if (err != EAGAIN) return err;  | ||||
|         if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;  | ||||
|     } | ||||
|     return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Write with timeout | ||||
| * | ||||
| * socket_read and socket_write are cut-n-paste of socket_send and socket_recv, | ||||
| * with send/recv replaced with write/read. We can't just use write/read | ||||
| * in the socket version, because behaviour when size is zero is different. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_write(p_socket ps, const char *data, size_t count,  | ||||
|         size_t *sent, p_timeout tm) | ||||
| { | ||||
|     int err; | ||||
|     *sent = 0; | ||||
|     /* avoid making system calls on closed sockets */ | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     /* loop until we send something or we give up on error */ | ||||
|     for ( ;; ) { | ||||
|         long put = (long) write(*ps, data, count); | ||||
|         /* if we sent anything, we are done */ | ||||
|         if (put >= 0) { | ||||
|             *sent = put; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         err = errno; | ||||
|         /* EPIPE means the connection was closed */ | ||||
|         if (err == EPIPE) return IO_CLOSED; | ||||
|         /* we call was interrupted, just try again */ | ||||
|         if (err == EINTR) continue; | ||||
|         /* if failed fatal reason, report error */ | ||||
|         if (err != EAGAIN) return err; | ||||
|         /* wait until we can send something or we timeout */ | ||||
|         if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; | ||||
|     } | ||||
|     /* can't reach here */ | ||||
|     return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Read with timeout | ||||
| * See note for socket_write | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_read(p_socket ps, char *data, size_t count, size_t *got, p_timeout tm) { | ||||
|     int err; | ||||
|     *got = 0; | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     for ( ;; ) { | ||||
|         long taken = (long) read(*ps, data, count); | ||||
|         if (taken > 0) { | ||||
|             *got = taken; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         err = errno; | ||||
|         if (taken == 0) return IO_CLOSED; | ||||
|         if (err == EINTR) continue; | ||||
|         if (err != EAGAIN) return err;  | ||||
|         if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err;  | ||||
|     } | ||||
|     return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Put socket into blocking mode | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void socket_setblocking(p_socket ps) { | ||||
|     int flags = fcntl(*ps, F_GETFL, 0); | ||||
|     flags &= (~(O_NONBLOCK)); | ||||
|     fcntl(*ps, F_SETFL, flags); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Put socket into non-blocking mode | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void socket_setnonblocking(p_socket ps) { | ||||
|     int flags = fcntl(*ps, F_GETFL, 0); | ||||
|     flags |= O_NONBLOCK; | ||||
|     fcntl(*ps, F_SETFL, flags); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * DNS helpers  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { | ||||
|     *hp = gethostbyaddr(addr, len, AF_INET); | ||||
|     if (*hp) return IO_DONE; | ||||
|     else if (h_errno) return h_errno; | ||||
|     else if (errno) return errno; | ||||
|     else return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
| int socket_gethostbyname(const char *addr, struct hostent **hp) { | ||||
|     *hp = gethostbyname(addr); | ||||
|     if (*hp) return IO_DONE; | ||||
|     else if (h_errno) return h_errno; | ||||
|     else if (errno) return errno; | ||||
|     else return IO_UNKNOWN; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Error translation functions | ||||
| * Make sure important error messages are standard | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *socket_hoststrerror(int err) { | ||||
|     if (err <= 0) return io_strerror(err); | ||||
|     switch (err) { | ||||
|         case HOST_NOT_FOUND: return "host not found"; | ||||
|         default: return hstrerror(err); | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *socket_strerror(int err) { | ||||
|     if (err <= 0) return io_strerror(err); | ||||
|     switch (err) { | ||||
|         case EADDRINUSE: return "address already in use"; | ||||
|         case EISCONN: return "already connected"; | ||||
|         case EACCES: return "permission denied"; | ||||
|         case ECONNREFUSED: return "connection refused"; | ||||
|         case ECONNABORTED: return "closed"; | ||||
|         case ECONNRESET: return "closed"; | ||||
|         case ETIMEDOUT: return "timeout"; | ||||
|         default: return strerror(err); | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *socket_ioerror(p_socket ps, int err) { | ||||
|     (void) ps; | ||||
|     return socket_strerror(err); | ||||
| }  | ||||
|  | ||||
| const char *socket_gaistrerror(int err) { | ||||
|     if (err == 0) return NULL;  | ||||
|     switch (err) { | ||||
|         case EAI_AGAIN: return "temporary failure in name resolution"; | ||||
|         case EAI_BADFLAGS: return "invalid value for ai_flags"; | ||||
| #ifdef EAI_BADHINTS | ||||
|         case EAI_BADHINTS: return "invalid value for hints"; | ||||
| #endif | ||||
|         case EAI_FAIL: return "non-recoverable failure in name resolution"; | ||||
|         case EAI_FAMILY: return "ai_family not supported"; | ||||
|         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_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_strerror(err); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif // _WIN32 | ||||
							
								
								
									
										63
									
								
								Plugins/slua_unreal/External/luasocket/usocket.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Plugins/slua_unreal/External/luasocket/usocket.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| #ifndef USOCKET_H | ||||
| #define USOCKET_H | ||||
| /*=========================================================================*\ | ||||
| * Socket compatibilization module for Unix | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * BSD include files | ||||
| \*=========================================================================*/ | ||||
| /* error codes */ | ||||
| #include <errno.h> | ||||
| /* close function */ | ||||
| #include <unistd.h> | ||||
| /* fnctnl function and associated constants */ | ||||
| #include <fcntl.h> | ||||
| /* struct sockaddr */ | ||||
| #include <sys/types.h> | ||||
| /* socket function */ | ||||
| #include <sys/socket.h> | ||||
| /* struct timeval */ | ||||
| #include <sys/time.h> | ||||
| /* gethostbyname and gethostbyaddr functions */ | ||||
| #include <netdb.h> | ||||
| /* sigpipe handling */ | ||||
| #include <signal.h> | ||||
| /* IP stuff*/ | ||||
| #include <netinet/in.h> | ||||
| #include <arpa/inet.h> | ||||
| /* TCP options (nagle algorithm disable) */ | ||||
| #include <netinet/tcp.h> | ||||
| #include <net/if.h> | ||||
|  | ||||
| #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 */ | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| typedef int t_socket; | ||||
| typedef t_socket *p_socket; | ||||
| typedef struct sockaddr_storage t_sockaddr_storage; | ||||
|  | ||||
| #define SOCKET_INVALID (-1) | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif /* USOCKET_H */ | ||||
							
								
								
									
										442
									
								
								Plugins/slua_unreal/External/luasocket/wsocket.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										442
									
								
								Plugins/slua_unreal/External/luasocket/wsocket.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,442 @@ | ||||
| /*=========================================================================*\ | ||||
| * Socket compatibilization module for Win32 | ||||
| * LuaSocket toolkit | ||||
| * | ||||
| * The penalty of calling select to avoid busy-wait is only paid when | ||||
| * the I/O call fail in the first place.  | ||||
| \*=========================================================================*/ | ||||
| #include <string.h> | ||||
|  | ||||
| #include "socket.h" | ||||
|  | ||||
| #ifdef _WIN32 | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| /* WinSock doesn't have a strerror... */ | ||||
| static const char *wstrerror(int err); | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Initializes module  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_open(void) { | ||||
|     WSADATA wsaData; | ||||
|     WORD wVersionRequested = MAKEWORD(2, 0);  | ||||
|     int err = WSAStartup(wVersionRequested, &wsaData ); | ||||
|     if (err != 0) return 0; | ||||
|     if ((LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) && | ||||
|         (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)) { | ||||
|         WSACleanup(); | ||||
|         return 0;  | ||||
|     } | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Close module  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_close(void) { | ||||
|     WSACleanup(); | ||||
|     return 1; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Wait for readable/writable/connected socket with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| #define WAITFD_R        1 | ||||
| #define WAITFD_W        2 | ||||
| #define WAITFD_E        4 | ||||
| #define WAITFD_C        (WAITFD_E|WAITFD_W) | ||||
|  | ||||
| int socket_waitfd(p_socket ps, int sw, p_timeout tm) { | ||||
|     int ret; | ||||
|     fd_set rfds, wfds, efds, *rp = NULL, *wp = NULL, *ep = NULL; | ||||
|     struct timeval tv, *tp = NULL; | ||||
|     double t; | ||||
|     if (timeout_iszero(tm)) return IO_TIMEOUT;  /* optimize timeout == 0 case */ | ||||
|     if (sw & WAITFD_R) {  | ||||
|         FD_ZERO(&rfds);  | ||||
|         FD_SET(*ps, &rfds); | ||||
|         rp = &rfds;  | ||||
|     } | ||||
|     if (sw & WAITFD_W) { FD_ZERO(&wfds); FD_SET(*ps, &wfds); wp = &wfds; } | ||||
|     if (sw & WAITFD_C) { FD_ZERO(&efds); FD_SET(*ps, &efds); ep = &efds; } | ||||
|     if ((t = timeout_get(tm)) >= 0.0) { | ||||
|         tv.tv_sec = (int) t; | ||||
|         tv.tv_usec = (int) ((t-tv.tv_sec)*1.0e6); | ||||
|         tp = &tv; | ||||
|     } | ||||
|     ret = select(0, rp, wp, ep, tp); | ||||
|     if (ret == -1) return WSAGetLastError(); | ||||
|     if (ret == 0) return IO_TIMEOUT; | ||||
|     if (sw == WAITFD_C && FD_ISSET(*ps, &efds)) return IO_CLOSED; | ||||
|     return IO_DONE; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Select with int timeout in ms | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_select(t_socket n, fd_set *rfds, fd_set *wfds, fd_set *efds,  | ||||
|         p_timeout tm) { | ||||
|     struct timeval tv;  | ||||
|     double t = timeout_get(tm); | ||||
|     tv.tv_sec = (int) t; | ||||
|     tv.tv_usec = (int) ((t - tv.tv_sec) * 1.0e6); | ||||
|     if (n <= 0) { | ||||
|         Sleep((DWORD) (1000*t)); | ||||
|         return 0; | ||||
|     } else return select(0, rfds, wfds, efds, t >= 0.0? &tv: NULL); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Close and inutilize socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void socket_destroy(p_socket ps) { | ||||
|     if (*ps != SOCKET_INVALID) { | ||||
|         socket_setblocking(ps); /* close can take a long time on WIN32 */ | ||||
|         closesocket(*ps); | ||||
|         *ps = SOCKET_INVALID; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| *  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void socket_shutdown(p_socket ps, int how) { | ||||
|     socket_setblocking(ps); | ||||
|     shutdown(*ps, how); | ||||
|     socket_setnonblocking(ps); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Creates and sets up a socket | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_create(p_socket ps, int domain, int type, int protocol) { | ||||
|     *ps = socket(domain, type, protocol); | ||||
|     if (*ps != SOCKET_INVALID) return IO_DONE; | ||||
|     else return WSAGetLastError(); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Connects or returns error message | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_connect(p_socket ps, SA *addr, socklen_t len, p_timeout tm) { | ||||
|     int err; | ||||
|     /* don't call on closed socket */ | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     /* ask system to connect */ | ||||
|     if (connect(*ps, addr, len) == 0) return IO_DONE; | ||||
|     /* make sure the system is trying to connect */ | ||||
|     err = WSAGetLastError(); | ||||
|     if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) return err; | ||||
|     /* zero timeout case optimization */ | ||||
|     if (timeout_iszero(tm)) return IO_TIMEOUT; | ||||
|     /* we wait until something happens */ | ||||
|     err = socket_waitfd(ps, WAITFD_C, tm); | ||||
|     if (err == IO_CLOSED) { | ||||
|         int len = sizeof(err); | ||||
|         /* give windows time to set the error (yes, disgusting) */ | ||||
|         Sleep(10); | ||||
|         /* find out why we failed */ | ||||
|         getsockopt(*ps, SOL_SOCKET, SO_ERROR, (char *)&err, &len);  | ||||
|         /* we KNOW there was an error. if 'why' is 0, we will return | ||||
|         * "unknown error", but it's not really our fault */ | ||||
|         return err > 0? err: IO_UNKNOWN;  | ||||
|     } else return err; | ||||
|  | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Binds or returns error message | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_bind(p_socket ps, SA *addr, socklen_t len) { | ||||
|     int err = IO_DONE; | ||||
|     socket_setblocking(ps); | ||||
|     if (bind(*ps, addr, len) < 0) err = WSAGetLastError(); | ||||
|     socket_setnonblocking(ps); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| *  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_listen(p_socket ps, int backlog) { | ||||
|     int err = IO_DONE; | ||||
|     socket_setblocking(ps); | ||||
|     if (listen(*ps, backlog) < 0) err = WSAGetLastError(); | ||||
|     socket_setnonblocking(ps); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Accept with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_accept(p_socket ps, p_socket pa, SA *addr, socklen_t *len,  | ||||
|         p_timeout tm) { | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     for ( ;; ) { | ||||
|         int err; | ||||
|         /* try to get client socket */ | ||||
|         if ((*pa = accept(*ps, addr, len)) != SOCKET_INVALID) return IO_DONE; | ||||
|         /* find out why we failed */ | ||||
|         err = WSAGetLastError();  | ||||
|         /* if we failed because there was no connectoin, keep trying */ | ||||
|         if (err != WSAEWOULDBLOCK && err != WSAECONNABORTED) return err; | ||||
|         /* call select to avoid busy wait */ | ||||
|         if ((err = socket_waitfd(ps, WAITFD_R, tm)) != IO_DONE) return err; | ||||
|     }  | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Send with timeout | ||||
| * On windows, if you try to send 10MB, the OS will buffer EVERYTHING  | ||||
| * this can take an awful lot of time and we will end up blocked.  | ||||
| * Therefore, whoever calls this function should not pass a huge buffer. | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_send(p_socket ps, const char *data, size_t count,  | ||||
|         size_t *sent, p_timeout tm) | ||||
| { | ||||
|     int err; | ||||
|     *sent = 0; | ||||
|     /* avoid making system calls on closed sockets */ | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     /* loop until we send something or we give up on error */ | ||||
|     for ( ;; ) { | ||||
|         /* try to send something */ | ||||
|         int put = send(*ps, data, (int) count, 0); | ||||
|         /* if we sent something, we are done */ | ||||
|         if (put > 0) { | ||||
|             *sent = put; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         /* deal with failure */ | ||||
|         err = WSAGetLastError();  | ||||
|         /* we can only proceed if there was no serious error */ | ||||
|         if (err != WSAEWOULDBLOCK) return err; | ||||
|         /* avoid busy wait */ | ||||
|         if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; | ||||
|     }  | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Sendto with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_sendto(p_socket ps, const char *data, size_t count, size_t *sent,  | ||||
|         SA *addr, socklen_t len, p_timeout tm) | ||||
| { | ||||
|     int err; | ||||
|     *sent = 0; | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     for ( ;; ) { | ||||
|         int put = sendto(*ps, data, (int) count, 0, addr, len); | ||||
|         if (put > 0) { | ||||
|             *sent = put; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         err = WSAGetLastError();  | ||||
|         if (err != WSAEWOULDBLOCK) return err; | ||||
|         if ((err = socket_waitfd(ps, WAITFD_W, tm)) != IO_DONE) return err; | ||||
|     }  | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Receive with timeout | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| 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 ( ;; ) { | ||||
|         int taken = recv(*ps, data, (int) count, 0); | ||||
|         if (taken > 0) { | ||||
|             *got = taken; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         if (taken == 0) return IO_CLOSED; | ||||
|         err = WSAGetLastError(); | ||||
|         /* 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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * 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, prev = IO_DONE; | ||||
|     *got = 0; | ||||
|     if (*ps == SOCKET_INVALID) return IO_CLOSED; | ||||
|     for ( ;; ) { | ||||
|         int taken = recvfrom(*ps, data, (int) count, 0, addr, len); | ||||
|         if (taken > 0) { | ||||
|             *got = taken; | ||||
|             return IO_DONE; | ||||
|         } | ||||
|         if (taken == 0) return IO_CLOSED; | ||||
|         err = WSAGetLastError(); | ||||
|         /* 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; | ||||
|     } | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Put socket into blocking mode | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void socket_setblocking(p_socket ps) { | ||||
|     u_long argp = 0; | ||||
|     ioctlsocket(*ps, FIONBIO, &argp); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Put socket into non-blocking mode | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| void socket_setnonblocking(p_socket ps) { | ||||
|     u_long argp = 1; | ||||
|     ioctlsocket(*ps, FIONBIO, &argp); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * DNS helpers  | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| int socket_gethostbyaddr(const char *addr, socklen_t len, struct hostent **hp) { | ||||
|     *hp = gethostbyaddr(addr, len, AF_INET); | ||||
|     if (*hp) return IO_DONE; | ||||
|     else return WSAGetLastError(); | ||||
| } | ||||
|  | ||||
| int socket_gethostbyname(const char *addr, struct hostent **hp) { | ||||
|     *hp = gethostbyname(addr); | ||||
|     if (*hp) return IO_DONE; | ||||
|     else return  WSAGetLastError(); | ||||
| } | ||||
|  | ||||
| /*-------------------------------------------------------------------------*\ | ||||
| * Error translation functions | ||||
| \*-------------------------------------------------------------------------*/ | ||||
| const char *socket_hoststrerror(int err) { | ||||
|     if (err <= 0) return io_strerror(err); | ||||
|     switch (err) { | ||||
|         case WSAHOST_NOT_FOUND: return "host not found"; | ||||
|         default: return wstrerror(err);  | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *socket_strerror(int err) { | ||||
|     if (err <= 0) return io_strerror(err); | ||||
|     switch (err) { | ||||
|         case WSAEADDRINUSE: return "address already in use"; | ||||
|         case WSAECONNREFUSED: return "connection refused"; | ||||
|         case WSAEISCONN: return "already connected"; | ||||
|         case WSAEACCES: return "permission denied"; | ||||
|         case WSAECONNABORTED: return "closed"; | ||||
|         case WSAECONNRESET: return "closed"; | ||||
|         case WSAETIMEDOUT: return "timeout"; | ||||
|         default: return wstrerror(err); | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *socket_ioerror(p_socket ps, int err) { | ||||
|     (void) ps; | ||||
|     return socket_strerror(err); | ||||
| } | ||||
|  | ||||
| static const char *wstrerror(int err) { | ||||
|     switch (err) { | ||||
|         case WSAEINTR: return "Interrupted function call"; | ||||
|         case WSAEACCES: return "Permission denied"; | ||||
|         case WSAEFAULT: return "Bad address"; | ||||
|         case WSAEINVAL: return "Invalid argument"; | ||||
|         case WSAEMFILE: return "Too many open files"; | ||||
|         case WSAEWOULDBLOCK: return "Resource temporarily unavailable"; | ||||
|         case WSAEINPROGRESS: return "Operation now in progress"; | ||||
|         case WSAEALREADY: return "Operation already in progress"; | ||||
|         case WSAENOTSOCK: return "Socket operation on nonsocket"; | ||||
|         case WSAEDESTADDRREQ: return "Destination address required"; | ||||
|         case WSAEMSGSIZE: return "Message too long"; | ||||
|         case WSAEPROTOTYPE: return "Protocol wrong type for socket"; | ||||
|         case WSAENOPROTOOPT: return "Bad protocol option"; | ||||
|         case WSAEPROTONOSUPPORT: return "Protocol not supported"; | ||||
|         case WSAESOCKTNOSUPPORT: return "Socket type not supported"; | ||||
|         case WSAEOPNOTSUPP: return "Operation not supported"; | ||||
|         case WSAEPFNOSUPPORT: return "Protocol family not supported"; | ||||
|         case WSAEAFNOSUPPORT:  | ||||
|             return "Address family not supported by protocol family";  | ||||
|         case WSAEADDRINUSE: return "Address already in use"; | ||||
|         case WSAEADDRNOTAVAIL: return "Cannot assign requested address"; | ||||
|         case WSAENETDOWN: return "Network is down"; | ||||
|         case WSAENETUNREACH: return "Network is unreachable"; | ||||
|         case WSAENETRESET: return "Network dropped connection on reset"; | ||||
|         case WSAECONNABORTED: return "Software caused connection abort"; | ||||
|         case WSAECONNRESET: return "Connection reset by peer"; | ||||
|         case WSAENOBUFS: return "No buffer space available"; | ||||
|         case WSAEISCONN: return "Socket is already connected"; | ||||
|         case WSAENOTCONN: return "Socket is not connected"; | ||||
|         case WSAESHUTDOWN: return "Cannot send after socket shutdown"; | ||||
|         case WSAETIMEDOUT: return "Connection timed out"; | ||||
|         case WSAECONNREFUSED: return "Connection refused"; | ||||
|         case WSAEHOSTDOWN: return "Host is down"; | ||||
|         case WSAEHOSTUNREACH: return "No route to host"; | ||||
|         case WSAEPROCLIM: return "Too many processes"; | ||||
|         case WSASYSNOTREADY: return "Network subsystem is unavailable"; | ||||
|         case WSAVERNOTSUPPORTED: return "Winsock.dll version out of range"; | ||||
|         case WSANOTINITIALISED:  | ||||
|             return "Successful WSAStartup not yet performed"; | ||||
|         case WSAEDISCON: return "Graceful shutdown in progress"; | ||||
|         case WSAHOST_NOT_FOUND: return "Host not found"; | ||||
|         case WSATRY_AGAIN: return "Nonauthoritative host not found"; | ||||
|         case WSANO_RECOVERY: return "Nonrecoverable name lookup error";  | ||||
|         case WSANO_DATA: return "Valid name, no data record of requested type"; | ||||
|         default: return "Unknown error"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| const char *socket_gaistrerror(int err) { | ||||
|     if (err == 0) return NULL;  | ||||
|     switch (err) { | ||||
|         case EAI_AGAIN: return "temporary failure in name resolution"; | ||||
|         case EAI_BADFLAGS: return "invalid value for ai_flags"; | ||||
| #ifdef EAI_BADHINTS | ||||
|         case EAI_BADHINTS: return "invalid value for hints"; | ||||
| #endif | ||||
|         case EAI_FAIL: return "non-recoverable failure in name resolution"; | ||||
|         case EAI_FAMILY: return "ai_family not supported"; | ||||
|         case EAI_MEMORY: return "memory allocation failure"; | ||||
|         case EAI_NONAME:  | ||||
|             return "host or service not provided, or not known"; | ||||
| #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"; | ||||
| #ifdef EAI_SYSTEM | ||||
|         case EAI_SYSTEM: return strerror(errno);  | ||||
| #endif | ||||
|         default: return gai_strerrorA(err); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| } // end NS_SLUA | ||||
|  | ||||
| #endif // _WIN32 | ||||
							
								
								
									
										38
									
								
								Plugins/slua_unreal/External/luasocket/wsocket.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								Plugins/slua_unreal/External/luasocket/wsocket.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| #ifndef WSOCKET_H | ||||
| #define WSOCKET_H | ||||
| /*=========================================================================*\ | ||||
| * Socket compatibilization module for Win32 | ||||
| * LuaSocket toolkit | ||||
| \*=========================================================================*/ | ||||
|  | ||||
| /*=========================================================================*\ | ||||
| * WinSock include files | ||||
| \*=========================================================================*/ | ||||
| #ifdef _WIN32 | ||||
| #include <winsock2.h> | ||||
| #include <ws2tcpip.h> | ||||
|  | ||||
| namespace NS_SLUA {     | ||||
|  | ||||
| typedef int socklen_t; | ||||
| 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 | ||||
|  | ||||
| } // end NS_SLUA | ||||
| #endif | ||||
| #endif /* WSOCKET_H */ | ||||
		Reference in New Issue
	
	Block a user