#include #include #include #include #include #include #include #include #include #define SBCONN_META "sircbot-connection" #ifndef VERSION #define VERSION "unknown" #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) luaL_typerror(L, index, SBCONN_META); 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_register(L, "sircbot", 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_register(L, NULL, sbconn_meta_methods); 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; }