From d7e80592a69c076991ed4f4cc15d5390e14d1f0b Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Mon, 2 Dec 2002 23:34:41 +0000 Subject: [PATCH] Already compiling and running for Lua 5.0 (alpha) --- src/http.lua | 20 ++++----- src/inet.c | 8 ++-- src/luasocket.c | 10 ++++- src/luasocket.h | 7 ++- src/mbox.lua | 111 +++++++++++++++++++++++++++++++++--------------- src/select.c | 15 ++++--- src/smtp.lua | 2 +- src/timeout.c | 4 +- src/udp.c | 12 +++--- src/unix.c | 8 ++-- src/unix.h | 6 +-- src/url.lua | 62 ++++++++++++++------------- 12 files changed, 164 insertions(+), 101 deletions(-) diff --git a/src/http.lua b/src/http.lua index 9832a6b..dce3ac8 100644 --- a/src/http.lua +++ b/src/http.lua @@ -32,7 +32,7 @@ Public.BLOCKSIZE = 8192 ----------------------------------------------------------------------------- function Private.try_receive(...) local sock = arg[1] - local data, err = call(sock.receive, arg) + local data, err = sock.receive(unpack(arg)) if err then sock:close() return nil, err @@ -62,7 +62,7 @@ end ----------------------------------------------------------------------------- function Private.get_statuscode(line) local code, _ - _, _, code = strfind(line, "HTTP/%d*%.%d* (%d%d%d)") + _, _, code = string.find(line, "HTTP/%d*%.%d* (%d%d%d)") return tonumber(code) end @@ -102,17 +102,17 @@ function Private.receive_headers(sock, headers) -- headers go until a blank line is found while line ~= "" do -- get field-name and value - _,_, name, value = strfind(line, "^(.-):%s*(.*)") + _,_, name, value = string.find(line, "^(.-):%s*(.*)") if not name or not value then sock:close() return nil, "malformed reponse headers" end - name = strlower(name) + name = string.lower(name) -- get next line (value might be folded) line, err = Private.try_receive(sock) if err then return nil, err end -- unfold any folded values - while not err and strfind(line, "^%s") do + while not err and string.find(line, "^%s") do value = value .. line line, err = Private.try_receive(sock) if err then return nil, err end @@ -142,7 +142,7 @@ function Private.receivebody_bychunks(sock, headers, receive_cb) local go, uerr = receive_cb(nil, err) return uerr or err end - size = tonumber(gsub(line, ";.*", ""), 16) + size = tonumber(string.gsub(line, ";.*", ""), 16) if not size then err = "invalid chunk size" sock:close() @@ -299,7 +299,7 @@ function Private.send_indirect(data, send_cb, chunk, size) data:close() return err end - sent = sent + strlen(chunk) + sent = sent + string.len(chunk) if sent >= size then break end chunk, size = send_cb() end @@ -391,7 +391,7 @@ function Private.fill_headers(headers, parsed) lower["user-agent"] = Public.USERAGENT -- override with user values for i,v in headers do - lower[strlower(i)] = v + lower[string.lower(i)] = v end lower["host"] = parsed.host -- this cannot be overriden @@ -554,7 +554,7 @@ function Public.request_cb(request, response) request.headers = Private.fill_headers(request.headers, parsed) -- try to connect to server local sock - sock, response.error = connect(parsed.host, parsed.port) + sock, response.error = socket.connect(parsed.host, parsed.port) if not sock then return response end -- set connection timeout so that we do not hang forever sock:timeout(Public.TIMEOUT) @@ -619,7 +619,7 @@ function Public.request(request) local response = {} if request.body then request.body_cb = function() - return request.body, strlen(request.body) + return request.body, string.len(request.body) end end local cat = Concat.create() diff --git a/src/inet.c b/src/inet.c index 5003ed9..3e89e88 100644 --- a/src/inet.c +++ b/src/inet.c @@ -38,9 +38,9 @@ static int inet_aton(cchar *cp, struct in_addr *inp); void inet_open(lua_State *L) { lua_pushcfunction(L, inet_lua_toip); - lua_setglobal(L, "toip"); + priv_newglobal(L, "toip"); lua_pushcfunction(L, inet_lua_tohostname); - lua_setglobal(L, "tohostname"); + priv_newglobal(L, "tohostname"); priv_newglobalmethod(L, "getsockname"); priv_newglobalmethod(L, "getpeername"); } @@ -145,7 +145,7 @@ static int inet_lua_getpeername(lua_State *L) { p_sock sock = (p_sock) lua_touserdata(L, 1); struct sockaddr_in peer; - size_t peer_len = sizeof(peer); + int peer_len = sizeof(peer); if (getpeername(sock->fd, (SA *) &peer, &peer_len) < 0) { lua_pushnil(L); return 1; @@ -167,7 +167,7 @@ static int inet_lua_getsockname(lua_State *L) { p_sock sock = (p_sock) lua_touserdata(L, 1); struct sockaddr_in local; - size_t local_len = sizeof(local); + int local_len = sizeof(local); if (getsockname(sock->fd, (SA *) &local, &local_len) < 0) { lua_pushnil(L); return 1; diff --git a/src/luasocket.c b/src/luasocket.c index d329d4e..26bc014 100644 --- a/src/luasocket.c +++ b/src/luasocket.c @@ -56,5 +56,13 @@ LUASOCKET_API int lua_socketlibopen(lua_State *L) buf_open(L); tcps_open(L); udp_open(L); - return 1; +#if LUASOCKET_DEBUG + lua_dofile(L, "concat.lua"); + lua_dofile(L, "code.lua"); + lua_dofile(L, "url.lua"); + lua_dofile(L, "http.lua"); + lua_dofile(L, "smtp.lua"); + lua_dofile(L, "ftp.lua"); +#endif + return 0; } diff --git a/src/luasocket.h b/src/luasocket.h index 95720e2..fd22606 100644 --- a/src/luasocket.h +++ b/src/luasocket.h @@ -11,7 +11,12 @@ /*-------------------------------------------------------------------------*\ * Current luasocket version \*-------------------------------------------------------------------------*/ -#define LUASOCKET_VERSION "LuaSocket 1.5" +#define LUASOCKET_VERSION "LuaSocket 1.5 (alpha)" + +/*-------------------------------------------------------------------------*\ +* Library's namespace +\*-------------------------------------------------------------------------*/ +#define LUASOCKET_LIBNAME "socket" /*-------------------------------------------------------------------------*\ * This macro prefixes all exported API functions diff --git a/src/mbox.lua b/src/mbox.lua index 9cce9ff..2969111 100644 --- a/src/mbox.lua +++ b/src/mbox.lua @@ -1,45 +1,88 @@ local Public = {} -parse = Public +mbox = Public -function Public.headers(headers_s) - local headers = {} - headers_s = "\n" .. headers_s .. "$$$:\n" - local i, j = 1, 1 - local name, value, _ - while 1 do - j = strfind(headers_s, "\n%S-:", i+1) - if not j then break end - _,_, name, value = strfind(strsub(headers_s, i+1, j-1), "(%S-):%s?(.*)") - value = gsub(value or "", "\r\n", "\n") - value = gsub(value, "\n%s*", " ") - name = strlower(name) - if headers[name] then headers[name] = headers[name] .. ", " .. value - else headers[name] = value end - i, j = j, i +function Public.split_message(message_s) + local message = {} + message_s = gsub(message_s, "\r\n", "\n") + gsub(message_s, "^(.-\n)\n", function (h) %message.headers = h end) + gsub(message_s, "^.-\n\n(.*)", function (b) %message.body = b end) + if not message.body then + gsub(message_s, "^\n(.*)", function (b) %message.body = b end) end - headers["$$$"] = nil + if not message.headers and not message.body then + message.headers = message_s + end + return message.headers or "", message.body or "" +end + +function Public.split_headers(headers_s) + local headers = {} + headers_s = gsub(headers_s, "\r\n", "\n") + headers_s = gsub(headers_s, "\n[ ]+", " ") + gsub("\n" .. headers_s, "\n([^\n]+)", function (h) tinsert(%headers, h) end) return headers end -function Public.message(message_s) - message_s = gsub(message_s, "^.-\n", "") - local _, headers_s, body - _, _, headers_s, body = strfind(message_s, "^(.-\n)\n(.*)") - headers_s = headers_s or "" - body = body or "" - return { headers = %Public.headers(headers_s), body = body } +function Public.parse_header(header_s) + header_s = gsub(header_s, "\n[ ]+", " ") + header_s = gsub(header_s, "\n+", "") + local _, __, name, value = strfind(header_s, "([^%s:]-):%s*(.*)") + return name, value end -function Public.mbox(mbox_s) - local mbox = {} - mbox_s = "\n" .. mbox_s .. "\nFrom " - local i, j = 1, 1 - while 1 do - j = strfind(mbox_s, "\nFrom ", i + 1) - if not j then break end - tinsert(mbox, %Public.message(strsub(mbox_s, i + 1, j - 1))) - i, j = j, i +function Public.parse_headers(headers_s) + local headers_t = %Public.split_headers(headers_s) + local headers = {} + for i = 1, getn(headers_t) do + local name, value = %Public.parse_header(headers_t[i]) + if name then + name = strlower(name) + if headers[name] then + headers[name] = headers[name] .. ", " .. value + else headers[name] = value end + end end - return mbox + return headers +end + +function Public.parse_from(from) + local _, __, name, address = strfind(from, "^%s*(.-)%s*%<(.-)%>") + if not address then + _, __, address = strfind(from, "%s*(.+)%s*") + end + name = name or "" + address = address or "" + if name == "" then name = address end + name = gsub(name, '"', "") + return name, address +end + +function Public.split_mbox(mbox_s) + mbox = {} + mbox_s = gsub(mbox_s, "\r\n", "\n") .."\n\nFrom \n" + local nj, i, j = 1, 1, 1 + while 1 do + i, nj = strfind(mbox_s, "\n\nFrom .-\n", j) + if not i then break end + local message = strsub(mbox_s, j, i-1) + tinsert(mbox, message) + j = nj+1 + end + return mbox +end + +function Public.parse_mbox(mbox_s) + local mbox = %Public.split_mbox(mbox_s) + for i = 1, getn(mbox) do + mbox[i] = %Public.parse_message(mbox[i]) + end + return mbox +end + +function Public.parse_message(message_s) + local message = {} + message.headers, message.body = %Public.split_message(message_s) + message.headers = %Public.parse_headers(message.headers) + return message end diff --git a/src/select.c b/src/select.c index 9a24dbb..1aaa7fe 100644 --- a/src/select.c +++ b/src/select.c @@ -31,9 +31,12 @@ void select_open(lua_State *L) { /* push select auxiliar lua function and register * select_lua_select with it as an upvalue */ -#include "lsselect.loh" +#ifdef LUASOCKET_DEBUG +#endif + luaL_loadfile(L, "lsselect.lua"); + lua_call(L, 0, 1); lua_pushcclosure(L, select_lua_select, 1); - lua_setglobal(L, "select"); + priv_newglobal(L, "select"); /* create luasocket(select) table */ lua_pushstring(L, "luasocket(select)"); lua_newtable(L); @@ -61,8 +64,8 @@ static int select_lua_select(lua_State *L) /* make sure we have enough arguments (nil is the default) */ lua_settop(L, 4); /* pass FD_SET and manipulation functions */ - lua_newuserdatabox(L, &read); - lua_newuserdatabox(L, &write); + lua_boxpointer(L, &read); + lua_boxpointer(L, &write); lua_pushcfunction(L, local_FD_SET); lua_pushcfunction(L, local_FD_ISSET); /* pass getfd function with selectable table as upvalue */ @@ -121,7 +124,7 @@ static int local_select(lua_State *L) static int local_FD_SET(lua_State *L) { COMPAT_FD fd = (COMPAT_FD) lua_tonumber(L, 1); - fd_set *set = (fd_set *) lua_touserdata(L, 2); + fd_set *set = (fd_set *) lua_topointer(L, 2); if (fd >= 0) FD_SET(fd, set); return 0; } @@ -129,7 +132,7 @@ static int local_FD_SET(lua_State *L) static int local_FD_ISSET(lua_State *L) { COMPAT_FD fd = (COMPAT_FD) lua_tonumber(L, 1); - fd_set *set = (fd_set *) lua_touserdata(L, 2); + fd_set *set = (fd_set *) lua_topointer(L, 2); if (fd >= 0 && FD_ISSET(fd, set)) lua_pushnumber(L, 1); else lua_pushnil(L); return 1; diff --git a/src/smtp.lua b/src/smtp.lua index 72a0e5a..774dddb 100644 --- a/src/smtp.lua +++ b/src/smtp.lua @@ -19,7 +19,7 @@ Public.TIMEOUT = 180 Public.PORT = 25 -- domain used in HELO command and default sendmail -- If we are under a CGI, try to get from environment -Public.DOMAIN = getenv("SERVER_NAME") or "localhost" +Public.DOMAIN = os.getenv("SERVER_NAME") or "localhost" -- default server used to send e-mails Public.SERVER = "localhost" diff --git a/src/timeout.c b/src/timeout.c index 266a86e..fdbc47a 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -125,9 +125,9 @@ void tm_open(lua_State *L) (void) L; #ifdef _DEBUG lua_pushcfunction(L, tm_lua_time); - lua_setglobal(L, "_time"); + priv_newglobal(L, "_time"); lua_pushcfunction(L, tm_lua_sleep); - lua_setglobal(L, "_sleep"); + priv_newglobal(L, "_sleep"); #endif } diff --git a/src/udp.c b/src/udp.c index 0dc0df8..29004fd 100644 --- a/src/udp.c +++ b/src/udp.c @@ -45,7 +45,7 @@ void udp_open(lua_State *L) udp_inherit(L, UDP_CLASS); /* declare global functions */ lua_pushcfunction(L, udp_global_udpsocket); - lua_setglobal(L, "udpsocket"); + priv_newglobal(L, "udp"); for (i = 0; i < sizeof(funcs)/sizeof(funcs[0]); i++) priv_newglobalmethod(L, funcs[i].name); /* make class selectable */ @@ -162,12 +162,12 @@ static int udp_lua_receivefrom(lua_State *L) p_udp udp = (p_udp) lua_touserdata(L, 1); p_tm tm = &udp->base_tm; struct sockaddr_in peer; - size_t peer_len = sizeof(peer); + int peer_len = sizeof(peer); unsigned char buffer[UDP_DATAGRAMSIZE]; size_t wanted = (size_t) luaL_opt_number(L, 2, sizeof(buffer)); size_t got; int err; - if (udp->udp_connected) lua_error(L, "receivefrom on connected socket"); + if (udp->udp_connected) luaL_error(L, "receivefrom on connected socket"); tm_markstart(tm); wanted = MIN(wanted, sizeof(buffer)); err = compat_recvfrom(udp->fd, buffer, wanted, &got, tm_getremaining(tm), @@ -201,7 +201,7 @@ static int udp_lua_send(lua_State *L) size_t wanted, sent = 0; int err; cchar *data = luaL_check_lstr(L, 2, &wanted); - if (!udp->udp_connected) lua_error(L, "send on unconnected socket"); + if (!udp->udp_connected) luaL_error(L, "send on unconnected socket"); tm_markstart(tm); err = compat_send(udp->fd, data, wanted, &sent, tm_getremaining(tm)); priv_pusherror(L, err == PRIV_CLOSED ? PRIV_REFUSED : err); @@ -230,9 +230,9 @@ static int udp_lua_sendto(lua_State *L) p_tm tm = &udp->base_tm; struct sockaddr_in peer; int err; - if (udp->udp_connected) lua_error(L, "sendto on connected socket"); + if (udp->udp_connected) luaL_error(L, "sendto on connected socket"); memset(&peer, 0, sizeof(peer)); - if (!inet_aton(ip, &peer.sin_addr)) lua_error(L, "invalid ip address"); + if (!inet_aton(ip, &peer.sin_addr)) luaL_error(L, "invalid ip address"); peer.sin_family = AF_INET; peer.sin_port = htons(port); tm_markstart(tm); diff --git a/src/unix.c b/src/unix.c index d50d98c..0fc08bd 100644 --- a/src/unix.c +++ b/src/unix.c @@ -28,7 +28,7 @@ void compat_open(lua_State *L) } COMPAT_FD compat_accept(COMPAT_FD s, struct sockaddr *addr, - socklen_t *len, int deadline) + int *len, int deadline) { struct timeval tv; fd_set fds; @@ -74,7 +74,7 @@ int compat_send(COMPAT_FD c, cchar *data, size_t count, size_t *sent, } int compat_sendto(COMPAT_FD c, cchar *data, size_t count, size_t *sent, - int deadline, SA *addr, socklen_t len) + int deadline, SA *addr, int len) { struct timeval tv; fd_set fds; @@ -134,7 +134,7 @@ int compat_recv(COMPAT_FD c, uchar *data, size_t count, size_t *got, } int compat_recvfrom(COMPAT_FD c, uchar *data, size_t count, size_t *got, - int deadline, SA *addr, socklen_t *len) + int deadline, SA *addr, int *len) { struct timeval tv; fd_set fds; @@ -290,7 +290,7 @@ cchar *compat_trysetoptions(lua_State *L, COMPAT_FD sock) static cchar *try_setbooloption(lua_State *L, COMPAT_FD sock, int name) { int bool, res; - if (!lua_isnumber(L, -1)) lua_error(L, "invalid option value"); + if (!lua_isnumber(L, -1)) luaL_error(L, "invalid option value"); bool = (int) lua_tonumber(L, -1); res = setsockopt(sock, SOL_SOCKET, name, (char *) &bool, sizeof(bool)); if (res < 0) return "error setting option"; diff --git a/src/unix.h b/src/unix.h index e317b06..944b471 100644 --- a/src/unix.h +++ b/src/unix.h @@ -46,15 +46,15 @@ void compat_open(lua_State *L); #define compat_select select COMPAT_FD compat_socket(int domain, int type, int protocol); -COMPAT_FD compat_accept(COMPAT_FD s, SA *addr, socklen_t *len, int deadline); +COMPAT_FD compat_accept(COMPAT_FD s, SA *addr, int *len, int deadline); int compat_send(COMPAT_FD c, cchar *data, size_t count, size_t *done, int deadline); int compat_recv(COMPAT_FD c, uchar *data, size_t count, size_t *done, int deadline); int compat_sendto(COMPAT_FD c, cchar *data, size_t count, size_t *done, - int deadline, SA *addr, socklen_t len); + int deadline, SA *addr, int len); int compat_recvfrom(COMPAT_FD c, uchar *data, size_t count, size_t *got, - int deadline, SA *addr, socklen_t *len); + int deadline, SA *addr, int *len); void compat_setnonblocking(COMPAT_FD sock); void compat_setblocking(COMPAT_FD sock); void compat_setreuseaddr(COMPAT_FD sock); diff --git a/src/url.lua b/src/url.lua index e17bcf5..0ecec3c 100644 --- a/src/url.lua +++ b/src/url.lua @@ -34,26 +34,30 @@ function Public.parse_url(url, default) -- empty url is parsed to nil if not url or url == "" then return nil end -- remove whitespace - url = gsub(url, "%s", "") + url = string.gsub(url, "%s", "") -- get fragment - url = gsub(url, "#(.*)$", function(f) parsed.fragment = f end) + url = string.gsub(url, "#(.*)$", function(f) parsed.fragment = f end) -- get scheme - url = gsub(url, "^([%w][%w%+%-%.]*)%:", function(s) parsed.scheme = s end) + url = string.gsub(url, "^([%w][%w%+%-%.]*)%:", + function(s) parsed.scheme = s end) -- get authority - url = gsub(url, "^//([^/]*)", function(n) parsed.authority = n end) - -- get query string - url = gsub(url, "%?(.*)", function(q) parsed.query = q end) + url = string.gsub(url, "^//([^/]*)", function(n) parsed.authority = n end) + -- get query stringing + url = string.gsub(url, "%?(.*)", function(q) parsed.query = q end) -- get params - url = gsub(url, "%;(.*)", function(p) parsed.params = p end) + url = string.gsub(url, "%;(.*)", function(p) parsed.params = p end) if url ~= "" then parsed.path = url end local authority = parsed.authority if not authority then return parsed end - authority = gsub(authority,"^([^@]*)@",function(u) parsed.userinfo = u end) - authority = gsub(authority, ":([^:]*)$", function(p) parsed.port = p end) + authority = string.gsub(authority,"^([^@]*)@", + function(u) parsed.userinfo = u end) + authority = string.gsub(authority, ":([^:]*)$", + function(p) parsed.port = p end) if authority ~= "" then parsed.host = authority end local userinfo = parsed.userinfo if not userinfo then return parsed end - userinfo = gsub(userinfo, ":([^:]*)$", function(p) parsed.password = p end) + userinfo = string.gsub(userinfo, ":([^:]*)$", + function(p) parsed.password = p end) parsed.user = userinfo return parsed end @@ -64,7 +68,7 @@ end -- Input -- parsed: parsed URL, as returned by Public.parse -- Returns --- a string with the corresponding URL +-- a stringing with the corresponding URL ----------------------------------------------------------------------------- function Public.build_url(parsed) local url = parsed.path or "" @@ -86,7 +90,7 @@ function Public.build_url(parsed) if authority then url = "//" .. authority .. url end if parsed.scheme then url = parsed.scheme .. ":" .. url end if parsed.fragment then url = url .. "#" .. parsed.fragment end - url = gsub(url, "%s", "") + url = string.gsub(url, "%s", "") return url end @@ -134,13 +138,13 @@ end function Public.parse_path(path) local parsed = {} path = path or "" - path = gsub(path, "%s", "") - gsub(path, "([^/]+)", function (s) tinsert(parsed, s) end) - for i = 1, getn(parsed) do + path = string.gsub(path, "%s", "") + string.gsub(path, "([^/]+)", function (s) table.insert(parsed, s) end) + for i = 1, table.getn(parsed) do parsed[i] = Code.unescape(parsed[i]) end - if strsub(path, 1, 1) == "/" then parsed.is_absolute = 1 end - if strsub(path, -1, -1) == "/" then parsed.is_directory = 1 end + if stringsub(path, 1, 1) == "/" then parsed.is_absolute = 1 end + if stringsub(path, -1, -1) == "/" then parsed.is_directory = 1 end return parsed end @@ -150,11 +154,11 @@ end -- parsed: path segments -- unsafe: if true, segments are not protected before path is built -- Returns --- path: correspondin path string +-- path: correspondin path stringing ----------------------------------------------------------------------------- function Public.build_path(parsed, unsafe) local path = "" - local n = getn(parsed) + local n = table.getn(parsed) if unsafe then for i = 1, n-1 do path = path .. parsed[i] @@ -178,10 +182,10 @@ function Public.build_path(parsed, unsafe) return path end -function Private.make_set(table) +function Private.make_set(t) local s = {} - for i = 1, getn(table) do - s[table[i]] = 1 + for i = 1, table.getn(t) do + s[t[i]] = 1 end return s end @@ -195,7 +199,7 @@ Private.segment_set = Private.make_set { function Private.protect_segment(s) local segment_set = Private.segment_set - return gsub(s, "(%W)", function (c) + return string.gsub(s, "(%W)", function (c) if segment_set[c] then return c else return Code.escape(c) end end) @@ -210,21 +214,21 @@ end -- corresponding absolute path ----------------------------------------------------------------------------- function Private.absolute_path(base_path, relative_path) - if strsub(relative_path, 1, 1) == "/" then return relative_path end - local path = gsub(base_path, "[^/]*$", "") + if stringsub(relative_path, 1, 1) == "/" then return relative_path end + local path = string.gsub(base_path, "[^/]*$", "") path = path .. relative_path - path = gsub(path, "([^/]*%./)", function (s) + path = string.gsub(path, "([^/]*%./)", function (s) if s ~= "./" then return s else return "" end end) - path = gsub(path, "/%.$", "/") + path = string.gsub(path, "/%.$", "/") local reduced while reduced ~= path do reduced = path - path = gsub(reduced, "([^/]*/%.%./)", function (s) + path = string.gsub(reduced, "([^/]*/%.%./)", function (s) if s ~= "../../" then return "" else return s end end) end - path = gsub(reduced, "([^/]*/%.%.)$", function (s) + path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) if s ~= "../.." then return "" else return s end end) return path