about summary refs log tree commit diff
path: root/bot.lua
diff options
context:
space:
mode:
Diffstat (limited to 'bot.lua')
-rw-r--r--bot.lua68
1 files changed, 62 insertions, 6 deletions
diff --git a/bot.lua b/bot.lua
index db01ba8..0704b63 100644
--- a/bot.lua
+++ b/bot.lua
@@ -7,7 +7,9 @@ local fifo = require("fifo")
 local mom = require("mom")
 
 local function parse_message(data)
-	if string.match(data, "[\0\r\n]") then return nil, "illegal character" end
+	if string.match(data, "[\0\r\n]") then
+		return nil, "illegal character"
+	end
 
 	local pos = 1
 	local prefix
@@ -108,16 +110,23 @@ function irc_handlers.JOIN(state, line)
 	if not state.channels[line.params[1]] then
 		-- TODO validate the params at all
 		local ch_name = line.params[1]
+		local ch_config = config.channels[ch_name]
 		local ch = {}
 		state.channels[ch_name] = ch
 
-		ch.command = config.channels[ch_name].command or config.command
-		ch.invoke = config.channels[ch_name].invoke or config.invoke
+		ch.command = ch_config.command or config.command
+		ch.invoke = ch_config.invoke or config.invoke
+		ch.directory = ch_config.directory or config.directory
 
 		ch.mom_id, ch.tx_queue = state.mom:create(
 			ch.command,
 			ch_name,
-			state.rx_queue
+			state.rx_queue,
+			ch.directory
+		)
+	else
+		state.mom:start_process(
+			state.channels[line.params[1]].mom_id
 		)
 	end
 end
@@ -134,6 +143,7 @@ function irc_handlers.PRIVMSG(state, line)
 	local full_line = line.params[2]
 	local line
 	for _, prefix in ipairs(state.channels[ch].invoke) do
+		-- TODO: escape the nick itself
 		prefix = string.gsub(prefix, "%%n", state.nick)
 		prefix = string.gsub(prefix, "%%%", "%")
 		-- TODO parens and stuff maybe
@@ -199,8 +209,10 @@ local function irc_connect(loop, config)
 		-- a channel has the fields:
 		-- - invoke, a list of patterns (as in config, but being
 		--   properly populated with defaults)
+		-- - command, the command to run as a list
+		-- - directory, the dir to run it in
 		-- - mom_id, the id in the state's process mom
-		-- - tx_queue: to send messages to the ed queue
+		-- - tx_queue, to send messages to the ed queue
 		--   (note we don't have rx_queue: that is shared)
 		channels = {},
 	}
@@ -220,6 +232,10 @@ local function irc_connect(loop, config)
 				line = { command = "BADLINE", params = { line } }
 			end
 
+			if line.command == "ERROR" or state.config.debug then
+				print(raw_line)
+			end
+
 			local command = (tonumber(line.command) and "_" or "") .. line.command
 			if irc_handlers[command] then
 				irc_handlers[command](state, line)
@@ -239,14 +255,53 @@ local function irc_connect(loop, config)
 	state.mom = mom.new(loop)
 
 	loop:wrap(function () handle_ed_rx(state) end)
+
+	if config.pass then
+		fifo.put(state.queue, {
+			command = "PASS", params = { config.pass }
+		})
+	end
+
 	fifo.put(state.queue, { command = "NICK", params = { config.nick } })
 	-- TODO: config
 	fifo.put(state.queue, {
 		command = "USER",
-		params = { "ed1bot", "0", "*", ":)" },
+		params = { config.user, "0", "*", ":)" },
 	})
 end
 
+local function validate_config(c)
+	local function valid(name, thing, kind)
+		assert(type(thing) == kind,
+			kind .. " " .. name .. " must be specified"
+		)
+	end
+
+	local function optional(name, thing, kind)
+		if thing then valid(name, thing, kind) end
+	end
+
+	valid("host", c.host, "table")
+	valid("host.host", c.host.host, "string")
+	valid("host.port", c.host.port, "number")
+	valid("nick", c.nick, "string")
+	valid("user", c.user, "string")
+	optional("pass", c.pass, "string")
+	valid("directory", c.directory, "string")
+	-- TODO better
+	valid("command", c.command, "table")
+	valid("invoke", c.invoke, "table")
+	valid("channels", c.channels, "table")
+
+	for k, v in pairs(c.channels) do
+		local name = string.format("channels[%q]", k)
+		valid(name, v, "table")
+		optional(name .. ".invoke", v.invoke, "table")
+		optional(name .. ".command", v.command, "table")
+		optional(name .. ".directory", v.directory, "string")
+	end
+end
+
 do
 	local main = cqueues.new()
 	if not arg[1] then
@@ -255,6 +310,7 @@ do
 	end
 
 	local config = assert(dofile(arg[1]))
+	validate_config(config)
 
 	main:wrap(function ()
 		irc_connect(main, config)