10 Commits

Author SHA1 Message Date
83764d1e1b Fix xB.adoc parsing with current libasciidoc 2022-08-24 03:17:05 +02:00
a717782480 Build with AsciiDoc as well as Asciidoctor 2022-08-24 00:13:51 +02:00
c50c959f4d Bump copyright years 2022-08-17 18:27:52 +02:00
0dd7536b5a Update README 2022-08-15 15:49:59 +02:00
0750096827 xC: expand behaviour.editor_command examples 2022-08-14 20:27:30 +02:00
49d9980662 xC: improve backlog helper capabilities
Snippets now receive positional parameters in the form of the buffer's
name in the locale encoding, and a filename if applicable
(we keep passing stdin along with the filename, which happens to
work out well for less(1)).

The default value of the configuration option also no longer uses
the "long prompt", which used to unhelpfully tell position in terms
of lines, but rather sets its own prompt that counts pages,
and makes sure to indicate the source buffer.

The main motivation behind this change is to make the 'v' command
work in less(1).  LESSSECURE must be omitted from the snippet
for this to work.

Bump liberty to receive a config parser that allows for less
convoluted escaping.
2022-08-14 18:52:26 +02:00
2f7fbcdc5d CMakeLists.txt: fix a typo 2022-08-12 13:21:46 +02:00
ef0cbe9a59 Rename the project
It is about to see some extensions, obsoleting the number three.
2022-08-07 10:40:42 +02:00
2d8808d795 utm-filter.lua: mention the passing of fbclid 2022-07-18 17:59:28 +02:00
60d52ad479 xC, xD: add basic WALLOPS support 2022-02-04 22:48:54 +01:00
12 changed files with 152 additions and 75 deletions

12
.gitignore vendored
View File

@@ -3,9 +3,9 @@
# Qt Creator files
/CMakeLists.txt.user*
/uirc3.config
/uirc3.files
/uirc3.creator*
/uirc3.includes
/uirc3.cflags
/uirc3.cxxflags
/xK.config
/xK.files
/xK.creator*
/xK.includes
/xK.cflags
/xK.cxxflags

View File

@@ -1,6 +1,6 @@
# Ubuntu 18.04 LTS and OpenBSD 6.4
cmake_minimum_required (VERSION 3.10)
project (uirc3 VERSION 1.5.0 LANGUAGES C)
project (xK VERSION 1.5.0 DESCRIPTION "IRC client, daemon and bot" LANGUAGES C)
# Options
option (WANT_READLINE "Use GNU Readline for the UI (better)" ON)
@@ -196,7 +196,7 @@ add_custom_target (clang-tidy
# Installation
install (TARGETS xB xC xD DESTINATION ${CMAKE_INSTALL_BINDIR})
install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
# XXX: our defaults for XDG_DATA_DIRS expect /usr/local/shore or /usr/share
# XXX: our defaults for XDG_DATA_DIRS expect /usr/local/share or /usr/share
install (DIRECTORY plugins/xB/
DESTINATION ${CMAKE_INSTALL_DATADIR}/xB/plugins USE_SOURCE_PERMISSIONS)
install (DIRECTORY plugins/xC/
@@ -204,20 +204,31 @@ install (DIRECTORY plugins/xC/
# Generate documentation from text markup
find_program (ASCIIDOCTOR_EXECUTABLE asciidoctor)
if (NOT ASCIIDOCTOR_EXECUTABLE)
message (FATAL_ERROR "asciidoctor not found")
find_program (A2X_EXECUTABLE a2x)
if (NOT ASCIIDOCTOR_EXECUTABLE AND NOT A2X_EXECUTABLE)
message (FATAL_ERROR "Neither asciidoctor nor a2x were found")
endif ()
foreach (page xB xC xD)
set (page_output "${PROJECT_BINARY_DIR}/${page}.1")
list (APPEND project_MAN_PAGES "${page_output}")
add_custom_command (OUTPUT ${page_output}
COMMAND ${ASCIIDOCTOR_EXECUTABLE} -b manpage
-a release-version=${project_version}
"${PROJECT_SOURCE_DIR}/${page}.adoc"
-o "${page_output}"
DEPENDS ${page}.adoc
COMMENT "Generating man page for ${page}" VERBATIM)
if (ASCIIDOCTOR_EXECUTABLE)
add_custom_command (OUTPUT ${page_output}
COMMAND ${ASCIIDOCTOR_EXECUTABLE} -b manpage
-a release-version=${project_version}
-o "${page_output}"
"${PROJECT_SOURCE_DIR}/${page}.adoc"
DEPENDS ${page}.adoc
COMMENT "Generating man page for ${page}" VERBATIM)
elseif (A2X_EXECUTABLE)
add_custom_command (OUTPUT ${page_output}
COMMAND ${A2X_EXECUTABLE} --doctype manpage --format manpage
-a release-version=${project_version}
-D "${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/${page}.adoc"
DEPENDS ${page}.adoc
COMMENT "Generating man page for ${page}" VERBATIM)
endif ()
endforeach ()
add_custom_target (docs ALL DEPENDS ${project_MAN_PAGES})
@@ -229,7 +240,6 @@ foreach (page ${project_MAN_PAGES})
endforeach ()
# CPack
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Unreasonable IRC client, daemon and bot")
set (CPACK_PACKAGE_VERSION "${project_version_safe}")
set (CPACK_PACKAGE_VENDOR "Premysl Eric Janouch")
set (CPACK_PACKAGE_CONTACT "Přemysl Eric Janouch <p@janouch.name>")

View File

@@ -1,4 +1,4 @@
Copyright (c) 2014 - 2021, Přemysl Eric Janouch <p@janouch.name>
Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

9
NEWS
View File

@@ -1,3 +1,12 @@
Unreleased
* xC: improved backlog helper integration capabilities
* xC: made it show WALLOPS messages, as PRIVMSG for the server buffer
* xD: implemented WALLOPS, choosing to make it target even non-operators
1.5.0 (2021-12-21) "The Show Must Go On"
* xC: made it possible to pass the cursor position to external editors,

View File

@@ -1,11 +1,11 @@
uirc3
=====
xK
==
The unreasonable IRC trinity. This project consists of an IRC client, daemon,
and bot. It's all you're ever going to need for chatting, as long as you can
make do with minimalist software.
'xK' (chat kit) is an IRC software suite consisting of a terminal client,
daemon, and bot. It's all you're ever going to need for chatting,
so long as you can make do with slightly minimalist software.
They have these potentially interesting properties:
They come with these potentially interesting properties:
- supporting IRCv3, SOCKS, IPv6, TLS (including client certificates)
- lean on dependencies
@@ -14,18 +14,18 @@ They have these potentially interesting properties:
xC
--
The IRC client. It is largely defined by being built on top of GNU Readline
that has been hacked to death. Its interface should feel somewhat familiar for
weechat or irssi users.
The IRC client, and the core of 'xK'. It is largely defined by being built
on top of GNU Readline that has been hacked to death. Its interface should feel
somewhat familiar for weechat or irssi users.
image::xC.png[align="center"]
This is the core of the project. It has most of the stuff you'd expect of
an IRC client, such as being multiserver, a powerful configuration system,
integrated help, text formatting, automatic splitting of overlong messages,
multiline editing, bracketed paste support, decent word wrapping, autocomplete,
logging, CTCP queries, auto-away, command aliases, and basic support for Lua
scripting. As a unique bonus, you can launch a full text editor from within.
It has most of the stuff you'd expect of an IRC client, such as being
multiserver, a powerful configuration system, integrated help, text formatting,
automatic splitting of overlong messages, multiline editing, bracketed paste
support, decent word wrapping, autocomplete, logging, CTCP queries, auto-away,
command aliases, and basic support for Lua scripting. As a unique bonus,
you can launch a full text editor from within.
xD
--
@@ -71,7 +71,8 @@ a package with the latest development version from Archlinux's AUR.
Building
--------
Build dependencies: CMake, pkg-config, asciidoctor, awk, liberty (included) +
Build dependencies: CMake, pkg-config, asciidoctor or asciidoc, awk,
liberty (included) +
Runtime dependencies: openssl +
Additionally for 'xC': curses, libffi, lua >= 5.3 (optional),
readline >= 6.0 or libedit >= 2013-07-12
@@ -79,9 +80,9 @@ Additionally for 'xC': curses, libffi, lua >= 5.3 (optional),
Avoid libedit if you can, in general it works but at the moment history is
acting up and I have no clue about fixing it.
$ git clone --recursive https://git.janouch.name/p/uirc3.git
$ mkdir uirc3/build
$ cd uirc3/build
$ git clone --recursive https://git.janouch.name/p/xK.git
$ mkdir xK/build
$ cd xK/build
$ cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DWANT_READLINE=ON -DWANT_LIBEDIT=OFF -DWANT_LUA=ON
$ make
@@ -93,7 +94,7 @@ To install the application, you can do either the usual:
Or you can try telling CMake to make a package for you:
$ cpack -G DEB # also supported: RPM, FreeBSD
# dpkg -i uirc3-*.deb
# dpkg -i xK-*.deb
Usage
-----
@@ -151,14 +152,18 @@ Beware that you can easily break the program if you're not careful.
How do I make xC look like the screenshot?
------------------------------------------
First of all, you must build it with Lua support. With the defaults, 'xC'
doesn't look too fancy because I don't want to depend on Lua or 256-colour
terminals. In addition to that, I appear to be one of the few people who use
black on white terminals.
With the defaults, 'xC' doesn't look too fancy because I don't want to have
a hard dependency on either Lua for the bundled script that provides an easily
adjustable enhanced prompt, or on 256-colour terminals. Moreover, it's nearly
impossible to come up with a colour theme that would work well with both
black-on-white and white-on-black terminals, or anything wild in between.
Assuming that your build supports Lua plugins, and that you have a decent,
properly set-up terminal emulator, it suffices to run:
/set behaviour.backlog_helper = Press Tab here and change +Gb to +Gb1d
/set behaviour.date_change_line = "%a %e %b %Y"
/set behaviour.plugin_autoload += "fancy-prompt.lua"
/set behaviour.backlog_helper = "LESSSECURE=1 less -R +Gb1d -Ps'Backlog ?ltlines %lt-%lb?L/%L. .?e(END):?pB%pB\\%..'"
/set attributes.userhost = "\x1b[38;5;109m"
/set attributes.join = "\x1b[38;5;108m"
/set attributes.part = "\x1b[38;5;138m"
@@ -179,7 +184,7 @@ configurations accordingly, but I consider it rather messy and unnecessary.
Contributing and Support
------------------------
Use https://git.janouch.name/p/uirc3 to report any bugs, request features,
Use https://git.janouch.name/p/xK to report any bugs, request features,
or submit pull requests. `git send-email` is tolerated. If you want to discuss
the project, feel free to join me at ircs://irc.janouch.name, channel #dev.

Submodule liberty updated: 1b9d89cab3...f545be725d

View File

@@ -18,6 +18,9 @@
-- A list of useless URL parameters that don't affect page function
local banned = {
gclid = 1,
-- Alas, Facebook no longer uses this parameter, see:
-- https://news.ycombinator.com/item?id=32117489
fbclid = 1,
utm_source = 1,

12
xB.adoc
View File

@@ -1,8 +1,8 @@
xB(1)
=====
:doctype: manpage
:manmanual: uirc3 Manual
:mansource: uirc3 {release-version}
:manmanual: xK Manual
:mansource: xK {release-version}
Name
----
@@ -60,14 +60,14 @@ using the IRC protocol. (Caveat: the standard C library doesn't automatically
flush FILE streams for pipes on newlines.) A special *XB* command is introduced
for RPC, with the following subcommands:
*XB get_config* _key_::
*XB get_config* __key__::
Request the value of the given configuration option. If no such option
exists, the value will be empty. The response will be delivered in
the following format:
+
```
....
XB :value
```
....
+
This is particularly useful for retrieving the *prefix* string.
@@ -100,5 +100,5 @@ _/usr/share/xB/plugins/_::
Reporting bugs
--------------
Use https://git.janouch.name/p/uirc3 to report bugs, request features,
Use https://git.janouch.name/p/xK to report bugs, request features,
or submit pull requests.

10
xC.adoc
View File

@@ -1,8 +1,8 @@
xC(1)
=====
:doctype: manpage
:manmanual: uirc3 Manual
:mansource: uirc3 {release-version}
:manmanual: xK Manual
:mansource: xK {release-version}
Name
----
@@ -25,9 +25,9 @@ Options
other formatting marks to ANSI codes retrieved from the *terminfo*(5)
database:
+
```
....
printf '\x02bold\x02\n' | xC -f
```
....
+
This feature may be used to preview server MOTD files.
@@ -119,7 +119,7 @@ to work but exhibits bugs that are not our fault.
Reporting bugs
--------------
Use https://git.janouch.name/p/uirc3 to report bugs, request features,
Use https://git.janouch.name/p/xK to report bugs, request features,
or submit pull requests.
See also

54
xC.c
View File

@@ -1,7 +1,7 @@
/*
* xC.c: a terminal-based IRC client
*
* Copyright (c) 2015 - 2021, Přemysl Eric Janouch <p@janouch.name>
* Copyright (c) 2015 - 2022, Přemysl Eric Janouch <p@janouch.name>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
@@ -2443,7 +2443,8 @@ static struct config_schema g_config_behaviour[] =
.default_ = "on",
.on_change = on_config_word_wrapping_change },
{ .name = "editor_command",
.comment = "VIM: \"vim +%Bgo %F\", Emacs: \"emacs -nw +%L:%C %F\"",
.comment = "VIM: \"vim +%Bgo %F\", Emacs: \"emacs -nw +%L:%C %F\", "
"nano/micro/kakoune: \"nano/micro/kak +%L:%C %F\"",
.type = CONFIG_ITEM_STRING },
{ .name = "process_pasted_text",
.comment = "Normalize newlines and quote the command prefix in pastes",
@@ -2480,9 +2481,11 @@ static struct config_schema g_config_behaviour[] =
.default_ = "1000",
.on_change = on_config_backlog_limit_change },
{ .name = "backlog_helper",
.comment = "Shell command to display a buffer's history",
.comment = "Shell command to page buffer history (args: name [path])",
.type = CONFIG_ITEM_STRING,
.default_ = "\"LESSSECURE=1 less -M -R +Gb\"" },
.default_ = "`name=$(echo \"$1\" | sed 's/[%?:.]/\\\\&/g'); "
"prompt='?f%F:'$name'. ?db- page %db?L of %D. .(?eEND:?PB%PB\\%..)'; "
"LESSSECURE=1 less +Gb -Ps\"$prompt\" \"${2:--R}\"`" },
{ .name = "backlog_helper_strip_formatting",
.comment = "Strip formatting from backlog helper input",
.type = CONFIG_ITEM_BOOLEAN,
@@ -7488,6 +7491,16 @@ irc_handle_topic (struct server *s, const struct irc_message *msg)
}
}
static void
irc_handle_wallops (struct server *s, const struct irc_message *msg)
{
if (!msg->prefix || msg->params.len < 1)
return;
const char *message = msg->params.vector[0];
log_server (s, s->buffer, 0, "<#n> #m", msg->prefix, message);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static struct irc_handler g_irc_handlers[] =
@@ -7511,6 +7524,7 @@ static struct irc_handler g_irc_handlers[] =
{ "QUIT", irc_handle_quit },
{ "TAGMSG", irc_handle_tagmsg },
{ "TOPIC", irc_handle_topic },
{ "WALLOPS", irc_handle_wallops },
};
static bool
@@ -13201,6 +13215,13 @@ build_editor_command (struct app_context *ctx, const char *filename)
&& !(command = getenv ("EDITOR")))
command = "vi";
// Although most visual editors support a "+LINE" argument (every
// editor mentioned in the default value of behaviour.editor_command,
// plus vi, mcedit, vis, ...), it isn't particularly useful by itself.
// We need to be able to specify the column number.
//
// Seeing as less popular software may try to process this as a filename
// and fail, do not bother with this "undocumented standard feature".
strv_append (&argv, command);
strv_append (&argv, filename);
return argv;
@@ -13355,15 +13376,19 @@ input_editor_cleanup (struct app_context *ctx)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void
launch_backlog_helper (struct app_context *ctx, int backlog_fd)
launch_backlog_helper (struct app_context *ctx, int backlog_fd,
const char *name, const char *path)
{
hard_assert (!ctx->running_backlog_helper);
switch (spawn_helper_child (ctx))
{
case 0:
dup2 (backlog_fd, STDIN_FILENO);
execl ("/bin/sh", "/bin/sh", "-c", get_config_string
(ctx->config.root, "behaviour.backlog_helper"), NULL);
char *localized_name =
iconv_xstrdup (ctx->term_from_utf8, (char *) name, -1, NULL);
execl ("/bin/sh", "/bin/sh", "-c",
get_config_string (ctx->config.root, "behaviour.backlog_helper"),
PROGRAM_NAME, localized_name, path, NULL);
print_error ("%s: %s",
"Failed to launch backlog helper", strerror (errno));
_exit (EXIT_FAILURE);
@@ -13408,7 +13433,7 @@ display_backlog (struct app_context *ctx, int flush_opts)
rewind (backlog);
set_cloexec (fileno (backlog));
launch_backlog_helper (ctx, fileno (backlog));
launch_backlog_helper (ctx, fileno (backlog), buffer->name, NULL);
fclose (backlog);
return true;
}
@@ -13436,24 +13461,25 @@ on_display_full_log (int count, int key, void *user_data)
(void) key;
struct app_context *ctx = user_data;
char *path = buffer_get_log_path (ctx->current_buffer);
struct buffer *buffer = ctx->current_buffer;
char *path = buffer_get_log_path (buffer);
FILE *full_log = fopen (path, "rb");
free (path);
if (!full_log)
{
log_global_error (ctx, "Failed to open log file for #s: #l",
ctx->current_buffer->name, strerror (errno));
free (path);
return false;
}
if (ctx->current_buffer->log_file)
if (buffer->log_file)
// The regular flush will log any error eventually
(void) fflush (ctx->current_buffer->log_file);
(void) fflush (buffer->log_file);
set_cloexec (fileno (full_log));
launch_backlog_helper (ctx, fileno (full_log));
launch_backlog_helper (ctx, fileno (full_log), buffer->name, path);
fclose (full_log);
free (path);
return true;
}

View File

@@ -1,8 +1,8 @@
xD(1)
=====
:doctype: manpage
:manmanual: uirc3 Manual
:mansource: uirc3 {release-version}
:manmanual: xK Manual
:mansource: xK {release-version}
Name
----
@@ -49,5 +49,5 @@ _/etc/xdg/xD/xD.conf_::
Reporting bugs
--------------
Use https://git.janouch.name/p/uirc3 to report bugs, request features,
Use https://git.janouch.name/p/xK to report bugs, request features,
or submit pull requests.

26
xD.c
View File

@@ -1,7 +1,7 @@
/*
* xD.c: an IRC daemon
*
* Copyright (c) 2014 - 2021, Přemysl Eric Janouch <p@janouch.name>
* Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
@@ -2932,6 +2932,29 @@ irc_handle_links (const struct irc_message *msg, struct client *c)
irc_send_reply (c, IRC_RPL_ENDOFLINKS, mask);
}
static void
irc_handle_wallops (const struct irc_message *msg, struct client *c)
{
if (msg->params.len < 1)
RETURN_WITH_REPLY (c, IRC_ERR_NEEDMOREPARAMS, msg->command);
if (!(c->mode & IRC_USER_MODE_OPERATOR))
RETURN_WITH_REPLY (c, IRC_ERR_NOPRIVILEGES);
const char *message = msg->params.vector[0];
// Our interpretation: anonymize the sender,
// and target all users who want to receive these messages
struct str_map_iter iter = str_map_iter_make (&c->ctx->users);
struct client *target;
while ((target = str_map_iter_next (&iter)))
{
if (target != c && !(target->mode & IRC_USER_MODE_RX_WALLOPS))
continue;
client_send (target, ":%s WALLOPS :%s", c->ctx->server_name, message);
}
}
static void
irc_handle_kill (const struct irc_message *msg, struct client *c)
{
@@ -2994,6 +3017,7 @@ irc_register_handlers (struct server_context *ctx)
{ "ADMIN", true, irc_handle_admin, 0, 0 },
{ "STATS", true, irc_handle_stats, 0, 0 },
{ "LINKS", true, irc_handle_links, 0, 0 },
{ "WALLOPS", true, irc_handle_wallops, 0, 0 },
{ "MODE", true, irc_handle_mode, 0, 0 },
{ "PRIVMSG", true, irc_handle_privmsg, 0, 0 },