diff --git a/Makefile b/Makefile index 5979161..c235a5b 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,14 @@ CFLAGS = -Wall -Werror -TARGETS = bot -TARGETS += extras/factoids +TARGETS = bot factoids all: $(TARGETS) -extras/factoids: extras/factoids.o extras/cdb.o extras/cdbmake.o +%: src/% + cp $< $@ + +src/bot: +src/factoids: src/factoids.o src/cdb.o src/cdbmake.o .PHONY: clean clean: - rm -f $(TARGETS) *.o extras/*.o + rm -f $(TARGETS) $(addprefix src/, $(TARGETS)) src/*.o diff --git a/README b/README index 47c1780..82bd7d7 100644 --- a/README +++ b/README @@ -84,6 +84,16 @@ want, and you don't even need to restart anything to apply your changes, since a new handler is launched for each message. +factoids +======== + +A program to maintain a low-overhead, read-optimized database file, which +can store multiple values for each key. This was written to help develop +infobots, but can also be used for any other key/value store needed. + +The `infobot.py` program in `contrib/` has a simple infobot implementation. + + Caution ======= @@ -103,26 +113,6 @@ much more difficult to accidentally create an exploit. Or create a new handler in Python, Ruby, etc. -Extras -====== - -Included AT NO ADDITIONAL COST, in the `extras/` directory, are: - - -newmont -------- - -A simple handler, written in lua. - - -factoids --------- - -A program to maintain a low-overhead, read-optimized database file, which -can store multiple values for each key. This was written to help develop -infobots, but can also be used for any other key/value store needed. - - Author ====== diff --git a/TODO b/TODO deleted file mode 100644 index 8b13789..0000000 --- a/TODO +++ /dev/null @@ -1 +0,0 @@ - diff --git a/contrib/infobot.py b/contrib/infobot.py new file mode 100755 index 0000000..de6e434 --- /dev/null +++ b/contrib/infobot.py @@ -0,0 +1,48 @@ +#! /usr/bin/python + +## +## Example of an infobot, using the provided helper. +## + +import sys +import os +from subprocess import * + +db = "infobot.cdb" + +command = os.environ.get("command") +sender = os.environ.get("sender") +forum = os.environ.get("forum") +text = os.environ.get("text") + +def factoids(*args): + cmd = ["./factoids"] + cmd.extend(args) + p = Popen(cmd, stdout=PIPE, stderr=STDOUT) + for bline in p.stdout: + line = bline.decode('utf-8')[:-1] + print("PRIVMSG %s :%s" % (forum, line)) + +# Create db if it doesn't exist +if not os.path.exists(db): + factoids("-n", db) + +if command == "_INIT_": + print("NICK infotest") + print("USER infotest infotest infotest: Infobot example") +elif command == "001": + print("JOIN #infotest") +elif command == "PRIVMSG": + if text[0] == "!": + txt = text[1:] + if " += " in txt: + key, val = txt.split(' += ', 1) + factoids("-a", val, db, key) + elif " -= " in txt: + key, glob = txt.split(' -= ', 1) + factoids("-r", glob, db, key) + else: + factoids("-l", db, txt) + else: + factoids(db, text) + diff --git a/extras/newmont b/contrib/newmont similarity index 89% rename from extras/newmont rename to contrib/newmont index 0cb3f89..02c7aee 100755 --- a/extras/newmont +++ b/contrib/newmont @@ -2,12 +2,12 @@ -- -- A very simple bot which will join IRC, join #newmont, and --- respond to any messages with "strawberry" in them. It also --- has some naïve nickname collision avoidance. +-- talk about strawberries. It also has some naïve nickname +-- collision avoidance. -- -- This is a good place to start if you're not going to write -- your handler in lua. If you *do* want to use lua, you should --- take a look at bot.lua instead. +-- think about how to make a better design :) -- prefix = os.getenv("prefix") @@ -21,17 +21,23 @@ io.stderr:write(">>> [" .. command .. "] " .. (forum or "-") .. " " .. (text or "") .. "\n") +-- -- Our behavior depends on what the command is +-- + if (command == "_INIT_") then -- bot sends this when it first starts up, so we can log in print("NICK nemont") print("USER newmont newmont newmont :Sample bot") + elseif (command == "433") then -- Couldn't get the nickname we asked for print("NICK bot_" .. (os.time() % 500)) + elseif (command == "001") then -- IRC server sends this after successful login print("JOIN #newmont") + elseif (command == "PRIVMSG") then -- Somebody said something! if (text:find("strawberry")) then diff --git a/bot.c b/src/bot.c similarity index 100% rename from bot.c rename to src/bot.c diff --git a/extras/cdb.c b/src/cdb.c similarity index 96% rename from extras/cdb.c rename to src/cdb.c index 89cab78..03f6b99 100644 --- a/extras/cdb.c +++ b/src/cdb.c @@ -129,7 +129,10 @@ cdb_find(struct cdb_ctx *ctx, char *key, size_t keylen) fseek(ctx->f, (ctx->hash_val % 256) * 8, SEEK_SET); ctx->hash_pos = read_u32le(ctx->f); ctx->hash_len = read_u32le(ctx->f); - ctx->entry = (ctx->hash_val / 256) % ctx->hash_len; + + if (ctx->hash_len > 0) { + ctx->entry = (ctx->hash_val / 256) % ctx->hash_len; + } } uint32_t @@ -140,7 +143,7 @@ cdb_next(struct cdb_ctx *ctx, char *buf, size_t buflen) uint32_t klen; uint32_t dlen; - for (;;) { + for (; ctx->hash_len > 0;) { fseek(ctx->f, ctx->hash_pos + (ctx->entry * 8), SEEK_SET); ctx->entry = (ctx->entry + 1) % ctx->hash_len; diff --git a/extras/cdb.h b/src/cdb.h similarity index 100% rename from extras/cdb.h rename to src/cdb.h diff --git a/extras/cdbmake.c b/src/cdbmake.c similarity index 100% rename from extras/cdbmake.c rename to src/cdbmake.c diff --git a/extras/cdbmake.h b/src/cdbmake.h similarity index 100% rename from extras/cdbmake.h rename to src/cdbmake.h diff --git a/extras/factoids.c b/src/factoids.c similarity index 100% rename from extras/factoids.c rename to src/factoids.c