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; |