From 0b2542d1a61fc5425ff65ab3dbf7ba7de174763f Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Wed, 4 Feb 2004 14:29:11 +0000 Subject: Worked on the manual. Implemented stuffing (needs test) Added cddb and qp examples. --- src/auxiliar.c | 14 +++++- src/auxiliar.h | 3 +- src/buffer.c | 3 +- src/buffer.h | 2 +- src/ftp.lua | 2 + src/http.lua | 2 +- src/inet.c | 9 +--- src/inet.h | 2 +- src/luasocket.c | 50 ++++++++++++++------ src/mime.c | 138 ++++++++++++++++++++++++++------------------------------ src/mime.h | 2 +- src/mime.lua | 71 ++++++++++++----------------- src/select.c | 3 +- src/select.h | 2 +- src/smtp.lua | 6 ++- src/tcp.c | 33 ++++++++------ src/tcp.h | 2 +- src/timeout.c | 3 +- src/timeout.h | 2 +- src/udp.c | 32 +------------ src/udp.h | 2 +- src/url.lua | 2 +- src/usocket.c | 5 +- src/wsocket.c | 6 ++- 24 files changed, 192 insertions(+), 204 deletions(-) (limited to 'src') 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: /*-------------------------------------------------------------------------*\ * Initializes the module \*-------------------------------------------------------------------------*/ -void aux_open(lua_State *L) +int aux_open(lua_State *L) { - ; + return 0; } /*-------------------------------------------------------------------------*\ @@ -159,3 +159,13 @@ void *aux_getclassudata(lua_State *L, const char *classname, int objidx) return luaL_checkudata(L, objidx, classname); } +/*-------------------------------------------------------------------------*\ +* Accept "false" as nil +\*-------------------------------------------------------------------------*/ +const char *aux_optlstring(lua_State *L, int n, const char *v, size_t *l) +{ + if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { + *l = 0; + return NULL; + } else return luaL_optlstring(L, n, v, l); +} 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 @@ #define MAX(x, y) ((x) > (y) ? x : y) #endif -void aux_open(lua_State *L); +int aux_open(lua_State *L); void aux_newclass(lua_State *L, const char *classname, luaL_reg *func); void aux_add2group(lua_State *L, const char *classname, const char *group); 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); void *aux_getclassudata(lua_State *L, const char *groupname, int objidx); void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx); int aux_checkboolean(lua_State *L, int objidx); +const char *aux_optlstring(lua_State *L, int n, const char *v, size_t *l); #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); /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -void buf_open(lua_State *L) +int buf_open(lua_State *L) { (void) L; + return 0; } /*-------------------------------------------------------------------------*\ 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_ { } t_buf; typedef t_buf *p_buf; -void buf_open(lua_State *L); +int buf_open(lua_State *L); void buf_init(p_buf buf, p_io io, p_tm tm); int buf_meth_send(lua_State *L, p_buf buf); 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) local err = Public.get_cb(request) return concat:getresult(), err end + +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 local socket = _G[LUASOCKET_LIBNAME] if not socket then error('module requires LuaSocket') end -- create smtp namespace inside LuaSocket namespace -local http = {} +local http = socket.http or {} socket.http = http -- make all module globals fall into smtp namespace setmetatable(http, { __index = _G }) diff --git a/src/inet.c b/src/inet.c index d626b86..096e2e3 100644 --- a/src/inet.c +++ b/src/inet.c @@ -35,17 +35,10 @@ static luaL_reg func[] = { /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -void inet_open(lua_State *L) +int inet_open(lua_State *L) { lua_pushstring(L, LUASOCKET_LIBNAME); lua_gettable(L, LUA_GLOBALSINDEX); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); - lua_newtable(L); - lua_pushstring(L, LUASOCKET_LIBNAME); - lua_pushvalue(L, -2); - lua_settable(L, LUA_GLOBALSINDEX); - } lua_pushstring(L, "dns"); lua_newtable(L); luaL_openlib(L, NULL, func, 0); diff --git a/src/inet.h b/src/inet.h index 87da23a..92e16f8 100644 --- a/src/inet.h +++ b/src/inet.h @@ -24,7 +24,7 @@ #define INET_ATON #endif -void inet_open(lua_State *L); +int inet_open(lua_State *L); const char *inet_trycreate(p_sock ps, int type); 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 @@ #include "tcp.h" #include "udp.h" #include "select.h" +#include "smtp.h" #include "mime.h" /*=========================================================================*\ * Declarations \*=========================================================================*/ static int base_open(lua_State *L); +static int mod_open(lua_State *L, const luaL_reg *mod); /*-------------------------------------------------------------------------*\ * Setup basic stuff. @@ -66,22 +68,9 @@ static int base_open(lua_State *L) return 0; } -/*-------------------------------------------------------------------------*\ -* Initializes all library modules. -\*-------------------------------------------------------------------------*/ -LUASOCKET_API int luaopen_socket(lua_State *L) +static int mod_open(lua_State *L, const luaL_reg *mod) { - if (!sock_open()) return 0; - /* initialize all modules */ - base_open(L); - aux_open(L); - tm_open(L); - buf_open(L); - inet_open(L); - tcp_open(L); - udp_open(L); - select_open(L); - mime_open(L); + for (; mod->name; mod++) mod->func(L); #ifdef LUASOCKET_COMPILED #include "auxiliar.lch" #include "concat.lch" @@ -101,5 +90,36 @@ LUASOCKET_API int luaopen_socket(lua_State *L) lua_dofile(L, "ftp.lua"); lua_dofile(L, "http.lua"); #endif + return 0; +} + +/*-------------------------------------------------------------------------*\ +* Modules +\*-------------------------------------------------------------------------*/ +static const luaL_reg mod[] = { + {"base", base_open}, + {"aux", aux_open}, + {"tm", tm_open}, + {"buf", buf_open}, + {"inet", inet_open}, + {"tcp", tcp_open}, + {"udp", udp_open}, + {"select", select_open}, + {"mime", mime_open}, + {"smtp", smtp_open}, + {NULL, NULL} +}; + +/*-------------------------------------------------------------------------*\ +* Initializes all library modules. +\*-------------------------------------------------------------------------*/ +LUASOCKET_API int luaopen_socket(lua_State *L) +{ + if (!sock_open()) { + lua_pushnil(L); + lua_pushstring(L, "unable to initialize library"); + return 2; + } + mod_open(L, mod); return 1; } diff --git a/src/mime.c b/src/mime.c index 95cd400..9fc4f51 100644 --- a/src/mime.c +++ b/src/mime.c @@ -10,6 +10,7 @@ #include #include "luasocket.h" +#include "auxiliar.h" #include "mime.h" /*=========================================================================*\ @@ -45,18 +46,16 @@ 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 const char *checklstring(lua_State *L, int n, size_t *l); -static const char *optlstring(lua_State *L, int n, const char *v, size_t *l); +static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer); /* code support functions */ static luaL_reg func[] = { + { "b64", mime_global_b64 }, { "eol", mime_global_eol }, { "qp", mime_global_qp }, - { "unqp", mime_global_unqp }, { "qpwrp", mime_global_qpwrp }, - { "b64", mime_global_b64 }, { "unb64", mime_global_unb64 }, + { "unqp", mime_global_unqp }, { "wrp", mime_global_wrp }, { NULL, NULL } }; @@ -82,17 +81,10 @@ static UC b64unbase[256]; /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -void mime_open(lua_State *L) +int mime_open(lua_State *L) { lua_pushstring(L, LUASOCKET_LIBNAME); lua_gettable(L, LUA_GLOBALSINDEX); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); - lua_newtable(L); - lua_pushstring(L, LUASOCKET_LIBNAME); - lua_pushvalue(L, -2); - lua_settable(L, LUA_GLOBALSINDEX); - } lua_pushstring(L, "mime"); lua_newtable(L); luaL_openlib(L, NULL, func, 0); @@ -101,25 +93,7 @@ void mime_open(lua_State *L) /* initialize lookup tables */ qpsetup(qpclass, qpunbase); b64setup(b64unbase); -} - -/*-------------------------------------------------------------------------*\ -* Check if a string was provided. We accept false also. -\*-------------------------------------------------------------------------*/ -static const char *checklstring(lua_State *L, int n, size_t *l) -{ - if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { - *l = 0; - return NULL; - } else return luaL_checklstring(L, n, l); -} - -static const char *optlstring(lua_State *L, int n, const char *v, size_t *l) -{ - if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { - *l = 0; - return NULL; - } else return luaL_optlstring(L, n, v, l); + return 0; } /*=========================================================================*\ @@ -127,31 +101,42 @@ static const char *optlstring(lua_State *L, int n, const char *v, size_t *l) \*=========================================================================*/ /*-------------------------------------------------------------------------*\ * Incrementaly breaks a string into lines -* A, n = wrp(l, B, length, marker) +* 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. -* Marker is the end-of-line marker. \*-------------------------------------------------------------------------*/ static int mime_global_wrp(lua_State *L) { size_t size = 0; int left = (int) luaL_checknumber(L, 1); - const UC *input = (UC *) checklstring(L, 2, &size); + const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size); const UC *last = input + size; int length = (int) luaL_optnumber(L, 3, 76); - const char *marker = luaL_optstring(L, 4, CRLF); luaL_Buffer buffer; luaL_buffinit(L, &buffer); while (input < last) { - luaL_putchar(&buffer, *input++); - if (--left <= 0) { - luaL_addstring(&buffer, marker); - left = length; + switch (*input) { + case CR: + break; + case LF: + luaL_addstring(&buffer, CRLF); + left = length; + break; + default: + if (left <= 0) { + left = length; + luaL_addstring(&buffer, CRLF); + } + luaL_putchar(&buffer, *input); + left--; + break; } + input++; } + /* if in last chunk and last line wasn't terminated, add a line-break */ if (!input && left < length) { - luaL_addstring(&buffer, marker); + luaL_addstring(&buffer, CRLF); left = length; } luaL_pushresult(&buffer); @@ -235,7 +220,6 @@ static size_t b64pad(const UC *input, size_t size, 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; @@ -277,7 +261,7 @@ static int mime_global_b64(lua_State *L) luaL_buffinit(L, &buffer); while (input < last) asize = b64encode(*input++, atom, asize, &buffer); - input = (UC *) optlstring(L, 2, NULL, &isize); + input = (UC *) aux_optlstring(L, 2, NULL, &isize); if (input) { last = input + isize; while (input < last) @@ -305,12 +289,14 @@ static int mime_global_unb64(lua_State *L) luaL_buffinit(L, &buffer); while (input < last) asize = b64decode(*input++, atom, asize, &buffer); - input = (UC *) optlstring(L, 2, NULL, &isize); + input = (UC *) aux_optlstring(L, 2, NULL, &isize); if (input) { last = input + isize; while (input < last) asize = b64decode(*input++, atom, asize, &buffer); } + /* if !input we are done. if atom > 0, the remaning is invalid. we just + * return it undecoded. */ luaL_pushresult(&buffer); lua_pushlstring(L, (char *) atom, asize); return 2; @@ -416,7 +402,7 @@ static size_t qpencode(UC c, UC *input, size_t size, /*-------------------------------------------------------------------------*\ * Deal with the final characters \*-------------------------------------------------------------------------*/ -static void qppad(UC *input, size_t size, luaL_Buffer *buffer) +static size_t qppad(UC *input, size_t size, luaL_Buffer *buffer) { size_t i; for (i = 0; i < size; i++) { @@ -424,12 +410,13 @@ static void qppad(UC *input, size_t size, luaL_Buffer *buffer) else qpquote(input[i], buffer); } luaL_addstring(buffer, EQCRLF); + return 0; } /*-------------------------------------------------------------------------*\ * Incrementally converts a string to quoted-printable * A, B = qp(C, D, marker) -* Crlf is the text to be used to replace CRLF sequences found in A. +* 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. @@ -439,19 +426,20 @@ static int mime_global_qp(lua_State *L) size_t asize = 0, isize = 0; UC atom[3]; - const UC *input = (UC *) checklstring(L, 1, &isize); + const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; const char *marker = luaL_optstring(L, 3, CRLF); luaL_Buffer buffer; luaL_buffinit(L, &buffer); while (input < last) asize = qpencode(*input++, atom, asize, marker, &buffer); - input = (UC *) optlstring(L, 2, NULL, &isize); + input = (UC *) aux_optlstring(L, 2, NULL, &isize); if (input) { last = input + isize; while (input < last) asize = qpencode(*input++, atom, asize, marker, &buffer); - } else qppad(atom, asize, &buffer); + } else + asize = qppad(atom, asize, &buffer); luaL_pushresult(&buffer); lua_pushlstring(L, (char *) atom, asize); return 2; @@ -507,13 +495,13 @@ static int mime_global_unqp(lua_State *L) size_t asize = 0, isize = 0; UC atom[3]; - const UC *input = (UC *) checklstring(L, 1, &isize); + const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; luaL_Buffer buffer; luaL_buffinit(L, &buffer); while (input < last) asize = qpdecode(*input++, atom, asize, &buffer); - input = (UC *) optlstring(L, 2, NULL, &isize); + input = (UC *) aux_optlstring(L, 2, NULL, &isize); if (input) { last = input + isize; while (input < last) @@ -537,38 +525,39 @@ static int mime_global_qpwrp(lua_State *L) { size_t size = 0; int left = (int) luaL_checknumber(L, 1); - const UC *input = (UC *) checklstring(L, 2, &size); + const UC *input = (UC *) aux_optlstring(L, 2, NULL, &size); const UC *last = input + size; int length = (int) luaL_optnumber(L, 3, 76); luaL_Buffer buffer; luaL_buffinit(L, &buffer); while (input < last) { - left--; switch (*input) { - case '=': - /* if there's no room in this line for the quoted char, - * output a soft line break now */ - if (left <= 3) { - luaL_addstring(&buffer, EQCRLF); - left = length; - } - break; - /* \r\n starts a new line */ - case CR: + case CR: break; case LF: left = length; + luaL_addstring(&buffer, CRLF); break; - default: - /* if in last column, output a soft line break */ - if (left <= 1) { + case '=': + if (left <= 3) { + left = length; luaL_addstring(&buffer, EQCRLF); + } + luaL_putchar(&buffer, *input); + left--; + break; + default: + if (left <= 1) { left = length; + luaL_addstring(&buffer, EQCRLF); } + luaL_putchar(&buffer, *input); + left--; + break; } - luaL_putchar(&buffer, *input); input++; } + /* if in last chunk and last line wasn't terminated, add a soft-break */ if (!input && left < length) { luaL_addstring(&buffer, EQCRLF); left = length; @@ -579,10 +568,10 @@ static int mime_global_qpwrp(lua_State *L) } /*-------------------------------------------------------------------------*\ -* Here is what we do: \n, \r and \f are considered candidates for line +* 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, \r\r and \f\f will issue two -* end of line markers each, but \r\n, \n\r, \r\f etc will only issue *one* +* 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. \*-------------------------------------------------------------------------*/ @@ -616,21 +605,24 @@ static int mime_global_eol(lua_State *L) { size_t asize = 0, isize = 0; UC atom[2]; - const UC *input = (UC *) checklstring(L, 1, &isize); + const UC *input = (UC *) aux_optlstring(L, 1, NULL, &isize); const UC *last = input + isize; const char *marker = luaL_optstring(L, 3, CRLF); luaL_Buffer buffer; luaL_buffinit(L, &buffer); while (input < last) asize = eolconvert(*input++, atom, asize, marker, &buffer); - input = (UC *) optlstring(L, 2, NULL, &isize); + input = (UC *) aux_optlstring(L, 2, NULL, &isize); if (input) { last = input + isize; while (input < last) asize = eolconvert(*input++, atom, asize, marker, &buffer); /* if there is something in atom, it's one character, and it * is a candidate. so we output a new line */ - } else if (asize > 0) luaL_addstring(&buffer, marker); + } else if (asize > 0) { + luaL_addstring(&buffer, marker); + asize = 0; + } luaL_pushresult(&buffer); lua_pushlstring(L, (char *) atom, asize); return 2; diff --git a/src/mime.h b/src/mime.h index 8323783..b91f735 100644 --- a/src/mime.h +++ b/src/mime.h @@ -12,6 +12,6 @@ \*=========================================================================*/ #include -void mime_open(lua_State *L); +int mime_open(lua_State *L); #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 = {} local dt = {} local wt = {} --- creates a function that chooses an algorithm from a given table +-- creates a function that chooses a filter from a given table local function choose(table) - return function(method, ...) - local f = table[method or "nil"] - if not f then error("unknown method (" .. tostring(method) .. ")", 3) + return function(filter, ...) + local f = table[filter or "nil"] + if not f then error("unknown filter (" .. tostring(filter) .. ")", 3) else return f(unpack(arg)) end end end --- creates a function that cicles a filter with a given initial --- context and extra arguments -local function cicle(f, ctx, ...) - return function(chunk) - local ret - ret, ctx = f(ctx, chunk, unpack(arg)) - return ret - end -end - --- function that choose the encoding, decoding or wrap algorithm -encode = choose(et) -decode = choose(dt) - --- the wrap filter has default parameters -local cwt = choose(wt) -function wrap(...) - if not arg[1] or type(arg[1]) ~= "string" then - table.insert(arg, 1, "base64") - end - return cwt(unpack(arg)) -end - --- define the encoding algorithms +-- define the encoding filters et['base64'] = function() - return cicle(b64, "") + return socket.cicle(b64, "") end et['quoted-printable'] = function(mode) - return cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10") + return socket.cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10") end --- define the decoding algorithms +-- define the decoding filters dt['base64'] = function() - return cicle(unb64, "") + return socket.cicle(unb64, "") end dt['quoted-printable'] = function() - return cicle(unqp, "") + return socket.cicle(unqp, "") end --- define the wrap algorithms -wt['base64'] = function(length, marker) +-- define the line-wrap filters +wt['text'] = function(length) length = length or 76 - return cicle(wrp, length, length, marker) + return socket.cicle(wrp, length, length) end +wt['base64'] = wt['text'] -wt['quoted-printable'] = function(length) - length = length or 76 - return cicle(qpwrp, length, length) +wt['quoted-printable'] = function() + return socket.cicle(qpwrp, 76, 76) +end + +-- function that choose the encoding, decoding or wrap algorithm +encode = choose(et) +decode = choose(dt) +-- there is a default wrap filter +local cwt = choose(wt) +function wrap(...) + if type(arg[1]) ~= "string" then table.insert(arg, 1, "text") end + return cwt(unpack(arg)) end --- define the end-of-line translation function +-- define the end-of-line translation filter function canonic(marker) - return cicle(eol, "", marker) + return socket.cicle(eol, "", marker) end -- chains several filters together @@ -104,4 +91,4 @@ function chain(...) end end -return code +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[] = { /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -void select_open(lua_State *L) +int select_open(lua_State *L) { /* get select auxiliar lua function from lua code and register * pass it as an upvalue to global_select */ @@ -54,6 +54,7 @@ void select_open(lua_State *L) luaL_openlib(L, LUASOCKET_LIBNAME, func, 1); lua_pop(L, 1); aux_newclass(L, "select{fd_set}", set); + return 0; } /*=========================================================================*\ 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 @@ * RCS ID: $Id$ \*=========================================================================*/ -void select_open(lua_State *L); +int select_open(lua_State *L); #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 local socket = _G[LUASOCKET_LIBNAME] if not socket then error('module requires LuaSocket') end -- create smtp namespace inside LuaSocket namespace -local smtp = {} +local smtp = socket.smtp or {} socket.smtp = smtp -- make all module globals fall into smtp namespace setmetatable(smtp, { __index = _G }) @@ -18,6 +18,10 @@ DOMAIN = os.getenv("SERVER_NAME") or "localhost" -- default server used to send e-mails SERVER = "localhost" +function stuff() + return socket.cicle(dot, 2) +end + -- tries to get a pattern from the server and closes socket on error local function try_receiving(connection, pattern) local data, message = connection:receive(pattern) diff --git a/src/tcp.c b/src/tcp.c index 4b3b0cc..46efac2 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -39,25 +39,26 @@ static int meth_dirty(lua_State *L); /* tcp object methods */ static luaL_reg tcp[] = { - {"connect", meth_connect}, - {"send", meth_send}, - {"receive", meth_receive}, + {"__gc", meth_close}, + {"accept", meth_accept}, {"bind", meth_bind}, + {"close", meth_close}, + {"connect", meth_connect}, + {"dirty", meth_dirty}, + {"getfd", meth_getfd}, + {"getpeername", meth_getpeername}, + {"getsockname", meth_getsockname}, {"listen", meth_listen}, - {"accept", meth_accept}, + {"receive", meth_receive}, + {"send", meth_send}, + {"setfd", meth_setfd}, + {"setoption", meth_setoption}, {"setpeername", meth_connect}, {"setsockname", meth_bind}, - {"getpeername", meth_getpeername}, - {"getsockname", meth_getsockname}, {"settimeout", meth_settimeout}, - {"close", meth_close}, {"shutdown", meth_shutdown}, - {"setoption", meth_setoption}, - {"__gc", meth_close}, - {"getfd", meth_getfd}, - {"setfd", meth_setfd}, - {"dirty", meth_dirty}, {NULL, NULL} + }; /* socket option handlers */ @@ -78,7 +79,7 @@ static luaL_reg func[] = { /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -void tcp_open(lua_State *L) +int tcp_open(lua_State *L) { /* create classes */ aux_newclass(L, "tcp{master}", tcp); @@ -96,6 +97,7 @@ void tcp_open(lua_State *L) /* define library functions */ luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); lua_pop(L, 1); + return 0; } /*=========================================================================*\ @@ -250,7 +252,7 @@ static int meth_listen(lua_State *L) \*-------------------------------------------------------------------------*/ static int meth_shutdown(lua_State *L) { - p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{any}", 1); + p_tcp tcp = (p_tcp) aux_checkgroup(L, "tcp{client}", 1); const char *how = luaL_optstring(L, 2, "both"); switch (how[0]) { case 'b': @@ -266,7 +268,8 @@ static int meth_shutdown(lua_State *L) sock_shutdown(&tcp->sock, 0); break; } - return 0; + lua_pushnumber(L, 1); + return 1; error: luaL_argerror(L, 2, "invalid shutdown method"); return 0; diff --git a/src/tcp.h b/src/tcp.h index ae99b8c..708023e 100644 --- a/src/tcp.h +++ b/src/tcp.h @@ -31,6 +31,6 @@ typedef struct t_tcp_ { typedef t_tcp *p_tcp; -void tcp_open(lua_State *L); +int tcp_open(lua_State *L); #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) /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -void tm_open(lua_State *L) +int tm_open(lua_State *L) { luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); lua_pop(L, 1); + return 0; } /*-------------------------------------------------------------------------*\ 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_ { } t_tm; typedef t_tm *p_tm; -void tm_open(lua_State *L); +int tm_open(lua_State *L); void tm_init(p_tm tm, int block, int total); int tm_get(p_tm tm); int tm_getretry(p_tm tm); diff --git a/src/udp.c b/src/udp.c index 14029f9..a0fdcc0 100644 --- a/src/udp.c +++ b/src/udp.c @@ -30,7 +30,6 @@ static int meth_getpeername(lua_State *L); static int meth_setsockname(lua_State *L); static int meth_setpeername(lua_State *L); static int meth_close(lua_State *L); -static int meth_shutdown(lua_State *L); static int meth_setoption(lua_State *L); static int meth_settimeout(lua_State *L); static int meth_getfd(lua_State *L); @@ -49,7 +48,6 @@ static luaL_reg udp[] = { {"receivefrom", meth_receivefrom}, {"settimeout", meth_settimeout}, {"close", meth_close}, - {"shutdown", meth_shutdown}, {"setoption", meth_setoption}, {"__gc", meth_close}, {"getfd", meth_getfd}, @@ -79,7 +77,7 @@ static luaL_reg func[] = { /*-------------------------------------------------------------------------*\ * Initializes module \*-------------------------------------------------------------------------*/ -void udp_open(lua_State *L) +int udp_open(lua_State *L) { /* create classes */ aux_newclass(L, "udp{connected}", udp); @@ -92,6 +90,7 @@ void udp_open(lua_State *L) /* define library functions */ luaL_openlib(L, LUASOCKET_LIBNAME, func, 0); lua_pop(L, 1); + return 0; } /*=========================================================================*\ @@ -287,33 +286,6 @@ static int meth_close(lua_State *L) return 0; } -/*-------------------------------------------------------------------------*\ -* Shuts the connection down partially -\*-------------------------------------------------------------------------*/ -static int meth_shutdown(lua_State *L) -{ - p_udp udp = (p_udp) aux_checkgroup(L, "udp{any}", 1); - const char *how = luaL_optstring(L, 2, "both"); - switch (how[0]) { - case 'b': - if (strcmp(how, "both")) goto error; - sock_shutdown(&udp->sock, 2); - break; - case 's': - if (strcmp(how, "send")) goto error; - sock_shutdown(&udp->sock, 1); - break; - case 'r': - if (strcmp(how, "receive")) goto error; - sock_shutdown(&udp->sock, 0); - break; - } - return 0; -error: - luaL_argerror(L, 2, "invalid shutdown method"); - return 0; -} - /*-------------------------------------------------------------------------*\ * Turns a master object into a server object \*-------------------------------------------------------------------------*/ diff --git a/src/udp.h b/src/udp.h index 699e31a..0d8e5f4 100644 --- a/src/udp.h +++ b/src/udp.h @@ -27,6 +27,6 @@ typedef struct t_udp_ { } t_udp; typedef t_udp *p_udp; -void udp_open(lua_State *L); +int udp_open(lua_State *L); #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 local socket = _G[LUASOCKET_LIBNAME] if not socket then error('module requires LuaSocket') end -- create smtp namespace inside LuaSocket namespace -local url = {} +local url = socket.url or {} socket.url = url -- make all module globals fall into smtp namespace 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) \*-------------------------------------------------------------------------*/ const char *sock_create(p_sock ps, int domain, int type, int protocol) { - int val = 1; t_sock sock = socket(domain, type, protocol); if (sock == SOCK_INVALID) return sock_createstrerror(errno); *ps = sock; sock_setnonblocking(ps); - setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); return NULL; } @@ -167,13 +165,14 @@ const char *sock_accept(p_sock ps, p_sock pa, SA *addr, for (;;) { int err; fd_set fds; + /* try to accept */ *pa = accept(sock, addr, addr_len); /* if result is valid, we are done */ if (*pa != SOCK_INVALID) return NULL; /* find out if we failed for a fatal reason */ if (errno != EWOULDBLOCK && errno != ECONNABORTED) return sock_acceptstrerror(errno); - /* call select just to avoid busy-wait. */ + /* call select to avoid busy-wait. */ FD_ZERO(&fds); FD_SET(sock, &fds); 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) \*-------------------------------------------------------------------------*/ const char *sock_create(p_sock ps, int domain, int type, int protocol) { - int val = 1; t_sock sock = socket(domain, type, protocol); if (sock == SOCK_INVALID) return sock_createstrerror(WSAGetLastError()); *ps = sock; - setsockopt(*ps, SOL_SOCKET, SO_REUSEADDR, (char *) &val, sizeof(val)); sock_setnonblocking(ps); return NULL; } @@ -112,8 +110,12 @@ const char *sock_connect(p_sock ps, SA *addr, socklen_t addr_len, p_tm tm) /* if was in efds, we failed */ if (FD_ISSET(sock, &efds)) { int why, len = sizeof(why); + /* give windows time to set the error (disgusting) */ + Sleep(0); /* find out why we failed */ getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&why, &len); + /* we KNOW there was an error. if why is 0, we will return + * "unknown error", but it's not really our fault */ return sock_connectstrerror(why); /* otherwise it must be in wfds, so we succeeded */ } else return NULL; -- cgit v1.2.3-55-g6feb