171 lines
6.6 KiB
Lua
171 lines
6.6 KiB
Lua
-- -*- Mode: Lua; indent-tabs-mode: nil; lua-indent-level: 2 -*-
|
|
-- LADI Continuous Integration (ladici)
|
|
-- SPDX-FileCopyrightText: Copyright © 2010-2023 Nedko Arnaudov */
|
|
-- SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
--module('irc_client', package.seeall)
|
|
|
|
local function connect(location)
|
|
assert(location.args.host)
|
|
assert(location.args.nick)
|
|
|
|
local host = location.args.host
|
|
local port = location.args.port or 6667
|
|
local nick = location.args.nick
|
|
local username = location.args.username or nick
|
|
local realname = location.args.realname or nick
|
|
local join = location.args.join
|
|
|
|
local print = function(msg) hub.incoming_message(msg, location) end
|
|
|
|
local peer
|
|
|
|
local function send(msg) irc.send_to_peer(peer, msg) end
|
|
|
|
local function print_notice(msg, prefix)
|
|
if msg then
|
|
if type(msg) == 'string' then print(prefix .. msg) end
|
|
if type(msg) == 'table' then print(prefix .. table.concat(msg, ' ')) end
|
|
end
|
|
end
|
|
|
|
local server_capabilities = {}
|
|
local command_handlers = {}
|
|
|
|
command_handlers['PING'] = function(prefix, command, params)
|
|
--print("PING received")
|
|
if #params ~= 0 then
|
|
local msg = "PONG"
|
|
for _, server in pairs(params) do
|
|
msg = msg .. ' ' .. server
|
|
end
|
|
send(msg)
|
|
end
|
|
end
|
|
|
|
command_handlers['NOTICE'] = function(prefix, command, params) print_notice(params[2], 'NOTICE: ') end
|
|
|
|
command_handlers['MODE'] = function(prefix, command, params)
|
|
print(('MODE: [%s] [%s]'):format(params[1], params[2]))
|
|
end
|
|
|
|
command_handlers['PRIVMSG'] =
|
|
function(prefix, command, params)
|
|
nick, user, host = irc.parse_nick_prefix(prefix)
|
|
-- print(("'%s' -> '%s' : '%s'"):format(nick, params[1], params[2]))
|
|
if params[1]:sub(1, 1) == "#" then
|
|
channel = params[1]:sub(2)
|
|
else
|
|
channel = nil
|
|
end
|
|
-- print(("channel is '%s'"):format(tostring(channel)))
|
|
hub.incoming_message(params[2], location, nick, channel)
|
|
end
|
|
|
|
command_handlers['JOIN'] = function(prefix, command, params)
|
|
nick, user, host = irc.parse_nick_prefix(prefix)
|
|
|
|
print(("'%s':'%s':'%s' joined '%s'"):format(tostring(nick), tostring(user), tostring(host), params[1]))
|
|
hub.join(location, params[1]:sub(2), nick)
|
|
end
|
|
|
|
-- welcome
|
|
command_handlers['001'] = function(prefix, command, params) print_notice(table.concat(params, ' ', 2), 'WELCOME: ') end
|
|
-- your host
|
|
command_handlers['002'] = function(prefix, command, params) print_notice(table.concat(params, ' ', 2), 'SHOST: ') end
|
|
-- server created
|
|
command_handlers['003'] = function(prefix, command, params) print_notice(table.concat(params, ' ', 2), 'SCREAT: ') end
|
|
-- server info
|
|
command_handlers['004'] = function(prefix, command, params)
|
|
local server_name = params[2]
|
|
local server_version = params[3]
|
|
local user_modes_available = params[4]
|
|
local channel_modes_available = params[5]
|
|
print_notice(server_name, 'SNAME: ')
|
|
print_notice(server_version, 'SVER: ')
|
|
print_notice(user_modes_available, 'UMODES: ')
|
|
print_notice(channel_modes_available, 'CMODES: ')
|
|
end
|
|
|
|
-- bounce / supported stuff
|
|
command_handlers['005'] = function(prefix, command, params)
|
|
if #params > 2 then
|
|
for i = 2, #params - 1 do
|
|
local param = params[i]
|
|
local _, _, key, value = param:find('^([^=]+)=(.+)')
|
|
if not key then
|
|
print(('SCAPS: %s is available'):format(param))
|
|
key = param
|
|
value = true
|
|
else
|
|
print(('SCAPS: %s is [%s]'):format(key, value))
|
|
end
|
|
server_capabilities[key] = value
|
|
end
|
|
end
|
|
end
|
|
|
|
local function stats_reply(prefix, command, params)
|
|
print_notice(table.concat(params, ' ', 2), 'SSTATS: ')
|
|
end
|
|
|
|
command_handlers['250'] = stats_reply
|
|
command_handlers['251'] = stats_reply
|
|
command_handlers['252'] = stats_reply
|
|
command_handlers['253'] = stats_reply
|
|
command_handlers['254'] = stats_reply
|
|
command_handlers['255'] = stats_reply
|
|
command_handlers['265'] = stats_reply
|
|
command_handlers['266'] = stats_reply
|
|
|
|
local function motd_reply(prefix, command, params)
|
|
print_notice(table.concat(params, ' ', 2), 'MOTD: ')
|
|
end
|
|
|
|
command_handlers['375'] = motd_reply -- MOTD start
|
|
command_handlers['372'] = motd_reply -- MOTD middle
|
|
command_handlers['376'] = motd_reply -- MOTD end
|
|
|
|
peer, err = remotes.connect_tcp(host, port)
|
|
if not peer then return nil, err end
|
|
|
|
local disconnect_function = nil
|
|
remotes.add_thread(function()
|
|
send(("NICK %s"):format(nick))
|
|
send(("USER %s %s %s :%s"):format(username, peer.get_local_ip(), host, realname))
|
|
if join then send("JOIN " .. join) end
|
|
err = irc.receive(peer, command_handlers, function(msg) print(msg) end)
|
|
-- print(err)
|
|
peer.close()
|
|
if disconnect_function then
|
|
-- print("Calling disconnect callback")
|
|
disconnect_function()
|
|
end
|
|
peer = nil
|
|
end)
|
|
return {
|
|
disconnect = function(disconnect_function_param)
|
|
print("Disconnecting from " .. host)
|
|
peer.close() -- this will break the receive loop
|
|
disconnect_function = disconnect_function_param
|
|
end,
|
|
send = send
|
|
}
|
|
end
|
|
|
|
local descriptor = {
|
|
name = 'IRC',
|
|
required_params = {
|
|
host="IP address or a host name if IRC server",
|
|
nick="Nickname",
|
|
},
|
|
optional_params = {
|
|
port="TCP port, defaults to 6667",
|
|
username="Username, defaults to nick",
|
|
realname="Real name, defaults to nick",
|
|
},
|
|
connect=connect,
|
|
}
|
|
|
|
return descriptor
|