From bce60be30fe8e9c1b0eb33128c23c93d7bca5303 Mon Sep 17 00:00:00 2001 From: Diego Nehab Date: Wed, 27 May 2009 09:31:38 +0000 Subject: Decent makefiles! --- src/auxiliar.h | 2 - src/buffer.c | 2 +- src/buffer.h | 2 - src/except.h | 2 - src/http.lua | 10 ++-- src/inet.h | 2 - src/io.h | 2 - src/luasocket.c | 2 - src/luasocket.h | 6 +-- src/makefile | 156 ++++++++++++++++++++++++++++++++++++++++++++------------ src/mime.c | 10 +++- src/mime.h | 6 +-- src/options.c | 86 ++++++++++++++++++++++++++----- src/options.h | 36 +++++++------ src/select.c | 39 +++++++++----- src/select.h | 2 - src/smtp.lua | 8 +-- src/socket.h | 2 - src/tcp.c | 12 ++--- src/tcp.h | 2 - src/timeout.c | 18 +++++-- src/timeout.h | 2 - src/tp.lua | 1 + src/udp.c | 41 +++++++++++---- src/udp.h | 2 - src/unix.c | 10 ++-- src/unix.h | 4 +- src/usocket.h | 6 ++- src/wsocket.h | 9 ++-- 29 files changed, 334 insertions(+), 148 deletions(-) (limited to 'src') diff --git a/src/auxiliar.h b/src/auxiliar.h index 8a18bcf..57a2ecc 100644 --- a/src/auxiliar.h +++ b/src/auxiliar.h @@ -27,8 +27,6 @@ * * The mapping from class name to the corresponding metatable and the * reverse mapping are done using lauxlib. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" diff --git a/src/buffer.c b/src/buffer.c index de817b2..363da3d 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -166,7 +166,7 @@ static int sendraw(p_buffer buf, const char *data, size_t count, size_t *sent) { size_t total = 0; int err = IO_DONE; while (total < count && err == IO_DONE) { - size_t done; + size_t done = 0; size_t step = (count-total <= STEPSIZE)? count-total: STEPSIZE; err = io->send(io->ctx, data+total, step, &done, tm); total += done; diff --git a/src/buffer.h b/src/buffer.h index 0a4a335..58838d1 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -14,8 +14,6 @@ * * The module is built on top of the I/O abstraction defined in io.h and the * timeout management is done with the timeout.h interface. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" diff --git a/src/except.h b/src/except.h index 03e417d..1e7a245 100644 --- a/src/except.h +++ b/src/except.h @@ -24,8 +24,6 @@ * * With these two function, it's easy to write functions that throw * exceptions on error, but that don't interrupt the user script. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" diff --git a/src/http.lua b/src/http.lua index 3a386a6..4c27149 100644 --- a/src/http.lua +++ b/src/http.lua @@ -13,6 +13,7 @@ local url = require("socket.url") local ltn12 = require("ltn12") local mime = require("mime") local string = require("string") +local headers = require("socket.headers") local base = _G local table = require("table") module("socket.http") @@ -123,10 +124,11 @@ function metat.__index:sendrequestline(method, uri) return self.try(self.c:send(reqline)) end -function metat.__index:sendheaders(headers) +function metat.__index:sendheaders(tosend) + local canonic = headers.canonic local h = "\r\n" - for i, v in base.pairs(headers) do - h = i .. ": " .. v .. "\r\n" .. h + for f, v in base.pairs(tosend) do + h = (canonic[f] or f) .. ": " .. v .. "\r\n" .. h end self.try(self.c:send(h)) return 1 @@ -254,7 +256,7 @@ local function shouldredirect(reqt, code, headers) return headers.location and string.gsub(headers.location, "%s", "") ~= "" and (reqt.redirect ~= false) and - (code == 301 or code == 302) and + (code == 301 or code == 302 or code == 303 or code == 307) and (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD") and (not reqt.nredirects or reqt.nredirects < 5) end diff --git a/src/inet.h b/src/inet.h index c6d717d..dbc160c 100644 --- a/src/inet.h +++ b/src/inet.h @@ -13,8 +13,6 @@ * getpeername and getsockname functions as seen by Lua programs. * * The Lua functions toip and tohostname are also implemented here. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" #include "socket.h" diff --git a/src/io.h b/src/io.h index bff48a6..8cca08a 100644 --- a/src/io.h +++ b/src/io.h @@ -11,8 +11,6 @@ * * The module socket.h implements this interface, and thus the module tcp.h * is very simple. -* -* RCS ID: $Id$ \*=========================================================================*/ #include #include "lua.h" diff --git a/src/luasocket.c b/src/luasocket.c index 142aa95..3b29e8e 100644 --- a/src/luasocket.c +++ b/src/luasocket.c @@ -10,8 +10,6 @@ * involved in setting up both client and server connections. The provided * IO routines, however, follow the Lua style, being very similar to the * standard Lua read and write functions. -* -* RCS ID: $Id$ \*=========================================================================*/ /*=========================================================================*\ diff --git a/src/luasocket.h b/src/luasocket.h index 13134cf..d7a78bb 100644 --- a/src/luasocket.h +++ b/src/luasocket.h @@ -5,16 +5,14 @@ * Networking support for the Lua language * Diego Nehab * 9/11/1999 -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" /*-------------------------------------------------------------------------*\ * Current socket library version \*-------------------------------------------------------------------------*/ -#define LUASOCKET_VERSION "LuaSocket 2.0.2" -#define LUASOCKET_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" +#define LUASOCKET_VERSION "LuaSocket 2.0.3" +#define LUASOCKET_COPYRIGHT "Copyright (C) 1999-2009 Diego Nehab" #define LUASOCKET_AUTHORS "Diego Nehab" /*-------------------------------------------------------------------------*\ diff --git a/src/makefile b/src/makefile index b614f77..3351997 100644 --- a/src/makefile +++ b/src/makefile @@ -1,39 +1,86 @@ +PLAT = none +INSTALL_DATA=cp +INSTALL_EXEC=cp +INSTALL_TOP= /opt/local +LUAINC= $(LUAINC_$(PLAT)) + #------ -# Load configuration +# Install directories # -include ../config +INSTALL_TOP_SHARE=$(INSTALL_TOP)/share/lua/5.1 +INSTALL_TOP_LIB=$(INSTALL_TOP)/lib/lua/5.1 +INSTALL_SOCKET_SHARE=$(INSTALL_TOP_SHARE)/socket +INSTALL_SOCKET_LIB=$(INSTALL_TOP_LIB)/socket +INSTALL_MIME_SHARE=$(INSTALL_TOP_SHARE)/mime +INSTALL_MIME_LIB=$(INSTALL_TOP_LIB)/mime #------ -# Hopefully no need to change anything below this line +# Output file names # +EXT=so +SOCKET_V=2.0.3 +MIME_V=1.0.3 +SOCKET_SO=socket.$(EXT).$(SOCKET_V) +MIME_SO=mime.$(EXT).$(MIME_V) +UNIX_SO=unix.$(EXT) #------ -# Modules belonging to socket-core -# +# Compiler and linker settings +# for Mac OS X +LUAINC_macosx= -I/opt/local/include +CC_macosx=gcc +DEF_macosx= -DLUASOCKET_DEBUG -DUNIX_HAS_SUN_LEN \ + -DLUASOCKET_API='__attribute__((visibility("default")))' \ + -DMIME_API='__attribute__((visibility("default")))' +CFLAGS_macosx= $(LUAINC) $(COMPAT) $(DEF) -pedantic -Wall -O2 -fno-common \ + -fvisibility=hidden +LDFLAGS_macosx= -bundle -undefined dynamic_lookup +LD_macosx= export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc -#$(COMPAT)/compat-5.1.o \ +#------ +# Compiler and linker settings +# for Linux +LUAINC_linux= -I/usr/local/include/lua5.1 +CC_linux=gcc +DEF_linux=-DLUASOCKET_DEBUG \ + -DLUASOCKET_API='__attribute__((visibility("default")))' \ + -DMIME_API='__attribute__((visibility("default")))' +CFLAGS_linux= $(LUAINC) $(DEF) -pedantic -Wall -O2 -fpic \ + -fvisibility=hidden +LDFLAGS_linux=-O -shared -fpic +LD_linux= gcc -SOCKET_OBJS:= \ +#------ +# Settings selected for platform +# +CC=$(CC_$(PLAT)) +DEF=$(DEF_$(PLAT)) +CFLAGS=$(CFLAGS_$(PLAT)) +LDFLAGS=$(LDFLAGS_$(PLAT)) +LD=$(LD_$(PLAT)) + +#------ +# Modules belonging to socket-core +# +SOCKET_OBJS= \ luasocket.o \ timeout.o \ buffer.o \ io.o \ - auxiliar.o \ + auxiliar.o \ options.o \ inet.o \ - tcp.o \ - udp.o \ + usocket.o \ except.o \ select.o \ - usocket.o + tcp.o \ + udp.o #------ # Modules belonging mime-core # -#$(COMPAT)/compat-5.1.o \ - -MIME_OBJS:=\ - mime.o +MIME_OBJS= \ + mime.o #------ # Modules belonging unix (local domain sockets) @@ -47,7 +94,35 @@ UNIX_OBJS:=\ usocket.o \ unix.o -all: $(SOCKET_SO) $(MIME_SO) +#------ +# Files to install +# +TO_SOCKET_SHARE:= \ + http.lua \ + url.lua \ + tp.lua \ + ftp.lua \ + headers.lua \ + smtp.lua + +TO_TOP_SHARE:= \ + ltn12.lua \ + socket.lua \ + mime.lua + +default: $(PLAT) + +macosx: + $(MAKE) all PLAT=macosx + +linux: + $(MAKE) all PLAT=linux + +none: + @echo "Please choose a platform:" + @echo " $(PLATS)" + +all: $(SOCKET_SO) $(MIME_SO) $(SOCKET_SO): $(SOCKET_OBJS) $(LD) $(LDFLAGS) -o $@ $(SOCKET_OBJS) @@ -58,6 +133,25 @@ $(MIME_SO): $(MIME_OBJS) $(UNIX_SO): $(UNIX_OBJS) $(LD) $(LDFLAGS) -o $@ $(UNIX_OBJS) +install: + mkdir -p $(INSTALL_TOP_SHARE) + $(INSTALL_DATA) $(TO_TOP_SHARE) $(INSTALL_TOP_SHARE) + mkdir -p $(INSTALL_SOCKET_SHARE) + $(INSTALL_DATA) $(TO_SOCKET_SHARE) $(INSTALL_SOCKET_SHARE) + mkdir -p $(INSTALL_SOCKET_LIB) + $(INSTALL_EXEC) $(SOCKET_SO) $(INSTALL_SOCKET_LIB)/core.$(EXT) + mkdir -p $(INSTALL_MIME_LIB) + $(INSTALL_EXEC) $(MIME_SO) $(INSTALL_MIME_LIB)/core.$(EXT) + +local: + $(MAKE) install INSTALL_TOP_LIB=.. INSTALL_TOP_SHARE=.. + +clean: + rm -f $(SOCKET_SO) $(SOCKET_OBJS) + rm -f $(MIME_SO) $(UNIX_SO) $(MIME_OBJS) $(UNIX_OBJS) + +.PHONY: all $(PLATS) default clean echo none + #------ # List of dependencies # @@ -66,25 +160,19 @@ buffer.o: buffer.c buffer.h io.h timeout.h except.o: except.c except.h inet.o: inet.c inet.h socket.h io.h timeout.h usocket.h io.o: io.c io.h timeout.h -luasocket.o: luasocket.c luasocket.h auxiliar.h except.h timeout.h \ - buffer.h io.h inet.h socket.h usocket.h tcp.h udp.h select.h +luasocket.o: luasocket.c luasocket.h auxiliar.h except.h \ + timeout.h buffer.h io.h inet.h socket.h usocket.h tcp.h \ + udp.h select.h mime.o: mime.c mime.h -options.o: options.c auxiliar.h options.h socket.h io.h timeout.h \ - usocket.h inet.h +options.o: options.c auxiliar.h options.h socket.h io.h \ + timeout.h usocket.h inet.h select.o: select.c socket.h io.h timeout.h usocket.h select.h -tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \ - options.h tcp.h buffer.h +tcp.o: tcp.c auxiliar.h socket.h io.h timeout.h usocket.h \ + inet.h options.h tcp.h buffer.h timeout.o: timeout.c auxiliar.h timeout.h -udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h inet.h \ - options.h udp.h -unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h options.h \ - unix.h buffer.h +udp.o: udp.c auxiliar.h socket.h io.h timeout.h usocket.h \ + inet.h options.h udp.h +unix.o: unix.c auxiliar.h socket.h io.h timeout.h usocket.h \ + options.h unix.h buffer.h usocket.o: usocket.c socket.h io.h timeout.h usocket.h - -clean: - rm -f $(SOCKET_SO) $(SOCKET_OBJS) - rm -f $(MIME_SO) $(UNIX_SO) $(MIME_OBJS) $(UNIX_OBJS) - -#------ -# End of makefile configuration -# +wsocket.o: wsocket.c socket.h io.h timeout.h usocket.h diff --git a/src/mime.c b/src/mime.c index a41bf40..1e8fded 100644 --- a/src/mime.c +++ b/src/mime.c @@ -272,9 +272,12 @@ static int mime_global_b64(lua_State *L) input = (UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second part is nil, we are done */ if (!input) { + size_t osize = 0; asize = b64pad(atom, asize, &buffer); luaL_pushresult(&buffer); - if (!(*lua_tostring(L, -1))) lua_pushnil(L); + /* if the output is empty and the input is nil, return nil */ + lua_tolstring(L, -1, &osize); + if (osize == 0) lua_pushnil(L); lua_pushnil(L); return 2; } @@ -313,8 +316,11 @@ static int mime_global_unb64(lua_State *L) input = (UC *) luaL_optlstring(L, 2, NULL, &isize); /* if second is nil, we are done */ if (!input) { + size_t osize = 0; luaL_pushresult(&buffer); - if (!(*lua_tostring(L, -1))) lua_pushnil(L); + /* if the output is empty and the input is nil, return nil */ + lua_tolstring(L, -1, &osize); + if (osize == 0) lua_pushnil(L); lua_pushnil(L); return 2; } diff --git a/src/mime.h b/src/mime.h index 0fe8000..37f370f 100644 --- a/src/mime.h +++ b/src/mime.h @@ -7,16 +7,14 @@ * This module provides functions to implement transfer content encodings * and formatting conforming to RFC 2045. It is used by mime.lua, which * provide a higher level interface to this functionality. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" /*-------------------------------------------------------------------------*\ * Current MIME library version \*-------------------------------------------------------------------------*/ -#define MIME_VERSION "MIME 1.0.2" -#define MIME_COPYRIGHT "Copyright (C) 2004-2007 Diego Nehab" +#define MIME_VERSION "MIME 1.0.3" +#define MIME_COPYRIGHT "Copyright (C) 2004-2009 Diego Nehab" #define MIME_AUTHORS "Diego Nehab" /*-------------------------------------------------------------------------*\ diff --git a/src/options.c b/src/options.c index a464a4b..1d4c950 100644 --- a/src/options.c +++ b/src/options.c @@ -12,12 +12,12 @@ #include "options.h" #include "inet.h" - /*=========================================================================*\ * Internal functions prototypes \*=========================================================================*/ static int opt_setmembership(lua_State *L, p_socket ps, int level, int name); static int opt_setboolean(lua_State *L, p_socket ps, int level, int name); +static int opt_getboolean(lua_State *L, p_socket ps, int level, int name); static int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len); @@ -40,39 +40,63 @@ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps) return opt->func(L, ps); } +int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps) +{ + const char *name = luaL_checkstring(L, 2); /* obj, name, ... */ + while (opt->name && strcmp(name, opt->name)) + opt++; + if (!opt->func) { + char msg[45]; + sprintf(msg, "unsupported option `%.35s'", name); + luaL_argerror(L, 2, msg); + } + return opt->func(L, ps); +} + /* enables reuse of local address */ -int opt_reuseaddr(lua_State *L, p_socket ps) +int opt_set_reuseaddr(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEADDR); } +/* enables reuse of local port */ +int opt_set_reuseport(lua_State *L, p_socket ps) +{ + return opt_setboolean(L, ps, SOL_SOCKET, SO_REUSEPORT); +} + /* disables the Naggle algorithm */ -int opt_tcp_nodelay(lua_State *L, p_socket ps) +int opt_set_tcp_nodelay(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, IPPROTO_TCP, TCP_NODELAY); } -int opt_keepalive(lua_State *L, p_socket ps) +int opt_set_keepalive(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, SOL_SOCKET, SO_KEEPALIVE); } -int opt_dontroute(lua_State *L, p_socket ps) +int opt_set_dontroute(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, SOL_SOCKET, SO_DONTROUTE); } -int opt_broadcast(lua_State *L, p_socket ps) +int opt_set_broadcast(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, SOL_SOCKET, SO_BROADCAST); } -int opt_ip_multicast_loop(lua_State *L, p_socket ps) +int opt_set_ip_multicast_loop(lua_State *L, p_socket ps) { return opt_setboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); } -int opt_linger(lua_State *L, p_socket ps) +int opt_get_ip_multicast_loop(lua_State *L, p_socket ps) +{ + return opt_getboolean(L, ps, IPPROTO_IP, IP_MULTICAST_LOOP); +} + +int opt_set_linger(lua_State *L, p_socket ps) { struct linger li; /* obj, name, table */ if (!lua_istable(L, 3)) luaL_typerror(L, 3, lua_typename(L, LUA_TTABLE)); @@ -89,18 +113,43 @@ int opt_linger(lua_State *L, p_socket ps) return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &li, sizeof(li)); } -int opt_ip_multicast_ttl(lua_State *L, p_socket ps) +int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps) { int val = (int) luaL_checknumber(L, 3); /* obj, name, int */ - return opt_set(L, ps, SOL_SOCKET, SO_LINGER, (char *) &val, sizeof(val)); + return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_TTL, + (char *) &val, sizeof(val)); +} + +int opt_set_ip_multicast_if(lua_State *L, p_socket ps) +{ + const char *address = luaL_checkstring(L, 3); /* obj, name, ip */ + struct in_addr val; + val.s_addr = htonl(INADDR_ANY); + if (strcmp(address, "*") && !inet_aton(address, &val)) + luaL_argerror(L, 3, "ip expected"); + return opt_set(L, ps, IPPROTO_IP, IP_MULTICAST_IF, + (char *) &val, sizeof(val)); +} + +int opt_get_ip_multicast_if(lua_State *L, p_socket ps) +{ + struct in_addr val; + socklen_t len = sizeof(val); + if (getsockopt(*ps, IPPROTO_IP, IP_MULTICAST_IF, (char *) &val, &len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getsockopt failed"); + return 2; + } + lua_pushstring(L, inet_ntoa(val)); + return 1; } -int opt_ip_add_membership(lua_State *L, p_socket ps) +int opt_set_ip_add_membership(lua_State *L, p_socket ps) { return opt_setmembership(L, ps, IPPROTO_IP, IP_ADD_MEMBERSHIP); } -int opt_ip_drop_membersip(lua_State *L, p_socket ps) +int opt_set_ip_drop_membersip(lua_State *L, p_socket ps) { return opt_setmembership(L, ps, IPPROTO_IP, IP_DROP_MEMBERSHIP); } @@ -141,6 +190,19 @@ int opt_set(lua_State *L, p_socket ps, int level, int name, void *val, int len) return 1; } +static int opt_getboolean(lua_State *L, p_socket ps, int level, int name) +{ + int val = 0; + socklen_t len = sizeof(val); + if (getsockopt(*ps, level, name, (char *) &val, &len) < 0) { + lua_pushnil(L); + lua_pushstring(L, "getsockopt failed"); + return 2; + } + lua_pushboolean(L, val); + return 1; +} + static int opt_setboolean(lua_State *L, p_socket ps, int level, int name) { int val = auxiliar_checkboolean(L, 3); /* obj, name, bool */ diff --git a/src/options.h b/src/options.h index 900761e..aa43cab 100644 --- a/src/options.h +++ b/src/options.h @@ -6,8 +6,6 @@ * * This module provides a common interface to socket options, used mainly by * modules UDP and TCP. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" @@ -20,20 +18,28 @@ typedef struct t_opt { } t_opt; typedef t_opt *p_opt; -/* supported options */ -int opt_dontroute(lua_State *L, p_socket ps); -int opt_broadcast(lua_State *L, p_socket ps); -int opt_reuseaddr(lua_State *L, p_socket ps); -int opt_tcp_nodelay(lua_State *L, p_socket ps); -int opt_keepalive(lua_State *L, p_socket ps); -int opt_linger(lua_State *L, p_socket ps); -int opt_reuseaddr(lua_State *L, p_socket ps); -int opt_ip_multicast_ttl(lua_State *L, p_socket ps); -int opt_ip_multicast_loop(lua_State *L, p_socket ps); -int opt_ip_add_membership(lua_State *L, p_socket ps); -int opt_ip_drop_membersip(lua_State *L, p_socket ps); - +/* supported options for setoption */ +int opt_set_dontroute(lua_State *L, p_socket ps); +int opt_set_broadcast(lua_State *L, p_socket ps); +int opt_set_reuseaddr(lua_State *L, p_socket ps); +int opt_set_tcp_nodelay(lua_State *L, p_socket ps); +int opt_set_keepalive(lua_State *L, p_socket ps); +int opt_set_linger(lua_State *L, p_socket ps); +int opt_set_reuseaddr(lua_State *L, p_socket ps); +int opt_set_reuseport(lua_State *L, p_socket ps); +int opt_set_ip_multicast_if(lua_State *L, p_socket ps); +int opt_set_ip_multicast_ttl(lua_State *L, p_socket ps); +int opt_set_ip_multicast_loop(lua_State *L, p_socket ps); +int opt_set_ip_add_membership(lua_State *L, p_socket ps); +int opt_set_ip_drop_membersip(lua_State *L, p_socket ps); /* invokes the appropriate option handler */ int opt_meth_setoption(lua_State *L, p_opt opt, p_socket ps); +/* supported options for getoption */ +int opt_get_ip_multicast_loop(lua_State *L, p_socket ps); +int opt_get_ip_multicast_if(lua_State *L, p_socket ps); +/* invokes the appropriate option handler */ +int opt_meth_getoption(lua_State *L, p_opt opt, p_socket ps); + + #endif diff --git a/src/select.c b/src/select.c index 99b59f5..8e47d0e 100644 --- a/src/select.c +++ b/src/select.c @@ -18,8 +18,8 @@ \*=========================================================================*/ static t_socket getfd(lua_State *L); static int dirty(lua_State *L); -static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, - int itab, fd_set *set); +static void collect_fd(lua_State *L, int tab, int itab, + fd_set *set, t_socket *max_fd); static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set); static void return_fd(lua_State *L, fd_set *set, t_socket max_fd, int itab, int tab, int start); @@ -39,6 +39,9 @@ static luaL_reg func[] = { * Initializes module \*-------------------------------------------------------------------------*/ int select_open(lua_State *L) { + lua_pushstring(L, "_SETSIZE"); + lua_pushnumber(L, FD_SETSIZE); + lua_rawset(L, -3); luaL_openlib(L, NULL, func, 0); return 0; } @@ -51,7 +54,7 @@ int select_open(lua_State *L) { \*-------------------------------------------------------------------------*/ static int global_select(lua_State *L) { int rtab, wtab, itab, ret, ndirty; - t_socket max_fd; + t_socket max_fd = SOCKET_INVALID; fd_set rset, wset; t_timeout tm; double t = luaL_optnumber(L, 3, -1); @@ -60,12 +63,12 @@ static int global_select(lua_State *L) { lua_newtable(L); itab = lua_gettop(L); lua_newtable(L); rtab = lua_gettop(L); lua_newtable(L); wtab = lua_gettop(L); - max_fd = collect_fd(L, 1, SOCKET_INVALID, itab, &rset); + collect_fd(L, 1, itab, &rset, &max_fd); + collect_fd(L, 2, itab, &wset, &max_fd); ndirty = check_dirty(L, 1, rtab, &rset); t = ndirty > 0? 0.0: t; timeout_init(&tm, t, -1); timeout_markstart(&tm); - max_fd = collect_fd(L, 2, max_fd, itab, &wset); ret = socket_select(max_fd+1, &rset, &wset, NULL, &tm); if (ret > 0 || ndirty > 0) { return_fd(L, &rset, max_fd+1, itab, rtab, ndirty); @@ -77,7 +80,7 @@ static int global_select(lua_State *L) { lua_pushstring(L, "timeout"); return 3; } else { - lua_pushstring(L, "error"); + luaL_error(L, "select failed"); return 3; } } @@ -112,11 +115,13 @@ static int dirty(lua_State *L) { return is; } -static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, - int itab, fd_set *set) { - int i = 1; - if (lua_isnil(L, tab)) - return max_fd; +static void collect_fd(lua_State *L, int tab, int itab, + fd_set *set, t_socket *max_fd) { + int i = 1, n = 0; + /* nil is the same as an empty table */ + if (lua_isnil(L, tab)) return; + /* otherwise we need it to be a table */ + luaL_checktype(L, tab, LUA_TTABLE); while (1) { t_socket fd; lua_pushnumber(L, i); @@ -125,11 +130,18 @@ static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, lua_pop(L, 1); break; } + /* getfd figures out if this is a socket */ fd = getfd(L); if (fd != SOCKET_INVALID) { + /* make sure we don't overflow the fd_set */ + if (n >= FD_SETSIZE) + luaL_argerror(L, tab, "too many sockets"); FD_SET(fd, set); - if (max_fd == SOCKET_INVALID || max_fd < fd) - max_fd = fd; + n++; + /* keep track of the largest descriptor so far */ + if (*max_fd == SOCKET_INVALID || *max_fd < fd) + *max_fd = fd; + /* make sure we can map back from descriptor to the object */ lua_pushnumber(L, fd); lua_pushvalue(L, -2); lua_settable(L, itab); @@ -137,7 +149,6 @@ static t_socket collect_fd(lua_State *L, int tab, t_socket max_fd, lua_pop(L, 1); i = i + 1; } - return max_fd; } static int check_dirty(lua_State *L, int tab, int dtab, fd_set *set) { diff --git a/src/select.h b/src/select.h index f2d2cc2..8750200 100644 --- a/src/select.h +++ b/src/select.h @@ -8,8 +8,6 @@ * method getfd() which returns the descriptor to be passed to the * underlying select function. Another method, dirty(), should return * true if there is data ready for reading (required for buffered input). -* -* RCS ID: $Id$ \*=========================================================================*/ int select_open(lua_State *L); diff --git a/src/smtp.lua b/src/smtp.lua index 9a204d8..b39f5d6 100644 --- a/src/smtp.lua +++ b/src/smtp.lua @@ -16,6 +16,7 @@ local os = require("os") local socket = require("socket") local tp = require("socket.tp") local ltn12 = require("ltn12") +local headers = require("socket.headers") local mime = require("mime") module("socket.smtp") @@ -146,10 +147,11 @@ end local send_message -- yield the headers all at once, it's faster -local function send_headers(headers) +local function send_headers(tosend) + local canonic = headers.canonic local h = "\r\n" - for i,v in base.pairs(headers) do - h = i .. ': ' .. v .. "\r\n" .. h + for f,v in base.pairs(tosend) do + h = (canonic[f] or f) .. ': ' .. v .. "\r\n" .. h end coroutine.yield(h) end diff --git a/src/socket.h b/src/socket.h index de5d79f..425628d 100644 --- a/src/socket.h +++ b/src/socket.h @@ -8,8 +8,6 @@ * differences. Also, not all *nix platforms behave the same. This module * (and the associated usocket.h and wsocket.h) factor these differences and * creates a interface compatible with the io.h module. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "io.h" diff --git a/src/tcp.c b/src/tcp.c index 539ad5e..06d687b 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -64,11 +64,11 @@ static luaL_reg tcp[] = { }; /* socket option handlers */ -static t_opt opt[] = { - {"keepalive", opt_keepalive}, - {"reuseaddr", opt_reuseaddr}, - {"tcp-nodelay", opt_tcp_nodelay}, - {"linger", opt_linger}, +static t_opt optset[] = { + {"keepalive", opt_set_keepalive}, + {"reuseaddr", opt_set_reuseaddr}, + {"tcp-nodelay", opt_set_tcp_nodelay}, + {"linger", opt_set_linger}, {NULL, NULL} }; @@ -128,7 +128,7 @@ static int meth_setstats(lua_State *L) { static int meth_setoption(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkgroup(L, "tcp{any}", 1); - return opt_meth_setoption(L, opt, &tcp->sock); + return opt_meth_setoption(L, optset, &tcp->sock); } /*-------------------------------------------------------------------------*\ diff --git a/src/tcp.h b/src/tcp.h index 7e98ab6..a536b49 100644 --- a/src/tcp.h +++ b/src/tcp.h @@ -13,8 +13,6 @@ * objects are tcp objects bound to some local address. Client objects are * tcp objects either connected to some address or returned by the accept * method of a server object. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" diff --git a/src/timeout.c b/src/timeout.c index 863546e..fb015f9 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -5,6 +5,8 @@ * RCS ID: $Id$ \*=========================================================================*/ #include +#include +#include #include "lua.h" #include "lauxlib.h" @@ -187,13 +189,23 @@ static int timeout_lua_gettime(lua_State *L) /*-------------------------------------------------------------------------*\ * Sleep for n seconds. \*-------------------------------------------------------------------------*/ +#ifdef _WIN32 int timeout_lua_sleep(lua_State *L) { double n = luaL_checknumber(L, 1); -#ifdef _WIN32 - Sleep((int)(n*1000)); + if (n < 0.0) n = 0.0; + if (n < DBL_MAX/1000.0) n *= 1000.0; + if (n > INT_MAX) n = INT_MAX; + Sleep((int)n); + return 0; +} #else +int timeout_lua_sleep(lua_State *L) +{ + double n = luaL_checknumber(L, 1); struct timespec t, r; + if (n < 0.0) n = 0.0; + if (n > INT_MAX) n = INT_MAX; t.tv_sec = (int) n; n -= t.tv_sec; t.tv_nsec = (int) (n * 1000000000); @@ -202,6 +214,6 @@ int timeout_lua_sleep(lua_State *L) t.tv_sec = r.tv_sec; t.tv_nsec = r.tv_nsec; } -#endif return 0; } +#endif diff --git a/src/timeout.h b/src/timeout.h index a328bcc..6715ca7 100644 --- a/src/timeout.h +++ b/src/timeout.h @@ -3,8 +3,6 @@ /*=========================================================================*\ * Timeout management functions * LuaSocket toolkit -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" diff --git a/src/tp.lua b/src/tp.lua index 2eacdc4..5fd8d22 100644 --- a/src/tp.lua +++ b/src/tp.lua @@ -64,6 +64,7 @@ function metat.__index:check(ok) end function metat.__index:command(cmd, arg) + cmd = string.upper(cmd) if arg then return self.c:send(cmd .. " " .. arg.. "\r\n") else diff --git a/src/udp.c b/src/udp.c index e604bea..db519ca 100644 --- a/src/udp.c +++ b/src/udp.c @@ -37,6 +37,7 @@ static int meth_setsockname(lua_State *L); static int meth_setpeername(lua_State *L); static int meth_close(lua_State *L); static int meth_setoption(lua_State *L); +static int meth_getoption(lua_State *L); static int meth_settimeout(lua_State *L); static int meth_getfd(lua_State *L); static int meth_setfd(lua_State *L); @@ -57,22 +58,32 @@ static luaL_reg udp[] = { {"sendto", meth_sendto}, {"setfd", meth_setfd}, {"setoption", meth_setoption}, + {"getoption", meth_getoption}, {"setpeername", meth_setpeername}, {"setsockname", meth_setsockname}, {"settimeout", meth_settimeout}, {NULL, NULL} }; -/* socket options */ -static t_opt opt[] = { - {"dontroute", opt_dontroute}, - {"broadcast", opt_broadcast}, - {"reuseaddr", opt_reuseaddr}, - {"ip-multicast-ttl", opt_ip_multicast_ttl}, - {"ip-multicast-loop", opt_ip_multicast_loop}, - {"ip-add-membership", opt_ip_add_membership}, - {"ip-drop-membership", opt_ip_drop_membersip}, - {NULL, NULL} +/* socket options for setoption */ +static t_opt optset[] = { + {"dontroute", opt_set_dontroute}, + {"broadcast", opt_set_broadcast}, + {"reuseaddr", opt_set_reuseaddr}, + {"reuseport", opt_set_reuseport}, + {"ip-multicast-if", opt_set_ip_multicast_if}, + {"ip-multicast-ttl", opt_set_ip_multicast_ttl}, + {"ip-multicast-loop", opt_set_ip_multicast_loop}, + {"ip-add-membership", opt_set_ip_add_membership}, + {"ip-drop-membership", opt_set_ip_drop_membersip}, + {NULL, NULL} +}; + +/* socket options for getoption */ +static t_opt optget[] = { + {"ip-multicast-if", opt_get_ip_multicast_if}, + {"ip-multicast-loop", opt_get_ip_multicast_loop}, + {NULL, NULL} }; /* functions in library namespace */ @@ -247,7 +258,15 @@ static int meth_getsockname(lua_State *L) { \*-------------------------------------------------------------------------*/ static int meth_setoption(lua_State *L) { p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); - return opt_meth_setoption(L, opt, &udp->sock); + return opt_meth_setoption(L, optset, &udp->sock); +} + +/*-------------------------------------------------------------------------*\ +* Just call option handler +\*-------------------------------------------------------------------------*/ +static int meth_getoption(lua_State *L) { + p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1); + return opt_meth_getoption(L, optget, &udp->sock); } /*-------------------------------------------------------------------------*\ diff --git a/src/udp.h b/src/udp.h index d29f833..358d9e1 100644 --- a/src/udp.h +++ b/src/udp.h @@ -11,8 +11,6 @@ * originally unconnected. They can be "connected" to a given address * with a call to the setpeername function. The same function can be used to * break the connection. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" diff --git a/src/unix.c b/src/unix.c index 0430086..a309823 100644 --- a/src/unix.c +++ b/src/unix.c @@ -63,10 +63,10 @@ static luaL_reg un[] = { }; /* socket option handlers */ -static t_opt opt[] = { - {"keepalive", opt_keepalive}, - {"reuseaddr", opt_reuseaddr}, - {"linger", opt_linger}, +static t_opt optset[] = { + {"keepalive", opt_set_keepalive}, + {"reuseaddr", opt_set_reuseaddr}, + {"linger", opt_set_linger}, {NULL, NULL} }; @@ -128,7 +128,7 @@ static int meth_setstats(lua_State *L) { \*-------------------------------------------------------------------------*/ static int meth_setoption(lua_State *L) { p_unix un = (p_unix) auxiliar_checkgroup(L, "unix{any}", 1); - return opt_meth_setoption(L, opt, &un->sock); + return opt_meth_setoption(L, optset, &un->sock); } /*-------------------------------------------------------------------------*\ diff --git a/src/unix.h b/src/unix.h index 055b02b..39fa719 100644 --- a/src/unix.h +++ b/src/unix.h @@ -6,8 +6,6 @@ * * This module is just an example of how to extend LuaSocket with a new * domain. -* -* RCS ID: $Id$ \*=========================================================================*/ #include "lua.h" @@ -23,6 +21,6 @@ typedef struct t_unix_ { } t_unix; typedef t_unix *p_unix; -int luaopen_socketunix(lua_State *L); +int luaopen_socket_unix(lua_State *L); #endif /* UNIX_H */ diff --git a/src/usocket.h b/src/usocket.h index e1f7498..75bfe82 100644 --- a/src/usocket.h +++ b/src/usocket.h @@ -3,8 +3,6 @@ /*=========================================================================*\ * Socket compatibilization module for Unix * LuaSocket toolkit -* -* RCS ID: $Id$ \*=========================================================================*/ /*=========================================================================*\ @@ -32,6 +30,10 @@ /* TCP options (nagle algorithm disable) */ #include +#ifndef SO_REUSEPORT +#define SO_REUSEPORT SO_REUSEADDR +#endif + typedef int t_socket; typedef t_socket *p_socket; diff --git a/src/wsocket.h b/src/wsocket.h index e4f0e92..8e0f114 100644 --- a/src/wsocket.h +++ b/src/wsocket.h @@ -3,14 +3,13 @@ /*=========================================================================*\ * Socket compatibilization module for Win32 * LuaSocket toolkit -* -* RCS ID: $Id$ \*=========================================================================*/ /*=========================================================================*\ * WinSock include files \*=========================================================================*/ -#include +#include +#include typedef int socklen_t; typedef SOCKET t_socket; @@ -18,4 +17,8 @@ typedef t_socket *p_socket; #define SOCKET_INVALID (INVALID_SOCKET) +#ifndef SO_REUSEPORT +#define SO_REUSEPORT SO_REUSEADDR +#endif + #endif /* WSOCKET_H */ -- cgit v1.2.3-55-g6feb