diff --git a/TODO b/TODO index 838be3d..bc307d5 100644 --- a/TODO +++ b/TODO @@ -1,54 +1,14 @@ -* should be interrupt-safe -* notice the change in callback conventions -* new mime module replacing old code module (faster, more functionality) -* new socket options (many) -* only allocate in case of success -* optimize for success (only call select if fails) -* add proxy support to http -* add gethostname -* local connect -* connect with timeout -* change code to mime -* change stay to redirect -* add shutdown -* change send/recv to avoid using select -* O location do "redirect" pode ser relativo ao servidor atual (não pode, - mas os servidores fazem merda...) -* Ajeitar para Lua 5.0 -* Padronizar os retornos de funccao -* Separar as classes em arquivos -* Retorno de sendto em datagram sockets pode ser refused -* select sets are now associative -* colocar pump.all, pump.step -* mudar ltn12.html e usar o exemplo source.cat que está muito melhor. -* break smtp.send into c = smtp.open, c:send() c:close() -* fazer com que a socket.source e socket.sink sejam "selectable". -* change mime.eol to output marker on detection of first candidate, instead - of on the second. that way it works in one pass for strings that end with - one candidate. -* unify backbone of smtp and ftp -* unify filter and send/receive callback. new sink/source/pump idea. -* get rid of aux_optlstring -* get rid of unpack in mime.lua -* create socket.(sink|source).simplify -* break chain into a simpler binary chain and a complex (recursive) one. -* Create a passive mode option for the FTP (good for firewall). -* Modules should return their namespace table in the end of the chunk. - - -get.lua precisa de ftp.get com url e sink +ajeitar os README.* +ajeitar select. upvalue nao tem nada a ver... make sure filter.chain fails gracefully. ajeitar o manual sobre select, mais liberal agora -conjunto associativo falar sobre encodet/wrapt/decodet no manual sobre mime - RECEIVE MUDOU!!! (partial stuff) COLOCAR NO MANUAL. HTTP.lua mudou bastante também. pump.step usado em todo mundo que recebe source ou sink -colocar um userdata com gc metamethod pra chamar sock_close (WSAClose); sources ans sinks are always simple in http and ftp and smtp expose encode/decode tables to provide extensibility for mime module use coroutines instead of fancy filters @@ -60,6 +20,7 @@ pop3??? add socket.TIMEOUT to be default timeout? manual + compatibility: select sets are associative add socket.connect and socket.bind to the manual say what a nil callback does for http check all occurences of it's @@ -87,24 +48,9 @@ tests check for interrupts wrp can't break lines in the middle of a line break. -call select before accept, not after, dumbass! -get rid of setnonblocking/setblocking in the bind function -close has to block... -fmt is not a good name -change wrap() to accept a number and default to "character" -move gethostname to dns table -get rid of _cb in name of functions? -trust character constants in mime.c? noooooo. -smtp.lua needs stuff filter add comments into each C module. -new option.c module to put all options (TCP and UDP share...)? testar os options! -add _tostring methods! -change all modules to use the new namespace scheme - -write some utilities that use the code.lua module and put them -in etc, modify the README.etc file and makefile.dist (eol.lua is done) use gethostname it in SMTP @@ -150,3 +96,61 @@ Ajeitar o protocolo da luaopen_socket()... sei l - unix 92 bytes maximo no endereço, incluindo o zero - unix 9216 maximo de datagram size + +-------------- +these are done +-------------- + +* should be interrupt-safe +* notice the change in callback conventions +* new mime module replacing old code module (faster, more functionality) +* new socket options (many) +* only allocate in case of success +* optimize for success (only call select if fails) +* add proxy support to http +* add gethostname +* local connect +* connect with timeout +* change code to mime +* change stay to redirect +* add shutdown +* change send/recv to avoid using select +* O location do "redirect" pode ser relativo ao servidor atual (não pode, + mas os servidores fazem merda...) +* Ajeitar para Lua 5.0 +* Padronizar os retornos de funccao +* Separar as classes em arquivos +* Retorno de sendto em datagram sockets pode ser refused +* select sets are now associative +* colocar pump.all, pump.step +* mudar ltn12.html e usar o exemplo source.cat que está muito melhor. +* break smtp.send into c = smtp.open, c:send() c:close() +* fazer com que a socket.source e socket.sink sejam "selectable". +* change mime.eol to output marker on detection of first candidate, instead + of on the second. that way it works in one pass for strings that end with + one candidate. +* unify backbone of smtp and ftp +* unify filter and send/receive callback. new sink/source/pump idea. +* get rid of aux_optlstring +* get rid of unpack in mime.lua +* create socket.(sink|source).simplify +* break chain into a simpler binary chain and a complex (recursive) one. +* Create a passive mode option for the FTP (good for firewall). +* Modules should return their namespace table in the end of the chunk. +* get.lua precisa de ftp.get com url e sink +* conjunto associativo +* colocar um userdata com gc metamethod pra chamar sock_close (WSAClose); +* call select before accept, not after, dumbass! +* get rid of setnonblocking/setblocking in the bind function +* close has to block... +* fmt is not a good name +* change wrap() to accept a number and default to "character" +* move gethostname to dns table +* get rid of _cb in name of functions? +* trust character constants in mime.c? yup. +* smtp.lua needs stuff filter +* new option.c module to put all options (TCP and UDP share...)? +* add _tostring methods! +* change all modules to use the new namespace scheme +* write some utilities that use the code.lua module and put them +* in etc, modify the README.etc file and makefile.dist (eol.lua is done) diff --git a/etc/get.lua b/etc/get.lua index cc270e8..35de7d7 100644 --- a/etc/get.lua +++ b/etc/get.lua @@ -106,7 +106,10 @@ function getbyftp(url, file) -- only print feedback if output is not stdout -- and we don't know how big the file is if file then save = ltn12.sink.chain(stats(), save) end - local ret, err = socket.ftp.get {url = url, sink = save, type = "i"} + local gett = socket.url.parse(url) + gett.sink = save + gett.type = "i" + local ret, err = socket.ftp.get(gett) if err then print(err) end end diff --git a/samples/listener.lua b/samples/listener.lua index dff4d25..bedbde5 100644 --- a/samples/listener.lua +++ b/samples/listener.lua @@ -4,6 +4,7 @@ -- Author: Diego Nehab -- RCS ID: $Id$ ----------------------------------------------------------------------------- +require("socket") host = host or "*" port = port or 8080 if arg then @@ -11,18 +12,10 @@ if arg then port = arg[2] or port end print("Binding to host '" ..host.. "' and port " ..port.. "...") -s, e = socket.bind(host, port) -if not s then - print(e) - exit() -end -i, p = s:getsockname() +s = socket.try(socket.bind(host, port)) +i, p = socket.try(s:getsockname()) print("Waiting connection from talker on " .. i .. ":" .. p .. "...") -c, e = s:accept() -if not c then - print(e) - exit() -end +c = socket.try(s:accept()) print("Connected. Here is the stuff:") l, e = c:receive() while not e do diff --git a/samples/talker.lua b/samples/talker.lua index 1b0652f..94d2133 100644 --- a/samples/talker.lua +++ b/samples/talker.lua @@ -4,6 +4,7 @@ -- Author: Diego Nehab -- RCS ID: $Id$ ----------------------------------------------------------------------------- +require("socket") host = host or "localhost" port = port or 8080 if arg then @@ -11,18 +12,10 @@ if arg then port = arg[2] or port end print("Attempting connection to host '" ..host.. "' and port " ..port.. "...") -c, e = socket.connect(host, port) -if not c then - print(e) - os.exit() -end +c = socket.try(socket.connect(host, port)) print("Connected! Please type stuff (empty line to stop):") l = io.read() while l and l ~= "" and not e do - t, e = c:send(l, "\n") - if e then - print(e) - os.exit() - end + socket.try(c:send(l, "\n")) l = io.read() end diff --git a/samples/tinyirc.lua b/samples/tinyirc.lua index b48b90a..eac979d 100644 --- a/samples/tinyirc.lua +++ b/samples/tinyirc.lua @@ -4,6 +4,7 @@ -- Author: Diego Nehab -- RCS ID: $Id$ ----------------------------------------------------------------------------- +require("socket") host = host or "*" port1 = port1 or 8080 port2 = port2 or 8181 @@ -13,12 +14,10 @@ if arg then port2 = arg[3] or port2 end -server1, error = socket.bind(host, port1) -assert(server1, error) +server1 = socket.try(socket.bind(host, port1)) +server2 = socket.try(socket.bind(host, port2)) server1:settimeout(1) -- make sure we don't block in accept -server2, error = socket.bind(host, port2) -assert(server2, error) -server2:settimeout(1) -- make sure we don't block in accept +server2:settimeout(1) io.write("Servers bound\n") @@ -49,7 +48,7 @@ set:insert(server2) while 1 do local readable, _, error = socket.select(set, nil) - for _, input in readable do + for _, input in ipairs(readable) do -- is it a server socket? if input == server1 or input == server2 then io.write("Waiting for clients\n") @@ -68,10 +67,12 @@ while 1 do set:remove(input) else io.write("Broadcasting line '", line, "'\n") - __, writable, error = socket.select(nil, set, 1) + writable, error = socket.skip(1, socket.select(nil, set, 1)) if not error then - for ___, output in writable do - output:send(line .. "\n") + for __, output in ipairs(writable) do + if output ~= input then + output:send(line .. "\n") + end end else io.write("No client ready to receive!!!\n") end end diff --git a/src/ftp.lua b/src/ftp.lua index 72be695..842fdbb 100644 --- a/src/ftp.lua +++ b/src/ftp.lua @@ -13,6 +13,7 @@ local socket = _G[LUASOCKET_LIBNAME] -- require other modules require("ltn12") require("url") +require("tp") -- create namespace inside LuaSocket namespace socket.ftp = socket.ftp or {} @@ -101,7 +102,9 @@ function metat.__index:send(sendt) local data socket.try(self.pasvt or self.portt, "need port or pasv first") if self.pasvt then data = socket.try(pasv(self.pasvt)) end - socket.try(self.tp:command(sendt.command or "stor", sendt.argument)) + local argument = sendt.argument or string.gsub(sendt.path, "^/", "") + local command = sendt.command or "stor" + socket.try(self.tp:command(command, argument)) local code, reply = socket.try(self.tp:check{"2..", "1.."}) if self.portt then data = socket.try(port(self.portt)) end local step = sendt.step or ltn12.pump.step @@ -128,7 +131,9 @@ function metat.__index:receive(recvt) local data socket.try(self.pasvt or self.portt, "need port or pasv first") if self.pasvt then data = socket.try(pasv(self.pasvt)) end - socket.try(self.tp:command(recvt.command or "retr", recvt.argument)) + local argument = recvt.argument or string.gsub(recvt.path, "^/", "") + local command = recvt.command or "retr" + socket.try(self.tp:command(command, argument)) local code = socket.try(self.tp:check{"1..", "2.."}) if self.portt then data = socket.try(port(self.portt)) end local source = socket.source("until-closed", data) @@ -200,8 +205,6 @@ local function parse(url) putt.type = socket.skip(2, string.find(putt.params, pat)) socket.try(putt.type == "a" or putt.type == "i") end - -- skip first backslash in path - putt.argument = string.sub(putt.path, 2) return putt end diff --git a/src/http.lua b/src/http.lua index b372a2e..66a236d 100644 --- a/src/http.lua +++ b/src/http.lua @@ -13,6 +13,8 @@ local socket = _G[LUASOCKET_LIBNAME] -- require other modules require("ltn12") require("mime") +-- get MIME namespace +local mime = _G[MIME_LIBNAME] require("url") -- create namespace inside LuaSocket namespace diff --git a/src/luasocket.c b/src/luasocket.c index 8d49be5..a5b6cb0 100644 --- a/src/luasocket.c +++ b/src/luasocket.c @@ -25,11 +25,10 @@ \*=========================================================================*/ #include "luasocket.h" -#include "base.h" #include "auxiliar.h" +#include "base.h" #include "timeout.h" #include "buffer.h" -#include "socket.h" #include "inet.h" #include "tcp.h" #include "udp.h" @@ -40,10 +39,10 @@ * Modules \*-------------------------------------------------------------------------*/ static const luaL_reg mod[] = { + {"auxiliar", aux_open}, {"base", base_open}, - {"aux", aux_open}, - {"tm", tm_open}, - {"buf", buf_open}, + {"timeout", tm_open}, + {"buffer", buf_open}, {"inet", inet_open}, {"tcp", tcp_open}, {"udp", udp_open}, @@ -55,14 +54,8 @@ static const luaL_reg mod[] = { /*-------------------------------------------------------------------------*\ * Initializes all library modules. \*-------------------------------------------------------------------------*/ -LUASOCKET_API int luaopen_socket(lua_State *L) -{ +LUASOCKET_API int luaopen_socket(lua_State *L) { int i; - if (!sock_open()) { - lua_pushnil(L); - lua_pushstring(L, "unable to initialize library"); - return 2; - } for (i = 0; mod[i].name; i++) mod[i].func(L); return 1; diff --git a/src/mime.c b/src/mime.c index 7a2baae..8cfcd26 100644 --- a/src/mime.c +++ b/src/mime.c @@ -82,8 +82,7 @@ int luaopen_mime(lua_State *L) /* initialize lookup tables */ qpsetup(qpclass, qpunbase); b64setup(b64unbase); - lua_pop(L, 1); - return 0; + return 1; } /*=========================================================================*\ diff --git a/src/select.h b/src/select.h index de10ea4..b58f082 100644 --- a/src/select.h +++ b/src/select.h @@ -7,10 +7,10 @@ * To make the code as simple as possible, the select function is * implemented int Lua, with a few helper functions written in C. * -* Each object that can be passed to the select function has to be in the -* group select{able} and export two methods: fd() and dirty(). Fd returns -* the descriptor to be passed to the select function. Dirty() should return -* true if there is data ready for reading (required for buffered input). +* Each object that can be passed to the select function has to export two +* methods: fd() and dirty(). Fd returns the descriptor to be passed to the +* select function. Dirty() should return true if there is data ready for +* reading (required for buffered input). * * RCS ID: $Id$ \*=========================================================================*/ diff --git a/src/smtp.lua b/src/smtp.lua index 01babbe..3108395 100644 --- a/src/smtp.lua +++ b/src/smtp.lua @@ -6,11 +6,12 @@ -- RCS ID: $Id$ ----------------------------------------------------------------------------- -- make sure LuaSocket is loaded -require"socket" +require("socket") -- get LuaSocket namespace local socket = _G[LUASOCKET_LIBNAME] -require"ltn12" +require("ltn12") +require("tp") -- create smtp namespace inside LuaSocket namespace local smtp = socket.smtp or {} diff --git a/src/socket.h b/src/socket.h index 2e7b6f9..85e8848 100644 --- a/src/socket.h +++ b/src/socket.h @@ -38,6 +38,7 @@ typedef struct sockaddr SA; * interface to sockets \*=========================================================================*/ int sock_open(void); +int sock_close(void); void sock_destroy(p_sock ps); void sock_shutdown(p_sock ps, int how); int sock_send(p_sock ps, const char *data, size_t count, diff --git a/src/tp.lua b/src/tp.lua index b671e58..f510226 100644 --- a/src/tp.lua +++ b/src/tp.lua @@ -6,10 +6,10 @@ -- RCS ID: $Id$ ----------------------------------------------------------------------------- -- make sure LuaSocket is loaded -if not LUASOCKET_LIBNAME then error('module requires LuaSocket') end +require("socket") -- get LuaSocket namespace local socket = _G[LUASOCKET_LIBNAME] -if not socket then error('module requires LuaSocket') end + -- create namespace inside LuaSocket namespace socket.tp = socket.tp or {} -- make all module globals fall into namespace @@ -35,6 +35,7 @@ local function get_reply(control) -- reply ends with same code until code == current and sep == " " end +print(reply) return code, reply end @@ -58,6 +59,7 @@ function metat.__index:check(ok) end function metat.__index:command(cmd, arg) +print(cmd, arg) if arg then return self.control:send(cmd .. " " .. arg.. "\r\n") else return self.control:send(cmd .. "\r\n") end end diff --git a/src/url.lua b/src/url.lua index 16b19e0..8c591c0 100644 --- a/src/url.lua +++ b/src/url.lua @@ -9,10 +9,11 @@ require("socket") -- get LuaSocket namespace local socket = _G[LUASOCKET_LIBNAME] + -- create url namespace inside LuaSocket namespace local url = socket.url or {} socket.url = url --- make all module globals fall into smtp namespace +-- make all module globals fall into url namespace setmetatable(url, { __index = _G }) setfenv(1, url) diff --git a/src/usocket.c b/src/usocket.c index 9e6efd3..6b4182b 100644 --- a/src/usocket.c +++ b/src/usocket.c @@ -42,6 +42,14 @@ int sock_open(void) return 1; } +/*-------------------------------------------------------------------------*\ +* Close module +\*-------------------------------------------------------------------------*/ +int sock_close(void) +{ + return 1; +} + /*-------------------------------------------------------------------------*\ * Close and inutilize socket \*-------------------------------------------------------------------------*/ diff --git a/src/wsocket.c b/src/wsocket.c index 023f470..08c1046 100644 --- a/src/wsocket.c +++ b/src/wsocket.c @@ -37,6 +37,15 @@ int sock_open(void) return 1; } +/*-------------------------------------------------------------------------*\ +* Close module +\*-------------------------------------------------------------------------*/ +int sock_close(void) +{ + WSACleanup(); + return 1; +} + /*-------------------------------------------------------------------------*\ * Select with int timeout in ms \*-------------------------------------------------------------------------*/ diff --git a/test/mimetest.lua b/test/mimetest.lua index 8433786..d092175 100644 --- a/test/mimetest.lua +++ b/test/mimetest.lua @@ -8,10 +8,14 @@ local qptest = "qptest.bin" local eqptest = "qptest.bin2" local dqptest = "qptest.bin3" -local b64test = "luasocket" +local b64test = "libluasocket.dylib" local eb64test = "b64test.bin" local db64test = "b64test.bin2" +-- make sure test file exists +local f = assert(io.open(b64test, "r")) +f:close() + -- from Machado de Assis, "A Mão e a Rosa" local mao = [[ Cursavam estes dois moços a academia de S. Paulo, estando