diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-02-04 14:29:11 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-02-04 14:29:11 +0000 |
| commit | 0b2542d1a61fc5425ff65ab3dbf7ba7de174763f (patch) | |
| tree | 8a6188e11db0c9ef6891c31e8a1bebca050b23b2 /src | |
| parent | f67864f86c7d703325e86b14d0ba33992c52891b (diff) | |
| download | luasocket-0b2542d1a61fc5425ff65ab3dbf7ba7de174763f.tar.gz luasocket-0b2542d1a61fc5425ff65ab3dbf7ba7de174763f.tar.bz2 luasocket-0b2542d1a61fc5425ff65ab3dbf7ba7de174763f.zip | |
Worked on the manual.
Implemented stuffing (needs test)
Added cddb and qp examples.
Diffstat (limited to 'src')
| -rw-r--r-- | src/auxiliar.c | 14 | ||||
| -rw-r--r-- | src/auxiliar.h | 3 | ||||
| -rw-r--r-- | src/buffer.c | 3 | ||||
| -rw-r--r-- | src/buffer.h | 2 | ||||
| -rw-r--r-- | src/ftp.lua | 2 | ||||
| -rw-r--r-- | src/http.lua | 2 | ||||
| -rw-r--r-- | src/inet.c | 9 | ||||
| -rw-r--r-- | src/inet.h | 2 | ||||
| -rw-r--r-- | src/luasocket.c | 50 | ||||
| -rw-r--r-- | src/mime.c | 138 | ||||
| -rw-r--r-- | src/mime.h | 2 | ||||
| -rw-r--r-- | src/mime.lua | 71 | ||||
| -rw-r--r-- | src/select.c | 3 | ||||
| -rw-r--r-- | src/select.h | 2 | ||||
| -rw-r--r-- | src/smtp.lua | 6 | ||||
| -rw-r--r-- | src/tcp.c | 33 | ||||
| -rw-r--r-- | src/tcp.h | 2 | ||||
| -rw-r--r-- | src/timeout.c | 3 | ||||
| -rw-r--r-- | src/timeout.h | 2 | ||||
| -rw-r--r-- | src/udp.c | 32 | ||||
| -rw-r--r-- | src/udp.h | 2 | ||||
| -rw-r--r-- | src/url.lua | 2 | ||||
| -rw-r--r-- | src/usocket.c | 5 | ||||
| -rw-r--r-- | src/wsocket.c | 6 |
24 files changed, 192 insertions, 204 deletions
diff --git a/src/auxiliar.c b/src/auxiliar.c index 9a249b6..812d7fc 100644 --- a/src/auxiliar.c +++ b/src/auxiliar.c | |||
| @@ -37,9 +37,9 @@ error: | |||
| 37 | /*-------------------------------------------------------------------------*\ | 37 | /*-------------------------------------------------------------------------*\ |
| 38 | * Initializes the module | 38 | * Initializes the module |
| 39 | \*-------------------------------------------------------------------------*/ | 39 | \*-------------------------------------------------------------------------*/ |
| 40 | void aux_open(lua_State *L) | 40 | int aux_open(lua_State *L) |
| 41 | { | 41 | { |
| 42 | ; | 42 | return 0; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | /*-------------------------------------------------------------------------*\ | 45 | /*-------------------------------------------------------------------------*\ |
| @@ -159,3 +159,13 @@ void *aux_getclassudata(lua_State *L, const char *classname, int objidx) | |||
| 159 | return luaL_checkudata(L, objidx, classname); | 159 | return luaL_checkudata(L, objidx, classname); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | /*-------------------------------------------------------------------------*\ | ||
| 163 | * Accept "false" as nil | ||
| 164 | \*-------------------------------------------------------------------------*/ | ||
| 165 | const char *aux_optlstring(lua_State *L, int n, const char *v, size_t *l) | ||
| 166 | { | ||
| 167 | if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { | ||
| 168 | *l = 0; | ||
| 169 | return NULL; | ||
| 170 | } else return luaL_optlstring(L, n, v, l); | ||
| 171 | } | ||
diff --git a/src/auxiliar.h b/src/auxiliar.h index b98eb9c..ac62ecd 100644 --- a/src/auxiliar.h +++ b/src/auxiliar.h | |||
| @@ -40,7 +40,7 @@ | |||
| 40 | #define MAX(x, y) ((x) > (y) ? x : y) | 40 | #define MAX(x, y) ((x) > (y) ? x : y) |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | void aux_open(lua_State *L); | 43 | int aux_open(lua_State *L); |
| 44 | void aux_newclass(lua_State *L, const char *classname, luaL_reg *func); | 44 | void aux_newclass(lua_State *L, const char *classname, luaL_reg *func); |
| 45 | void aux_add2group(lua_State *L, const char *classname, const char *group); | 45 | void aux_add2group(lua_State *L, const char *classname, const char *group); |
| 46 | void aux_setclass(lua_State *L, const char *classname, int objidx); | 46 | void aux_setclass(lua_State *L, const char *classname, int objidx); |
| @@ -49,5 +49,6 @@ void *aux_checkgroup(lua_State *L, const char *groupname, int objidx); | |||
| 49 | void *aux_getclassudata(lua_State *L, const char *groupname, int objidx); | 49 | void *aux_getclassudata(lua_State *L, const char *groupname, int objidx); |
| 50 | void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx); | 50 | void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx); |
| 51 | int aux_checkboolean(lua_State *L, int objidx); | 51 | int aux_checkboolean(lua_State *L, int objidx); |
| 52 | const char *aux_optlstring(lua_State *L, int n, const char *v, size_t *l); | ||
| 52 | 53 | ||
| 53 | #endif /* AUX_H */ | 54 | #endif /* AUX_H */ |
diff --git a/src/buffer.c b/src/buffer.c index e6d4ce8..d9ba779 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -26,9 +26,10 @@ static int sendraw(p_buf buf, const char *data, size_t count, size_t *sent); | |||
| 26 | /*-------------------------------------------------------------------------*\ | 26 | /*-------------------------------------------------------------------------*\ |
| 27 | * Initializes module | 27 | * Initializes module |
| 28 | \*-------------------------------------------------------------------------*/ | 28 | \*-------------------------------------------------------------------------*/ |
| 29 | void buf_open(lua_State *L) | 29 | int buf_open(lua_State *L) |
| 30 | { | 30 | { |
| 31 | (void) L; | 31 | (void) L; |
| 32 | return 0; | ||
| 32 | } | 33 | } |
| 33 | 34 | ||
| 34 | /*-------------------------------------------------------------------------*\ | 35 | /*-------------------------------------------------------------------------*\ |
diff --git a/src/buffer.h b/src/buffer.h index 12b90a0..4b7563f 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -34,7 +34,7 @@ typedef struct t_buf_ { | |||
| 34 | } t_buf; | 34 | } t_buf; |
| 35 | typedef t_buf *p_buf; | 35 | typedef t_buf *p_buf; |
| 36 | 36 | ||
| 37 | void buf_open(lua_State *L); | 37 | int buf_open(lua_State *L); |
| 38 | void buf_init(p_buf buf, p_io io, p_tm tm); | 38 | void buf_init(p_buf buf, p_io io, p_tm tm); |
| 39 | int buf_meth_send(lua_State *L, p_buf buf); | 39 | int buf_meth_send(lua_State *L, p_buf buf); |
| 40 | int buf_meth_receive(lua_State *L, p_buf buf); | 40 | int buf_meth_receive(lua_State *L, p_buf buf); |
diff --git a/src/ftp.lua b/src/ftp.lua index bfc4ece..e596416 100644 --- a/src/ftp.lua +++ b/src/ftp.lua | |||
| @@ -649,3 +649,5 @@ function Public.get(url_or_request) | |||
| 649 | local err = Public.get_cb(request) | 649 | local err = Public.get_cb(request) |
| 650 | return concat:getresult(), err | 650 | return concat:getresult(), err |
| 651 | end | 651 | end |
| 652 | |||
| 653 | return ftp | ||
diff --git a/src/http.lua b/src/http.lua index 4d6e426..74c29ba 100644 --- a/src/http.lua +++ b/src/http.lua | |||
| @@ -11,7 +11,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end | |||
| 11 | local socket = _G[LUASOCKET_LIBNAME] | 11 | local socket = _G[LUASOCKET_LIBNAME] |
| 12 | if not socket then error('module requires LuaSocket') end | 12 | if not socket then error('module requires LuaSocket') end |
| 13 | -- create smtp namespace inside LuaSocket namespace | 13 | -- create smtp namespace inside LuaSocket namespace |
| 14 | local http = {} | 14 | local http = socket.http or {} |
| 15 | socket.http = http | 15 | socket.http = http |
| 16 | -- make all module globals fall into smtp namespace | 16 | -- make all module globals fall into smtp namespace |
| 17 | setmetatable(http, { __index = _G }) | 17 | setmetatable(http, { __index = _G }) |
| @@ -35,17 +35,10 @@ static luaL_reg func[] = { | |||
| 35 | /*-------------------------------------------------------------------------*\ | 35 | /*-------------------------------------------------------------------------*\ |
| 36 | * Initializes module | 36 | * Initializes module |
| 37 | \*-------------------------------------------------------------------------*/ | 37 | \*-------------------------------------------------------------------------*/ |
| 38 | void inet_open(lua_State *L) | 38 | int inet_open(lua_State *L) |
| 39 | { | 39 | { |
| 40 | lua_pushstring(L, LUASOCKET_LIBNAME); | 40 | lua_pushstring(L, LUASOCKET_LIBNAME); |
| 41 | lua_gettable(L, LUA_GLOBALSINDEX); | 41 | lua_gettable(L, LUA_GLOBALSINDEX); |
| 42 | if (lua_isnil(L, -1)) { | ||
| 43 | lua_pop(L, 1); | ||
| 44 | lua_newtable(L); | ||
| 45 | lua_pushstring(L, LUASOCKET_LIBNAME); | ||
| 46 | lua_pushvalue(L, -2); | ||
| 47 | lua_settable(L, LUA_GLOBALSINDEX); | ||
| 48 | } | ||
| 49 | lua_pushstring(L, "dns"); | 42 | lua_pushstring(L, "dns"); |
| 50 | lua_newtable(L); | 43 | lua_newtable(L); |
| 51 | luaL_openlib(L, NULL, func, 0); | 44 | luaL_openlib(L, NULL, func, 0); |
| @@ -24,7 +24,7 @@ | |||
| 24 | #define INET_ATON | 24 | #define INET_ATON |
| 25 | #endif | 25 | #endif |
| 26 | 26 | ||
| 27 | void inet_open(lua_State *L); | 27 | int inet_open(lua_State *L); |
| 28 | 28 | ||
| 29 | const char *inet_trycreate(p_sock ps, int type); | 29 | const char *inet_trycreate(p_sock ps, int type); |
| 30 | const char *inet_tryconnect(p_sock ps, const char *address, | 30 | const char *inet_tryconnect(p_sock ps, const char *address, |
diff --git a/src/luasocket.c b/src/luasocket.c index bfe71c2..e99fcdf 100644 --- a/src/luasocket.c +++ b/src/luasocket.c | |||
| @@ -33,12 +33,14 @@ | |||
| 33 | #include "tcp.h" | 33 | #include "tcp.h" |
| 34 | #include "udp.h" | 34 | #include "udp.h" |
| 35 | #include "select.h" | 35 | #include "select.h" |
| 36 | #include "smtp.h" | ||
| 36 | #include "mime.h" | 37 | #include "mime.h" |
| 37 | 38 | ||
| 38 | /*=========================================================================*\ | 39 | /*=========================================================================*\ |
| 39 | * Declarations | 40 | * Declarations |
| 40 | \*=========================================================================*/ | 41 | \*=========================================================================*/ |
| 41 | static int base_open(lua_State *L); | 42 | static int base_open(lua_State *L); |
| 43 | static int mod_open(lua_State *L, const luaL_reg *mod); | ||
| 42 | 44 | ||
| 43 | /*-------------------------------------------------------------------------*\ | 45 | /*-------------------------------------------------------------------------*\ |
| 44 | * Setup basic stuff. | 46 | * Setup basic stuff. |
| @@ -66,22 +68,9 @@ static int base_open(lua_State *L) | |||
| 66 | return 0; | 68 | return 0; |
| 67 | } | 69 | } |
| 68 | 70 | ||
| 69 | /*-------------------------------------------------------------------------*\ | 71 | static int mod_open(lua_State *L, const luaL_reg *mod) |
| 70 | * Initializes all library modules. | ||
| 71 | \*-------------------------------------------------------------------------*/ | ||
| 72 | LUASOCKET_API int luaopen_socket(lua_State *L) | ||
| 73 | { | 72 | { |
| 74 | if (!sock_open()) return 0; | 73 | for (; mod->name; mod++) mod->func(L); |
| 75 | /* initialize all modules */ | ||
| 76 | base_open(L); | ||
| 77 | aux_open(L); | ||
| 78 | tm_open(L); | ||
| 79 | buf_open(L); | ||
| 80 | inet_open(L); | ||
| 81 | tcp_open(L); | ||
| 82 | udp_open(L); | ||
| 83 | select_open(L); | ||
| 84 | mime_open(L); | ||
| 85 | #ifdef LUASOCKET_COMPILED | 74 | #ifdef LUASOCKET_COMPILED |
| 86 | #include "auxiliar.lch" | 75 | #include "auxiliar.lch" |
| 87 | #include "concat.lch" | 76 | #include "concat.lch" |
| @@ -101,5 +90,36 @@ LUASOCKET_API int luaopen_socket(lua_State *L) | |||
| 101 | lua_dofile(L, "ftp.lua"); | 90 | lua_dofile(L, "ftp.lua"); |
| 102 | lua_dofile(L, "http.lua"); | 91 | lua_dofile(L, "http.lua"); |
| 103 | #endif | 92 | #endif |
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | /*-------------------------------------------------------------------------*\ | ||
| 97 | * Modules | ||
| 98 | \*-------------------------------------------------------------------------*/ | ||
| 99 | static const luaL_reg mod[] = { | ||
| 100 | {"base", base_open}, | ||
| 101 | {"aux", aux_open}, | ||
| 102 | {"tm", tm_open}, | ||
| 103 | {"buf", buf_open}, | ||
| 104 | {"inet", inet_open}, | ||
| 105 | {"tcp", tcp_open}, | ||
| 106 | {"udp", udp_open}, | ||
| 107 | {"select", select_open}, | ||
| 108 | {"mime", mime_open}, | ||
| 109 | {"smtp", smtp_open}, | ||
| 110 | {NULL, NULL} | ||
| 111 | }; | ||
| 112 | |||
| 113 | /*-------------------------------------------------------------------------*\ | ||
| 114 | * Initializes all library modules. | ||
| 115 | \*-------------------------------------------------------------------------*/ | ||
| 116 | LUASOCKET_API int luaopen_socket(lua_State *L) | ||
| 117 | { | ||
| 118 | if (!sock_open()) { | ||
| 119 | lua_pushnil(L); | ||
| 120 | lua_pushstring(L, "unable to initialize library"); | ||
| 121 | return 2; | ||
| 122 | } | ||
| 123 | mod_open(L, mod); | ||
| 104 | return 1; | 124 | return 1; |
| 105 | } | 125 | } |
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <lauxlib.h> | 10 | #include <lauxlib.h> |
| 11 | 11 | ||
| 12 | #include "luasocket.h" | 12 | #include "luasocket.h" |
| 13 | #include "auxiliar.h" | ||
| 13 | #include "mime.h" | 14 | #include "mime.h" |
| 14 | 15 | ||
| 15 | /*=========================================================================*\ | 16 | /*=========================================================================*\ |
| @@ -45,18 +46,16 @@ static void qpquote(UC c, luaL_Buffer *buffer); | |||
| 45 | static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | 46 | static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); |
| 46 | static size_t qpencode(UC c, UC *input, size_t size, | 47 | static size_t qpencode(UC c, UC *input, size_t size, |
| 47 | const char *marker, luaL_Buffer *buffer); | 48 | const char *marker, luaL_Buffer *buffer); |
| 48 | 49 | static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); | |
| 49 | static const char *checklstring(lua_State *L, int n, size_t *l); | ||
| 50 | static const char *optlstring(lua_State *L, int n, const char *v, size_t *l); | ||
| 51 | 50 | ||
| 52 | /* code support functions */ | 51 | /* code support functions */ |
| 53 | static luaL_reg func[] = { | 52 | static luaL_reg func[] = { |
| 53 | { "b64", mime_global_b64 }, | ||
| 54 | { "eol", mime_global_eol }, | 54 | { "eol", mime_global_eol }, |
| 55 | { "qp", mime_global_qp }, | 55 | { "qp", mime_global_qp }, |
| 56 | { "unqp", mime_global_unqp }, | ||
| 57 | { "qpwrp", mime_global_qpwrp }, | 56 | { "qpwrp", mime_global_qpwrp }, |
| 58 | { "b64", mime_global_b64 }, | ||
| 59 | { "unb64", mime_global_unb64 }, | 57 | { "unb64", mime_global_unb64 }, |
| 58 | { "unqp", mime_global_unqp }, | ||
| 60 | { "wrp", mime_global_wrp }, | 59 | { "wrp", mime_global_wrp }, |
| 61 | { NULL, NULL } | 60 | { NULL, NULL } |
| 62 | }; | 61 | }; |
| @@ -82,17 +81,10 @@ static UC b64unbase[256]; | |||
| 82 | /*-------------------------------------------------------------------------*\ | 81 | /*-------------------------------------------------------------------------*\ |
| 83 | * Initializes module | 82 | * Initializes module |
| 84 | \*-------------------------------------------------------------------------*/ | 83 | \*-------------------------------------------------------------------------*/ |
| 85 | void mime_open(lua_State *L) | 84 | int mime_open(lua_State *L) |
| 86 | { | 85 | { |
| 87 | lua_pushstring(L, LUASOCKET_LIBNAME); | 86 | lua_pushstring(L, LUASOCKET_LIBNAME); |
| 88 | lua_gettable(L, LUA_GLOBALSINDEX); | 87 | lua_gettable(L, LUA_GLOBALSINDEX); |
| 89 | if (lua_isnil(L, -1)) { | ||
| 90 | lua_pop(L, 1); | ||
| 91 | lua_newtable(L); | ||
| 92 | lua_pushstring(L, LUASOCKET_LIBNAME); | ||
| 93 | lua_pushvalue(L, -2); | ||
| 94 | lua_settable(L, LUA_GLOBALSINDEX); | ||
| 95 | } | ||
| 96 | lua_pushstring(L, "mime"); | 88 | lua_pushstring(L, "mime"); |
| 97 | lua_newtable(L); | 89 | lua_newtable(L); |
| 98 | luaL_openlib(L, NULL, func, 0); | 90 | luaL_openlib(L, NULL, func, 0); |
| @@ -101,25 +93,7 @@ void mime_open(lua_State *L) | |||
| 101 | /* initialize lookup tables */ | 93 | /* initialize lookup tables */ |
| 102 | qpsetup(qpclass, qpunbase); | 94 | qpsetup(qpclass, qpunbase); |
| 103 | b64setup(b64unbase); | 95 | b64setup(b64unbase); |
| 104 | } | 96 | return 0; |
| 105 | |||
| 106 | /*-------------------------------------------------------------------------*\ | ||
| 107 | * Check if a string was provided. We accept false also. | ||
| 108 | \*-------------------------------------------------------------------------*/ | ||
| 109 | static const char *checklstring(lua_State *L, int n, size_t *l) | ||
| 110 | { | ||
| 111 | if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { | ||
| 112 | *l = 0; | ||
| 113 | return NULL; | ||
| 114 | } else return luaL_checklstring(L, n, l); | ||
| 115 | } | ||
| 116 | |||
| 117 | static const char *optlstring(lua_State *L, int n, const char *v, size_t *l) | ||
| 118 | { | ||
| 119 | if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { | ||
| 120 | *l = 0; | ||
| 121 | return NULL; | ||
| 122 | } else return luaL_optlstring(L, n, v, l); | ||
| 123 | } | 97 | } |
| 124 | 98 | ||
| 125 | /*=========================================================================*\ | 99 | /*=========================================================================*\ |
| @@ -127,31 +101,42 @@ static const char *optlstring(lua_State *L, int n, const char *v, size_t *l) | |||
| 127 | \*=========================================================================*/ | 101 | \*=========================================================================*/ |
| 128 | /*-------------------------------------------------------------------------*\ | 102 | /*-------------------------------------------------------------------------*\ |
| 129 | * Incrementaly breaks a string into lines | 103 | * Incrementaly breaks a string into lines |
| 130 | * A, n = wrp(l, B, length, marker) | 104 | * A, n = wrp(l, B, length) |
| 131 | * A is a copy of B, broken into lines of at most 'length' bytes. | 105 | * A is a copy of B, broken into lines of at most 'length' bytes. |
| 132 | * 'l' is how many bytes are left for the first line of B. | 106 | * 'l' is how many bytes are left for the first line of B. |
| 133 | * 'n' is the number of bytes left in the last line of A. | 107 | * 'n' is the number of bytes left in the last line of A. |
| 134 | * Marker is the end-of-line marker. | ||
| 135 | \*-------------------------------------------------------------------------*/ | 108 | \*-------------------------------------------------------------------------*/ |
| 136 | static int mime_global_wrp(lua_State *L) | 109 | static int mime_global_wrp(lua_State *L) |
| 137 | { | 110 | { |
| 138 | size_t size = 0; | 111 | size_t size = 0; |
| 139 | int left = (int) luaL_checknumber(L, 1); | 112 | int left = (int) luaL_checknumber(L, 1); |
| 140 | const UC *input = (UC *) checklstring(L, 2, &size); | 113 | const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size); |
| 141 | const UC *last = input + size; | 114 | const UC *last = input + size; |
| 142 | int length = (int) luaL_optnumber(L, 3, 76); | 115 | int length = (int) luaL_optnumber(L, 3, 76); |
| 143 | const char *marker = luaL_optstring(L, 4, CRLF); | ||
| 144 | luaL_Buffer buffer; | 116 | luaL_Buffer buffer; |
| 145 | luaL_buffinit(L, &buffer); | 117 | luaL_buffinit(L, &buffer); |
| 146 | while (input < last) { | 118 | while (input < last) { |
| 147 | luaL_putchar(&buffer, *input++); | 119 | switch (*input) { |
| 148 | if (--left <= 0) { | 120 | case CR: |
| 149 | luaL_addstring(&buffer, marker); | 121 | break; |
| 150 | left = length; | 122 | case LF: |
| 123 | luaL_addstring(&buffer, CRLF); | ||
| 124 | left = length; | ||
| 125 | break; | ||
| 126 | default: | ||
| 127 | if (left <= 0) { | ||
| 128 | left = length; | ||
| 129 | luaL_addstring(&buffer, CRLF); | ||
| 130 | } | ||
| 131 | luaL_putchar(&buffer, *input); | ||
| 132 | left--; | ||
| 133 | break; | ||
| 151 | } | 134 | } |
| 135 | input++; | ||
| 152 | } | 136 | } |
| 137 | /* if in last chunk and last line wasn't terminated, add a line-break */ | ||
| 153 | if (!input && left < length) { | 138 | if (!input && left < length) { |
| 154 | luaL_addstring(&buffer, marker); | 139 | luaL_addstring(&buffer, CRLF); |
| 155 | left = length; | 140 | left = length; |
| 156 | } | 141 | } |
| 157 | luaL_pushresult(&buffer); | 142 | luaL_pushresult(&buffer); |
| @@ -235,7 +220,6 @@ static size_t b64pad(const UC *input, size_t size, | |||
| 235 | static size_t b64decode(UC c, UC *input, size_t size, | 220 | static size_t b64decode(UC c, UC *input, size_t size, |
| 236 | luaL_Buffer *buffer) | 221 | luaL_Buffer *buffer) |
| 237 | { | 222 | { |
| 238 | |||
| 239 | /* ignore invalid characters */ | 223 | /* ignore invalid characters */ |
| 240 | if (b64unbase[c] > 64) return size; | 224 | if (b64unbase[c] > 64) return size; |
| 241 | input[size++] = c; | 225 | input[size++] = c; |
| @@ -277,7 +261,7 @@ static int mime_global_b64(lua_State *L) | |||
| 277 | luaL_buffinit(L, &buffer); | 261 | luaL_buffinit(L, &buffer); |
| 278 | while (input < last) | 262 | while (input < last) |
| 279 | asize = b64encode(*input++, atom, asize, &buffer); | 263 | asize = b64encode(*input++, atom, asize, &buffer); |
| 280 | input = (UC *) optlstring(L, 2, NULL, &isize); | 264 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
| 281 | if (input) { | 265 | if (input) { |
| 282 | last = input + isize; | 266 | last = input + isize; |
| 283 | while (input < last) | 267 | while (input < last) |
| @@ -305,12 +289,14 @@ static int mime_global_unb64(lua_State *L) | |||
| 305 | luaL_buffinit(L, &buffer); | 289 | luaL_buffinit(L, &buffer); |
| 306 | while (input < last) | 290 | while (input < last) |
| 307 | asize = b64decode(*input++, atom, asize, &buffer); | 291 | asize = b64decode(*input++, atom, asize, &buffer); |
| 308 | input = (UC *) optlstring(L, 2, NULL, &isize); | 292 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
| 309 | if (input) { | 293 | if (input) { |
| 310 | last = input + isize; | 294 | last = input + isize; |
| 311 | while (input < last) | 295 | while (input < last) |
| 312 | asize = b64decode(*input++, atom, asize, &buffer); | 296 | asize = b64decode(*input++, atom, asize, &buffer); |
| 313 | } | 297 | } |
| 298 | /* if !input we are done. if atom > 0, the remaning is invalid. we just | ||
| 299 | * return it undecoded. */ | ||
| 314 | luaL_pushresult(&buffer); | 300 | luaL_pushresult(&buffer); |
| 315 | lua_pushlstring(L, (char *) atom, asize); | 301 | lua_pushlstring(L, (char *) atom, asize); |
| 316 | return 2; | 302 | return 2; |
| @@ -416,7 +402,7 @@ static size_t qpencode(UC c, UC *input, size_t size, | |||
| 416 | /*-------------------------------------------------------------------------*\ | 402 | /*-------------------------------------------------------------------------*\ |
| 417 | * Deal with the final characters | 403 | * Deal with the final characters |
| 418 | \*-------------------------------------------------------------------------*/ | 404 | \*-------------------------------------------------------------------------*/ |
| 419 | static void qppad(UC *input, size_t size, luaL_Buffer *buffer) | 405 | static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) |
| 420 | { | 406 | { |
| 421 | size_t i; | 407 | size_t i; |
| 422 | for (i = 0; i < size; i++) { | 408 | for (i = 0; i < size; i++) { |
| @@ -424,12 +410,13 @@ static void qppad(UC *input, size_t size, luaL_Buffer *buffer) | |||
| 424 | else qpquote(input[i], buffer); | 410 | else qpquote(input[i], buffer); |
| 425 | } | 411 | } |
| 426 | luaL_addstring(buffer, EQCRLF); | 412 | luaL_addstring(buffer, EQCRLF); |
| 413 | return 0; | ||
| 427 | } | 414 | } |
| 428 | 415 | ||
| 429 | /*-------------------------------------------------------------------------*\ | 416 | /*-------------------------------------------------------------------------*\ |
| 430 | * Incrementally converts a string to quoted-printable | 417 | * Incrementally converts a string to quoted-printable |
| 431 | * A, B = qp(C, D, marker) | 418 | * A, B = qp(C, D, marker) |
| 432 | * Crlf is the text to be used to replace CRLF sequences found in A. | 419 | * Marker is the text to be used to replace CRLF sequences found in A. |
| 433 | * A is the encoded version of the largest prefix of C .. D that | 420 | * A is the encoded version of the largest prefix of C .. D that |
| 434 | * can be encoded without doubts. | 421 | * can be encoded without doubts. |
| 435 | * B has the remaining bytes of C .. D, *without* encoding. | 422 | * B has the remaining bytes of C .. D, *without* encoding. |
| @@ -439,19 +426,20 @@ static int mime_global_qp(lua_State *L) | |||
| 439 | 426 | ||
| 440 | size_t asize = 0, isize = 0; | 427 | size_t asize = 0, isize = 0; |
| 441 | UC atom[3]; | 428 | UC atom[3]; |
| 442 | const UC *input = (UC *) checklstring(L, 1, &isize); | 429 | const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); |
| 443 | const UC *last = input + isize; | 430 | const UC *last = input + isize; |
| 444 | const char *marker = luaL_optstring(L, 3, CRLF); | 431 | const char *marker = luaL_optstring(L, 3, CRLF); |
| 445 | luaL_Buffer buffer; | 432 | luaL_Buffer buffer; |
| 446 | luaL_buffinit(L, &buffer); | 433 | luaL_buffinit(L, &buffer); |
| 447 | while (input < last) | 434 | while (input < last) |
| 448 | asize = qpencode(*input++, atom, asize, marker, &buffer); | 435 | asize = qpencode(*input++, atom, asize, marker, &buffer); |
| 449 | input = (UC *) optlstring(L, 2, NULL, &isize); | 436 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
| 450 | if (input) { | 437 | if (input) { |
| 451 | last = input + isize; | 438 | last = input + isize; |
| 452 | while (input < last) | 439 | while (input < last) |
| 453 | asize = qpencode(*input++, atom, asize, marker, &buffer); | 440 | asize = qpencode(*input++, atom, asize, marker, &buffer); |
| 454 | } else qppad(atom, asize, &buffer); | 441 | } else |
| 442 | asize = qppad(atom, asize, &buffer); | ||
| 455 | luaL_pushresult(&buffer); | 443 | luaL_pushresult(&buffer); |
| 456 | lua_pushlstring(L, (char *) atom, asize); | 444 | lua_pushlstring(L, (char *) atom, asize); |
| 457 | return 2; | 445 | return 2; |
| @@ -507,13 +495,13 @@ static int mime_global_unqp(lua_State *L) | |||
| 507 | 495 | ||
| 508 | size_t asize = 0, isize = 0; | 496 | size_t asize = 0, isize = 0; |
| 509 | UC atom[3]; | 497 | UC atom[3]; |
| 510 | const UC *input = (UC *) checklstring(L, 1, &isize); | 498 | const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); |
| 511 | const UC *last = input + isize; | 499 | const UC *last = input + isize; |
| 512 | luaL_Buffer buffer; | 500 | luaL_Buffer buffer; |
| 513 | luaL_buffinit(L, &buffer); | 501 | luaL_buffinit(L, &buffer); |
| 514 | while (input < last) | 502 | while (input < last) |
| 515 | asize = qpdecode(*input++, atom, asize, &buffer); | 503 | asize = qpdecode(*input++, atom, asize, &buffer); |
| 516 | input = (UC *) optlstring(L, 2, NULL, &isize); | 504 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
| 517 | if (input) { | 505 | if (input) { |
| 518 | last = input + isize; | 506 | last = input + isize; |
| 519 | while (input < last) | 507 | while (input < last) |
| @@ -537,38 +525,39 @@ static int mime_global_qpwrp(lua_State *L) | |||
| 537 | { | 525 | { |
| 538 | size_t size = 0; | 526 | size_t size = 0; |
| 539 | int left = (int) luaL_checknumber(L, 1); | 527 | int left = (int) luaL_checknumber(L, 1); |
| 540 | const UC *input = (UC *) checklstring(L, 2, &size); | 528 | const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size); |
| 541 | const UC *last = input + size; | 529 | const UC *last = input + size; |
| 542 | int length = (int) luaL_optnumber(L, 3, 76); | 530 | int length = (int) luaL_optnumber(L, 3, 76); |
| 543 | luaL_Buffer buffer; | 531 | luaL_Buffer buffer; |
| 544 | luaL_buffinit(L, &buffer); | 532 | luaL_buffinit(L, &buffer); |
| 545 | while (input < last) { | 533 | while (input < last) { |
| 546 | left--; | ||
| 547 | switch (*input) { | 534 | switch (*input) { |
| 548 | case '=': | 535 | case CR: |
| 549 | /* if there's no room in this line for the quoted char, | ||
| 550 | * output a soft line break now */ | ||
| 551 | if (left <= 3) { | ||
| 552 | luaL_addstring(&buffer, EQCRLF); | ||
| 553 | left = length; | ||
| 554 | } | ||
| 555 | break; | ||
| 556 | /* \r\n starts a new line */ | ||
| 557 | case CR: | ||
| 558 | break; | 536 | break; |
| 559 | case LF: | 537 | case LF: |
| 560 | left = length; | 538 | left = length; |
| 539 | luaL_addstring(&buffer, CRLF); | ||
| 561 | break; | 540 | break; |
| 562 | default: | 541 | case '=': |
| 563 | /* if in last column, output a soft line break */ | 542 | if (left <= 3) { |
| 564 | if (left <= 1) { | 543 | left = length; |
| 565 | luaL_addstring(&buffer, EQCRLF); | 544 | luaL_addstring(&buffer, EQCRLF); |
| 545 | } | ||
| 546 | luaL_putchar(&buffer, *input); | ||
| 547 | left--; | ||
| 548 | break; | ||
| 549 | default: | ||
| 550 | if (left <= 1) { | ||
| 566 | left = length; | 551 | left = length; |
| 552 | luaL_addstring(&buffer, EQCRLF); | ||
| 567 | } | 553 | } |
| 554 | luaL_putchar(&buffer, *input); | ||
| 555 | left--; | ||
| 556 | break; | ||
| 568 | } | 557 | } |
| 569 | luaL_putchar(&buffer, *input); | ||
| 570 | input++; | 558 | input++; |
| 571 | } | 559 | } |
| 560 | /* if in last chunk and last line wasn't terminated, add a soft-break */ | ||
| 572 | if (!input && left < length) { | 561 | if (!input && left < length) { |
| 573 | luaL_addstring(&buffer, EQCRLF); | 562 | luaL_addstring(&buffer, EQCRLF); |
| 574 | left = length; | 563 | left = length; |
| @@ -579,10 +568,10 @@ static int mime_global_qpwrp(lua_State *L) | |||
| 579 | } | 568 | } |
| 580 | 569 | ||
| 581 | /*-------------------------------------------------------------------------*\ | 570 | /*-------------------------------------------------------------------------*\ |
| 582 | * Here is what we do: \n, \r and \f are considered candidates for line | 571 | * Here is what we do: \n, and \r are considered candidates for line |
| 583 | * break. We issue *one* new line marker if any of them is seen alone, or | 572 | * break. We issue *one* new line marker if any of them is seen alone, or |
| 584 | * followed by a different one. That is, \n\n, \r\r and \f\f will issue two | 573 | * followed by a different one. That is, \n\n and \r\r will issue two |
| 585 | * end of line markers each, but \r\n, \n\r, \r\f etc will only issue *one* | 574 | * end of line markers each, but \r\n, \n\r etc will only issue *one* |
| 586 | * marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as | 575 | * marker. This covers Mac OS, Mac OS X, VMS, Unix and DOS, as well as |
| 587 | * probably other more obscure conventions. | 576 | * probably other more obscure conventions. |
| 588 | \*-------------------------------------------------------------------------*/ | 577 | \*-------------------------------------------------------------------------*/ |
| @@ -616,21 +605,24 @@ static int mime_global_eol(lua_State *L) | |||
| 616 | { | 605 | { |
| 617 | size_t asize = 0, isize = 0; | 606 | size_t asize = 0, isize = 0; |
| 618 | UC atom[2]; | 607 | UC atom[2]; |
| 619 | const UC *input = (UC *) checklstring(L, 1, &isize); | 608 | const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); |
| 620 | const UC *last = input + isize; | 609 | const UC *last = input + isize; |
| 621 | const char *marker = luaL_optstring(L, 3, CRLF); | 610 | const char *marker = luaL_optstring(L, 3, CRLF); |
| 622 | luaL_Buffer buffer; | 611 | luaL_Buffer buffer; |
| 623 | luaL_buffinit(L, &buffer); | 612 | luaL_buffinit(L, &buffer); |
| 624 | while (input < last) | 613 | while (input < last) |
| 625 | asize = eolconvert(*input++, atom, asize, marker, &buffer); | 614 | asize = eolconvert(*input++, atom, asize, marker, &buffer); |
| 626 | input = (UC *) optlstring(L, 2, NULL, &isize); | 615 | input = (UC *) aux_optlstring(L, 2, NULL, &isize); |
| 627 | if (input) { | 616 | if (input) { |
| 628 | last = input + isize; | 617 | last = input + isize; |
| 629 | while (input < last) | 618 | while (input < last) |
| 630 | asize = eolconvert(*input++, atom, asize, marker, &buffer); | 619 | asize = eolconvert(*input++, atom, asize, marker, &buffer); |
| 631 | /* if there is something in atom, it's one character, and it | 620 | /* if there is something in atom, it's one character, and it |
| 632 | * is a candidate. so we output a new line */ | 621 | * is a candidate. so we output a new line */ |
| 633 | } else if (asize > 0) luaL_addstring(&buffer, marker); | 622 | } else if (asize > 0) { |
| 623 | luaL_addstring(&buffer, marker); | ||
| 624 | asize = 0; | ||
| 625 | } | ||
| 634 | luaL_pushresult(&buffer); | 626 | luaL_pushresult(&buffer); |
| 635 | lua_pushlstring(L, (char *) atom, asize); | 627 | lua_pushlstring(L, (char *) atom, asize); |
| 636 | return 2; | 628 | return 2; |
| @@ -12,6 +12,6 @@ | |||
| 12 | \*=========================================================================*/ | 12 | \*=========================================================================*/ |
| 13 | #include <lua.h> | 13 | #include <lua.h> |
| 14 | 14 | ||
| 15 | void mime_open(lua_State *L); | 15 | int mime_open(lua_State *L); |
| 16 | 16 | ||
| 17 | #endif /* MIME_H */ | 17 | #endif /* MIME_H */ |
diff --git a/src/mime.lua b/src/mime.lua index 30c6b38..369567f 100644 --- a/src/mime.lua +++ b/src/mime.lua | |||
| @@ -15,70 +15,57 @@ local et = {} | |||
| 15 | local dt = {} | 15 | local dt = {} |
| 16 | local wt = {} | 16 | local wt = {} |
| 17 | 17 | ||
| 18 | -- creates a function that chooses an algorithm from a given table | 18 | -- creates a function that chooses a filter from a given table |
| 19 | local function choose(table) | 19 | local function choose(table) |
| 20 | return function(method, ...) | 20 | return function(filter, ...) |
| 21 | local f = table[method or "nil"] | 21 | local f = table[filter or "nil"] |
| 22 | if not f then error("unknown method (" .. tostring(method) .. ")", 3) | 22 | if not f then error("unknown filter (" .. tostring(filter) .. ")", 3) |
| 23 | else return f(unpack(arg)) end | 23 | else return f(unpack(arg)) end |
| 24 | end | 24 | end |
| 25 | end | 25 | end |
| 26 | 26 | ||
| 27 | -- creates a function that cicles a filter with a given initial | 27 | -- define the encoding filters |
| 28 | -- context and extra arguments | ||
| 29 | local function cicle(f, ctx, ...) | ||
| 30 | return function(chunk) | ||
| 31 | local ret | ||
| 32 | ret, ctx = f(ctx, chunk, unpack(arg)) | ||
| 33 | return ret | ||
| 34 | end | ||
| 35 | end | ||
| 36 | |||
| 37 | -- function that choose the encoding, decoding or wrap algorithm | ||
| 38 | encode = choose(et) | ||
| 39 | decode = choose(dt) | ||
| 40 | |||
| 41 | -- the wrap filter has default parameters | ||
| 42 | local cwt = choose(wt) | ||
| 43 | function wrap(...) | ||
| 44 | if not arg[1] or type(arg[1]) ~= "string" then | ||
| 45 | table.insert(arg, 1, "base64") | ||
| 46 | end | ||
| 47 | return cwt(unpack(arg)) | ||
| 48 | end | ||
| 49 | |||
| 50 | -- define the encoding algorithms | ||
| 51 | et['base64'] = function() | 28 | et['base64'] = function() |
| 52 | return cicle(b64, "") | 29 | return socket.cicle(b64, "") |
| 53 | end | 30 | end |
| 54 | 31 | ||
| 55 | et['quoted-printable'] = function(mode) | 32 | et['quoted-printable'] = function(mode) |
| 56 | return cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10") | 33 | return socket.cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10") |
| 57 | end | 34 | end |
| 58 | 35 | ||
| 59 | -- define the decoding algorithms | 36 | -- define the decoding filters |
| 60 | dt['base64'] = function() | 37 | dt['base64'] = function() |
| 61 | return cicle(unb64, "") | 38 | return socket.cicle(unb64, "") |
| 62 | end | 39 | end |
| 63 | 40 | ||
| 64 | dt['quoted-printable'] = function() | 41 | dt['quoted-printable'] = function() |
| 65 | return cicle(unqp, "") | 42 | return socket.cicle(unqp, "") |
| 66 | end | 43 | end |
| 67 | 44 | ||
| 68 | -- define the wrap algorithms | 45 | -- define the line-wrap filters |
| 69 | wt['base64'] = function(length, marker) | 46 | wt['text'] = function(length) |
| 70 | length = length or 76 | 47 | length = length or 76 |
| 71 | return cicle(wrp, length, length, marker) | 48 | return socket.cicle(wrp, length, length) |
| 72 | end | 49 | end |
| 50 | wt['base64'] = wt['text'] | ||
| 73 | 51 | ||
| 74 | wt['quoted-printable'] = function(length) | 52 | wt['quoted-printable'] = function() |
| 75 | length = length or 76 | 53 | return socket.cicle(qpwrp, 76, 76) |
| 76 | return cicle(qpwrp, length, length) | 54 | end |
| 55 | |||
| 56 | -- function that choose the encoding, decoding or wrap algorithm | ||
| 57 | encode = choose(et) | ||
| 58 | decode = choose(dt) | ||
| 59 | -- there is a default wrap filter | ||
| 60 | local cwt = choose(wt) | ||
| 61 | function wrap(...) | ||
| 62 | if type(arg[1]) ~= "string" then table.insert(arg, 1, "text") end | ||
| 63 | return cwt(unpack(arg)) | ||
| 77 | end | 64 | end |
| 78 | 65 | ||
| 79 | -- define the end-of-line translation function | 66 | -- define the end-of-line translation filter |
| 80 | function canonic(marker) | 67 | function canonic(marker) |
| 81 | return cicle(eol, "", marker) | 68 | return socket.cicle(eol, "", marker) |
| 82 | end | 69 | end |
| 83 | 70 | ||
| 84 | -- chains several filters together | 71 | -- chains several filters together |
| @@ -104,4 +91,4 @@ function chain(...) | |||
| 104 | end | 91 | end |
| 105 | end | 92 | end |
| 106 | 93 | ||
| 107 | return code | 94 | return mime |
diff --git a/src/select.c b/src/select.c index 9769667..8590b96 100644 --- a/src/select.c +++ b/src/select.c | |||
| @@ -42,7 +42,7 @@ static luaL_reg func[] = { | |||
| 42 | /*-------------------------------------------------------------------------*\ | 42 | /*-------------------------------------------------------------------------*\ |
| 43 | * Initializes module | 43 | * Initializes module |
| 44 | \*-------------------------------------------------------------------------*/ | 44 | \*-------------------------------------------------------------------------*/ |
| 45 | void select_open(lua_State *L) | 45 | int select_open(lua_State *L) |
| 46 | { | 46 | { |
| 47 | /* get select auxiliar lua function from lua code and register | 47 | /* get select auxiliar lua function from lua code and register |
| 48 | * pass it as an upvalue to global_select */ | 48 | * pass it as an upvalue to global_select */ |
| @@ -54,6 +54,7 @@ void select_open(lua_State *L) | |||
| 54 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 1); | 54 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 1); |
| 55 | lua_pop(L, 1); | 55 | lua_pop(L, 1); |
| 56 | aux_newclass(L, "select{fd_set}", set); | 56 | aux_newclass(L, "select{fd_set}", set); |
| 57 | return 0; | ||
| 57 | } | 58 | } |
| 58 | 59 | ||
| 59 | /*=========================================================================*\ | 60 | /*=========================================================================*\ |
diff --git a/src/select.h b/src/select.h index 0e1eeb4..de10ea4 100644 --- a/src/select.h +++ b/src/select.h | |||
| @@ -15,6 +15,6 @@ | |||
| 15 | * RCS ID: $Id$ | 15 | * RCS ID: $Id$ |
| 16 | \*=========================================================================*/ | 16 | \*=========================================================================*/ |
| 17 | 17 | ||
| 18 | void select_open(lua_State *L); | 18 | int select_open(lua_State *L); |
| 19 | 19 | ||
| 20 | #endif /* SELECT_H */ | 20 | #endif /* SELECT_H */ |
diff --git a/src/smtp.lua b/src/smtp.lua index 25d7f74..8b65e44 100644 --- a/src/smtp.lua +++ b/src/smtp.lua | |||
| @@ -4,7 +4,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end | |||
| 4 | local socket = _G[LUASOCKET_LIBNAME] | 4 | local socket = _G[LUASOCKET_LIBNAME] |
| 5 | if not socket then error('module requires LuaSocket') end | 5 | if not socket then error('module requires LuaSocket') end |
| 6 | -- create smtp namespace inside LuaSocket namespace | 6 | -- create smtp namespace inside LuaSocket namespace |
| 7 | local smtp = {} | 7 | local smtp = socket.smtp or {} |
| 8 | socket.smtp = smtp | 8 | socket.smtp = smtp |
| 9 | -- make all module globals fall into smtp namespace | 9 | -- make all module globals fall into smtp namespace |
| 10 | setmetatable(smtp, { __index = _G }) | 10 | setmetatable(smtp, { __index = _G }) |
| @@ -18,6 +18,10 @@ DOMAIN = os.getenv("SERVER_NAME") or "localhost" | |||
| 18 | -- default server used to send e-mails | 18 | -- default server used to send e-mails |
| 19 | SERVER = "localhost" | 19 | SERVER = "localhost" |
| 20 | 20 | ||
| 21 | function stuff() | ||
| 22 | return socket.cicle(dot, 2) | ||
| 23 | end | ||
| 24 | |||
| 21 | -- tries to get a pattern from the server and closes socket on error | 25 | -- tries to get a pattern from the server and closes socket on error |
| 22 | local function try_receiving(connection, pattern) | 26 | local function try_receiving(connection, pattern) |
| 23 | local data, message = connection:receive(pattern) | 27 | local data, message = connection:receive(pattern) |
| @@ -39,25 +39,26 @@ static int meth_dirty(lua_State *L); | |||
| 39 | 39 | ||
| 40 | /* tcp object methods */ | 40 | /* tcp object methods */ |
| 41 | static luaL_reg tcp[] = { | 41 | static luaL_reg tcp[] = { |
| 42 | {"connect", meth_connect}, | 42 | {"__gc", meth_close}, |
| 43 | {"send", meth_send}, | 43 | {"accept", meth_accept}, |
| 44 | {"receive", meth_receive}, | ||
| 45 | {"bind", meth_bind}, | 44 | {"bind", meth_bind}, |
| 45 | {"close", meth_close}, | ||
| 46 | {"connect", meth_connect}, | ||
| 47 | {"dirty", meth_dirty}, | ||
| 48 | {"getfd", meth_getfd}, | ||
| 49 | {"getpeername", meth_getpeername}, | ||
| 50 | {"getsockname", meth_getsockname}, | ||
| 46 | {"listen", meth_listen}, | 51 | {"listen", meth_listen}, |
| 47 | {"accept", meth_accept}, | 52 | {"receive", meth_receive}, |
| 53 | {"send", meth_send}, | ||
| 54 | {"setfd", meth_setfd}, | ||
| 55 | {"setoption", meth_setoption}, | ||
| 48 | {"setpeername", meth_connect}, | 56 | {"setpeername", meth_connect}, |
| 49 | {"setsockname", meth_bind}, | 57 | {"setsockname", meth_bind}, |
| 50 | {"getpeername", meth_getpeername}, | ||
| 51 | {"getsockname", meth_getsockname}, | ||
| 52 | {"settimeout", meth_settimeout}, | 58 | {"settimeout", meth_settimeout}, |
| 53 | {"close", meth_close}, | ||
| 54 | {"shutdown", meth_shutdown}, | 59 | {"shutdown", meth_shutdown}, |
| 55 | {"setoption", meth_setoption}, | ||
| 56 | {"__gc", meth_close}, | ||
| 57 | {"getfd", meth_getfd}, | ||
| 58 | {"setfd", meth_setfd}, | ||
| 59 | {"dirty", meth_dirty}, | ||
| 60 | {NULL, NULL} | 60 | {NULL, NULL} |
| 61 | |||
| 61 | }; | 62 | }; |
| 62 | 63 | ||
| 63 | /* socket option handlers */ | 64 | /* socket option handlers */ |
| @@ -78,7 +79,7 @@ static luaL_reg func[] = { | |||
| 78 | /*-------------------------------------------------------------------------*\ | 79 | /*-------------------------------------------------------------------------*\ |
| 79 | * Initializes module | 80 | * Initializes module |
| 80 | \*-------------------------------------------------------------------------*/ | 81 | \*-------------------------------------------------------------------------*/ |
| 81 | void tcp_open(lua_State *L) | 82 | int tcp_open(lua_State *L) |
| 82 | { | 83 | { |
| 83 | /* create classes */ | 84 | /* create classes */ |
| 84 | aux_newclass(L, "tcp{master}", tcp); | 85 | aux_newclass(L, "tcp{master}", tcp); |
| @@ -96,6 +97,7 @@ void tcp_open(lua_State *L) | |||
| 96 | /* define library functions */ | 97 | /* define library functions */ |
| 97 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 98 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
| 98 | lua_pop(L, 1); | 99 | lua_pop(L, 1); |
| 100 | return 0; | ||
| 99 | } | 101 | } |
| 100 | 102 | ||
| 101 | /*=========================================================================*\ | 103 | /*=========================================================================*\ |
| @@ -250,7 +252,7 @@ static int meth_listen(lua_State *L) | |||
| 250 | \*-------------------------------------------------------------------------*/ | 252 | \*-------------------------------------------------------------------------*/ |
| 251 | static int meth_shutdown(lua_State *L) | 253 | static int meth_shutdown(lua_State *L) |
| 252 | { | 254 | { |
| 253 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); | 255 | p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client}", 1); |
| 254 | const char *how = luaL_optstring(L, 2, "both"); | 256 | const char *how = luaL_optstring(L, 2, "both"); |
| 255 | switch (how[0]) { | 257 | switch (how[0]) { |
| 256 | case 'b': | 258 | case 'b': |
| @@ -266,7 +268,8 @@ static int meth_shutdown(lua_State *L) | |||
| 266 | sock_shutdown(&tcp->sock, 0); | 268 | sock_shutdown(&tcp->sock, 0); |
| 267 | break; | 269 | break; |
| 268 | } | 270 | } |
| 269 | return 0; | 271 | lua_pushnumber(L, 1); |
| 272 | return 1; | ||
| 270 | error: | 273 | error: |
| 271 | luaL_argerror(L, 2, "invalid shutdown method"); | 274 | luaL_argerror(L, 2, "invalid shutdown method"); |
| 272 | return 0; | 275 | return 0; |
| @@ -31,6 +31,6 @@ typedef struct t_tcp_ { | |||
| 31 | 31 | ||
| 32 | typedef t_tcp *p_tcp; | 32 | typedef t_tcp *p_tcp; |
| 33 | 33 | ||
| 34 | void tcp_open(lua_State *L); | 34 | int tcp_open(lua_State *L); |
| 35 | 35 | ||
| 36 | #endif /* TCP_H */ | 36 | #endif /* TCP_H */ |
diff --git a/src/timeout.c b/src/timeout.c index 83bffc9..73a1146 100644 --- a/src/timeout.c +++ b/src/timeout.c | |||
| @@ -141,10 +141,11 @@ int tm_gettime(void) | |||
| 141 | /*-------------------------------------------------------------------------*\ | 141 | /*-------------------------------------------------------------------------*\ |
| 142 | * Initializes module | 142 | * Initializes module |
| 143 | \*-------------------------------------------------------------------------*/ | 143 | \*-------------------------------------------------------------------------*/ |
| 144 | void tm_open(lua_State *L) | 144 | int tm_open(lua_State *L) |
| 145 | { | 145 | { |
| 146 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 146 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
| 147 | lua_pop(L, 1); | 147 | lua_pop(L, 1); |
| 148 | return 0; | ||
| 148 | } | 149 | } |
| 149 | 150 | ||
| 150 | /*-------------------------------------------------------------------------*\ | 151 | /*-------------------------------------------------------------------------*\ |
diff --git a/src/timeout.h b/src/timeout.h index 6584a8e..6b105c3 100644 --- a/src/timeout.h +++ b/src/timeout.h | |||
| @@ -16,7 +16,7 @@ typedef struct t_tm_ { | |||
| 16 | } t_tm; | 16 | } t_tm; |
| 17 | typedef t_tm *p_tm; | 17 | typedef t_tm *p_tm; |
| 18 | 18 | ||
| 19 | void tm_open(lua_State *L); | 19 | int tm_open(lua_State *L); |
| 20 | void tm_init(p_tm tm, int block, int total); | 20 | void tm_init(p_tm tm, int block, int total); |
| 21 | int tm_get(p_tm tm); | 21 | int tm_get(p_tm tm); |
| 22 | int tm_getretry(p_tm tm); | 22 | int tm_getretry(p_tm tm); |
| @@ -30,7 +30,6 @@ static int meth_getpeername(lua_State *L); | |||
| 30 | static int meth_setsockname(lua_State *L); | 30 | static int meth_setsockname(lua_State *L); |
| 31 | static int meth_setpeername(lua_State *L); | 31 | static int meth_setpeername(lua_State *L); |
| 32 | static int meth_close(lua_State *L); | 32 | static int meth_close(lua_State *L); |
| 33 | static int meth_shutdown(lua_State *L); | ||
| 34 | static int meth_setoption(lua_State *L); | 33 | static int meth_setoption(lua_State *L); |
| 35 | static int meth_settimeout(lua_State *L); | 34 | static int meth_settimeout(lua_State *L); |
| 36 | static int meth_getfd(lua_State *L); | 35 | static int meth_getfd(lua_State *L); |
| @@ -49,7 +48,6 @@ static luaL_reg udp[] = { | |||
| 49 | {"receivefrom", meth_receivefrom}, | 48 | {"receivefrom", meth_receivefrom}, |
| 50 | {"settimeout", meth_settimeout}, | 49 | {"settimeout", meth_settimeout}, |
| 51 | {"close", meth_close}, | 50 | {"close", meth_close}, |
| 52 | {"shutdown", meth_shutdown}, | ||
| 53 | {"setoption", meth_setoption}, | 51 | {"setoption", meth_setoption}, |
| 54 | {"__gc", meth_close}, | 52 | {"__gc", meth_close}, |
| 55 | {"getfd", meth_getfd}, | 53 | {"getfd", meth_getfd}, |
| @@ -79,7 +77,7 @@ static luaL_reg func[] = { | |||
| 79 | /*-------------------------------------------------------------------------*\ | 77 | /*-------------------------------------------------------------------------*\ |
| 80 | * Initializes module | 78 | * Initializes module |
| 81 | \*-------------------------------------------------------------------------*/ | 79 | \*-------------------------------------------------------------------------*/ |
| 82 | void udp_open(lua_State *L) | 80 | int udp_open(lua_State *L) |
| 83 | { | 81 | { |
| 84 | /* create classes */ | 82 | /* create classes */ |
| 85 | aux_newclass(L, "udp{connected}", udp); | 83 | aux_newclass(L, "udp{connected}", udp); |
| @@ -92,6 +90,7 @@ void udp_open(lua_State *L) | |||
| 92 | /* define library functions */ | 90 | /* define library functions */ |
| 93 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); | 91 | luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); |
| 94 | lua_pop(L, 1); | 92 | lua_pop(L, 1); |
| 93 | return 0; | ||
| 95 | } | 94 | } |
| 96 | 95 | ||
| 97 | /*=========================================================================*\ | 96 | /*=========================================================================*\ |
| @@ -288,33 +287,6 @@ static int meth_close(lua_State *L) | |||
| 288 | } | 287 | } |
| 289 | 288 | ||
| 290 | /*-------------------------------------------------------------------------*\ | 289 | /*-------------------------------------------------------------------------*\ |
| 291 | * Shuts the connection down partially | ||
| 292 | \*-------------------------------------------------------------------------*/ | ||
| 293 | static int meth_shutdown(lua_State *L) | ||
| 294 | { | ||
| 295 | p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); | ||
| 296 | const char *how = luaL_optstring(L, 2, "both"); | ||
| 297 | switch (how[0]) { | ||
| 298 | case 'b': | ||
| 299 | if (strcmp(how, "both")) goto error; | ||
| 300 | sock_shutdown(&udp->sock, 2); | ||
| 301 | break; | ||
| 302 | case 's': | ||
| 303 | if (strcmp(how, "send")) goto error; | ||
| 304 | sock_shutdown(&udp->sock, 1); | ||
| 305 | break; | ||
| 306 | case 'r': | ||
| 307 | if (strcmp(how, "receive")) goto error; | ||
| 308 | sock_shutdown(&udp->sock, 0); | ||
| 309 | break; | ||
| 310 | } | ||
| 311 | return 0; | ||
| 312 | error: | ||
| 313 | luaL_argerror(L, 2, "invalid shutdown method"); | ||
| 314 | return 0; | ||
| 315 | } | ||
| 316 | |||
| 317 | /*-------------------------------------------------------------------------*\ | ||
| 318 | * Turns a master object into a server object | 290 | * Turns a master object into a server object |
| 319 | \*-------------------------------------------------------------------------*/ | 291 | \*-------------------------------------------------------------------------*/ |
| 320 | static int meth_setsockname(lua_State *L) | 292 | static int meth_setsockname(lua_State *L) |
| @@ -27,6 +27,6 @@ typedef struct t_udp_ { | |||
| 27 | } t_udp; | 27 | } t_udp; |
| 28 | typedef t_udp *p_udp; | 28 | typedef t_udp *p_udp; |
| 29 | 29 | ||
| 30 | void udp_open(lua_State *L); | 30 | int udp_open(lua_State *L); |
| 31 | 31 | ||
| 32 | #endif /* UDP_H */ | 32 | #endif /* UDP_H */ |
diff --git a/src/url.lua b/src/url.lua index ab3a922..de0474b 100644 --- a/src/url.lua +++ b/src/url.lua | |||
| @@ -12,7 +12,7 @@ if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end | |||
| 12 | local socket = _G[LUASOCKET_LIBNAME] | 12 | local socket = _G[LUASOCKET_LIBNAME] |
| 13 | if not socket then error('module requires LuaSocket') end | 13 | if not socket then error('module requires LuaSocket') end |
| 14 | -- create smtp namespace inside LuaSocket namespace | 14 | -- create smtp namespace inside LuaSocket namespace |
| 15 | local url = {} | 15 | local url = socket.url or {} |
| 16 | socket.url = url | 16 | socket.url = url |
| 17 | -- make all module globals fall into smtp namespace | 17 | -- make all module globals fall into smtp namespace |
| 18 | setmetatable(url, { __index = _G }) | 18 | setmetatable(url, { __index = _G }) |
diff --git a/src/usocket.c b/src/usocket.c index bece354..eb1a49a 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
| @@ -70,12 +70,10 @@ int sock_select(int n, fd_set *rfds, fd_set *wfds, fd_set *efds, int timeout) | |||
| 70 | \*-------------------------------------------------------------------------*/ | 70 | \*-------------------------------------------------------------------------*/ |
| 71 | const char *sock_create(p_sock ps, int domain, int type, int protocol) | 71 | const char *sock_create(p_sock ps, int domain, int type, int protocol) |
| 72 | { | 72 | { |
| 73 | int val = 1; | ||
| 74 | t_sock sock = socket(domain, type, protocol); | 73 | t_sock sock = socket(domain, type, protocol); |
| 75 | if (sock == SOCK_INVALID) return sock_createstrerror(errno); | 74 | if (sock == SOCK_INVALID) return sock_createstrerror(errno); |
| 76 | *ps = sock; | 75 | *ps = sock; |
| 77 | sock_setnonblocking(ps); | 76 | sock_setnonblocking(ps); |
| 78 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); | ||
| 79 | return NULL; | 77 | return NULL; |
| 80 | } | 78 | } |
| 81 | 79 | ||
| @@ -167,13 +165,14 @@ const char *sock_accept(p_sock ps, p_sock pa, SA *addr, | |||
| 167 | for (;;) { | 165 | for (;;) { |
| 168 | int err; | 166 | int err; |
| 169 | fd_set fds; | 167 | fd_set fds; |
| 168 | /* try to accept */ | ||
| 170 | *pa = accept(sock, addr, addr_len); | 169 | *pa = accept(sock, addr, addr_len); |
| 171 | /* if result is valid, we are done */ | 170 | /* if result is valid, we are done */ |
| 172 | if (*pa != SOCK_INVALID) return NULL; | 171 | if (*pa != SOCK_INVALID) return NULL; |
| 173 | /* find out if we failed for a fatal reason */ | 172 | /* find out if we failed for a fatal reason */ |
| 174 | if (errno != EWOULDBLOCK && errno != ECONNABORTED) | 173 | if (errno != EWOULDBLOCK && errno != ECONNABORTED) |
| 175 | return sock_acceptstrerror(errno); | 174 | return sock_acceptstrerror(errno); |
| 176 | /* call select just to avoid busy-wait. */ | 175 | /* call select to avoid busy-wait. */ |
| 177 | FD_ZERO(&fds); | 176 | FD_ZERO(&fds); |
| 178 | FD_SET(sock, &fds); | 177 | FD_SET(sock, &fds); |
| 179 | do err = sock_select(sock+1, &fds, NULL, NULL, tm_getretry(tm)); | 178 | do err = sock_select(sock+1, &fds, NULL, NULL, tm_getretry(tm)); |
diff --git a/src/wsocket.c b/src/wsocket.c index f33e154..fcd2fff 100644 --- a/src/wsocket.c +++ b/src/wsocket.c | |||
| @@ -75,12 +75,10 @@ void sock_shutdown(p_sock ps, int how) | |||
| 75 | \*-------------------------------------------------------------------------*/ | 75 | \*-------------------------------------------------------------------------*/ |
| 76 | const char *sock_create(p_sock ps, int domain, int type, int protocol) | 76 | const char *sock_create(p_sock ps, int domain, int type, int protocol) |
| 77 | { | 77 | { |
| 78 | int val = 1; | ||
| 79 | t_sock sock = socket(domain, type, protocol); | 78 | t_sock sock = socket(domain, type, protocol); |
| 80 | if (sock == SOCK_INVALID) | 79 | if (sock == SOCK_INVALID) |
| 81 | return sock_createstrerror(WSAGetLastError()); | 80 | return sock_createstrerror(WSAGetLastError()); |
| 82 | *ps = sock; | 81 | *ps = sock; |
| 83 | setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); | ||
| 84 | sock_setnonblocking(ps); | 82 | sock_setnonblocking(ps); |
| 85 | return NULL; | 83 | return NULL; |
| 86 | } | 84 | } |
| @@ -112,8 +110,12 @@ const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm) | |||
| 112 | /* if was in efds, we failed */ | 110 | /* if was in efds, we failed */ |
| 113 | if (FD_ISSET(sock, &efds)) { | 111 | if (FD_ISSET(sock, &efds)) { |
| 114 | int why, len = sizeof(why); | 112 | int why, len = sizeof(why); |
| 113 | /* give windows time to set the error (disgusting) */ | ||
| 114 | Sleep(0); | ||
| 115 | /* find out why we failed */ | 115 | /* find out why we failed */ |
| 116 | getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len); | 116 | getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len); |
| 117 | /* we KNOW there was an error. if why is 0, we will return | ||
| 118 | * "unknown error", but it's not really our fault */ | ||
| 117 | return sock_connectstrerror(why); | 119 | return sock_connectstrerror(why); |
| 118 | /* otherwise it must be in wfds, so we succeeded */ | 120 | /* otherwise it must be in wfds, so we succeeded */ |
| 119 | } else return NULL; | 121 | } else return NULL; |
