aboutsummaryrefslogtreecommitdiffstats
path: root/lua
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2015-06-19 08:40:52 +0200
committerNatanael Copa <ncopa@alpinelinux.org>2015-06-19 08:43:02 +0200
commitfe552a1422cb40b99159947c5f8f66bd99a13d4c (patch)
treef2d06be41b59085aadc7dc6defd23fb19e3138cc /lua
parent7e29992497f891666d9eaa25a1b80544b8e5efa5 (diff)
downloadsircbot-fe552a1422cb40b99159947c5f8f66bd99a13d4c.tar.bz2
sircbot-fe552a1422cb40b99159947c5f8f66bd99a13d4c.tar.xz
lua: add support for building multiple versions
It might be handy to be able to build Lua module for multiple Lua versions.
Diffstat (limited to 'lua')
-rw-r--r--lua/lsircbot.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/lua/lsircbot.c b/lua/lsircbot.c
new file mode 100644
index 0000000..0b97d5a
--- /dev/null
+++ b/lua/lsircbot.c
@@ -0,0 +1,113 @@
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#define SBCONN_META "sircbot-connection"
+#ifndef VERSION
+#define VERSION "unknown"
+#endif
+
+#if LUA_VERSION_NUM < 502
+# define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l))
+# define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l))
+#endif
+
+static int *Lsbconn_checkarg(lua_State *L, int index)
+{
+ int *fdp;
+ luaL_checktype(L, index, LUA_TUSERDATA);
+ fdp = (int *) luaL_checkudata(L, index, SBCONN_META);
+ if (fdp == NULL) {
+ const char *msg = lua_pushfstring(L, "%s expected, got %s",
+ SBCONN_META,
+ luaL_typename(L, index));
+ luaL_argerror(L, index, msg);
+ }
+ return fdp;
+}
+
+static int Lsbconn_new(lua_State *L)
+{
+ int *fdp;
+ const char *channel_name = luaL_checklstring(L, 1, NULL);
+ struct sockaddr_un sun;
+ fdp = (int *) lua_newuserdata(L, sizeof(int *));
+ luaL_getmetatable(L, SBCONN_META);
+ lua_setmetatable(L, -2);
+
+ *fdp = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (*fdp < 0)
+ luaL_error(L, "Failed to create socket for '%s'", channel_name);
+
+ sun.sun_family = AF_UNIX;
+ snprintf(sun.sun_path, sizeof(sun.sun_path), "/var/run/sircbot/%s",
+ channel_name);
+ if (connect(*fdp, (struct sockaddr *) &sun, sizeof(sun)) < 0)
+ luaL_error(L, "%s", sun.sun_path);
+
+ return 1;
+}
+
+static int Lsbconn_destroy(lua_State *L)
+{
+ int *fdp = Lsbconn_checkarg(L, 1);
+ close(*fdp);
+ return 1;
+}
+
+static int Lsbconn_send(lua_State *L)
+{
+ int *fdp;
+ const char *msg;
+ int r;
+
+ fdp = Lsbconn_checkarg(L, 1);
+ msg = luaL_checklstring(L, 2, NULL);
+ r = write(*fdp, msg, strlen(msg));
+ lua_pushinteger(L, r);
+ return 1;
+}
+
+static const luaL_Reg sbconn_meta_methods[] = {
+ { "__gc", Lsbconn_destroy },
+ { NULL, NULL }
+};
+
+static const luaL_Reg sircbot_methods[] = {
+ { "connect", Lsbconn_new },
+ { "send", Lsbconn_send },
+ { NULL, NULL }
+};
+
+LUALIB_API int luaopen_sircbot(lua_State *L)
+{
+ /* register sircbot library */
+ luaL_newlib(L, sircbot_methods);
+
+ /* version */
+ lua_pushliteral(L, "version");
+ lua_pushliteral(L, VERSION);
+ lua_settable(L, -3);
+
+ /* register metatable for it */
+ luaL_newmetatable(L, SBCONN_META);
+ luaL_setfuncs(L, sbconn_meta_methods, 0);
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, -3);
+ lua_rawset(L, -3);
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, -3);
+ lua_rawset(L, -3);
+ lua_pop(L, 1);
+
+ return 1;
+}
+