From 855ccd6c97cc29efd494abe56608f44a7974d3fe Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Fri, 10 Sep 2010 10:30:53 +0200 Subject: send clients --- Makefile | 21 +++++++++--- lsircbot.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sircbot-send.c | 40 ++++++++++++++++++++++ 3 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 lsircbot.c create mode 100644 sircbot-send.c diff --git a/Makefile b/Makefile index 62c42db..e0956f8 100644 --- a/Makefile +++ b/Makefile @@ -4,15 +4,26 @@ GIT_VERSION := $(shell [ -d .git ] && echo "-$$(git describe --always)") CFLAGS ?= -g CFLAGS += -DVERSION=\"$(VERSION)$(GIT_VERSION)\" -all: sircbot +TARGETS = sircbot sircbot-send -sircbot_OBJ = sircbot.o irc.o +ifneq (NOLUA,) +TARGETS += sircbot.so +LUA_LIBS=-llua +endif -sircbot: $(sircbot_OBJ) +all: $(TARGETS) + +sircbot: sircbot.o irc.o + $(CC) $(LDFLAGS) -o $@ $^ + +sircbot-send: sircbot-send.o $(CC) $(LDFLAGS) -o $@ $^ +sircbot.so: lsircbot.o + $(CC) -shared $(LDFLAGS) -o $@ $^ $(LUA_LIBS) + .c.o: - $(CC) $(CFLAGS) -c $^ + $(CC) -fPIC $(CFLAGS) -c $^ clean: - rm -rf sircbot $(sircbot_OBJ) + rm -f *.o $(TARGETS) diff --git a/lsircbot.c b/lsircbot.c new file mode 100644 index 0000000..c283f0e --- /dev/null +++ b/lsircbot.c @@ -0,0 +1,104 @@ +#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; +} + diff --git a/sircbot-send.c b/sircbot-send.c new file mode 100644 index 0000000..6f109d3 --- /dev/null +++ b/sircbot-send.c @@ -0,0 +1,40 @@ +#include +#include +#include + +#include +#include +#include + +int connect_channel(const char *channel_name) +{ + struct sockaddr_un sun; + int fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) + return fd; + + sun.sun_family = AF_UNIX; + snprintf(sun.sun_path, sizeof(sun.sun_path), "/var/run/sircbot/%s", + channel_name); + if (connect(fd, (struct sockaddr *) &sun, sizeof(sun)) == 0) + return fd; + perror(sun.sun_path); + close(fd); + return -1; +} + +int main(int argc, char *argv[]) +{ + int i; + int fd = connect_channel(argv[1]); + char buf[2048]; + + if (fd < 0) + return 1; + + while (fgets(buf, sizeof(buf), stdin)) + if (write(fd, buf, strlen(buf)) < 0) + err(1, "write"); + return 0; +} + -- cgit v1.2.3