12 Commits

Author SHA1 Message Date
5e728f6d31 Bump version, update NEWS 2021-10-06 14:05:23 +02:00
766f68e070 Bump liberty 2021-10-06 13:52:59 +02:00
3dc5242d43 Bump liberty
Importing some minor unimportant fixes.
2021-09-26 08:55:46 +02:00
fd9d5db1d2 xD: bump the soft file descriptor limit
By default it's a mere thousand connections, which is unnecessarily
crippling our advertised ability to handle lots of them.

Thanks for the advice, Lennart.
2021-09-23 20:32:00 +02:00
cb480b4c71 xC: show orphan outcoming actions differently
It's hard to think of anything actually good here.

This would be an exceptionally rare thing to do, anyway.
2021-09-05 02:51:05 +02:00
59cc423694 xC: abandon Freenode, embrace IRCnet
You're not fucking supposed to require a fucking registration
on fucking IRC networks.
2021-08-29 15:18:20 +02:00
9323089d66 xC: mIRC didn't invent all IRC formatting
So let's not confuse ourselves.
2021-08-29 12:12:52 +02:00
de7df1f60d xC: refactor parsing of IRC formatting 2021-08-29 12:06:53 +02:00
b082e82b62 xC: fix displaying IRC colours above 16
First, we indexed the colour array without a required offset.
Second, the data type was too small and overflowed negative.

Detected during a refactor, which this is a part of.
2021-08-28 18:25:03 +02:00
b8dbc70a9c xC: respect text formatting when autosplitting 2021-08-28 18:24:20 +02:00
e0ad67a921 Bump version, update NEWS 2021-08-07 07:53:08 +02:00
565edc15b4 README.adoc: be consistent in emphasizing 2021-08-07 07:40:02 +02:00
6 changed files with 211 additions and 91 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.0) cmake_minimum_required (VERSION 3.0)
project (uirc3 VERSION 1.2.0 LANGUAGES C) project (uirc3 VERSION 1.4.0 LANGUAGES C)
# Options # Options
option (WANT_READLINE "Use GNU Readline for the UI (better)" ON) option (WANT_READLINE "Use GNU Readline for the UI (better)" ON)

17
NEWS
View File

@@ -1,10 +1,23 @@
1.3.0 (2021-xx-xx) 1.4.0 (2021-10-06) "Call Me Scruffy Scruffington"
* xC: made message autosplitting respect text formatting
* xC: fixed displaying IRC colours above 16
* xC: offer IRCnet as an IRC network to connect to,
rather than the lunatic new Freenode
* xD: started bumping the soft limit on file descriptors to the hard one
1.3.0 (2021-08-07) "New World Order"
* xC: made nick autocompletion offer recent speakers first * xC: made nick autocompletion offer recent speakers first
* All binaries have been renamed to something even sillier, * All binaries have been renamed to something even sillier,
and all references in the source tree have been redacted; and all references in the source tree have been redacted;
this represents a major incompatible change for all plugins this represents a major incompatible change for all plugins;
configuration and program data have to be adjusted manually
1.2.0 (2021-07-08) "There Are Other Countries As Well" 1.2.0 (2021-07-08) "There Are Other Countries As Well"

View File

@@ -48,7 +48,7 @@ Not supported:
- server linking (which also means no services); I consider existing protocols - server linking (which also means no services); I consider existing protocols
for this purpose ugly and tricky to implement correctly; I've also found no for this purpose ugly and tricky to implement correctly; I've also found no
use for this feature yet use for this feature yet
- online changes to configuration; the configuration system from xC could - online changes to configuration; the configuration system from 'xC' could
be used to implement this feature if needed be used to implement this feature if needed
- limits of almost any kind, just connections and mode `+l` - limits of almost any kind, just connections and mode `+l`
@@ -78,8 +78,8 @@ Building
-------- --------
Build dependencies: CMake, pkg-config, asciidoctor, awk, liberty (included) + Build dependencies: CMake, pkg-config, asciidoctor, awk, liberty (included) +
Runtime dependencies: openssl + Runtime dependencies: openssl +
Additionally for xC: curses, libffi, lua >= 5.3 (optional), Additionally for 'xC': curses, libffi, lua >= 5.3 (optional),
readline >= 6.0 or libedit >= 2013-07-12 readline >= 6.0 or libedit >= 2013-07-12
Avoid libedit if you can, in general it works but at the moment history is 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. acting up and I have no clue about fixing it.
@@ -156,10 +156,10 @@ Beware that you can easily break the program if you're not careful.
How do I make xC look like the screenshot? 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 First of all, you must build it with Lua support. With the defaults, 'xC'
look too fancy because I don't want to depend on Lua or 256-colour terminals. doesn't look too fancy because I don't want to depend on Lua or 256-colour
In addition to that, I appear to be one of the few people who use black on white terminals. In addition to that, I appear to be one of the few people who use
terminals. black on white terminals.
/set behaviour.date_change_line = "%a %e %b %Y" /set behaviour.date_change_line = "%a %e %b %Y"
/set behaviour.plugin_autoload += "fancy-prompt.lua" /set behaviour.plugin_autoload += "fancy-prompt.lua"

Submodule liberty updated: 9639777814...1b9d89cab3

247
xC.c
View File

@@ -1448,7 +1448,7 @@ enum formatter_item_type
FORMATTER_ITEM_ATTR, ///< Formatting attributes FORMATTER_ITEM_ATTR, ///< Formatting attributes
FORMATTER_ITEM_FG_COLOR, ///< Foreground colour FORMATTER_ITEM_FG_COLOR, ///< Foreground colour
FORMATTER_ITEM_BG_COLOR, ///< Background colour FORMATTER_ITEM_BG_COLOR, ///< Background colour
FORMATTER_ITEM_SIMPLE, ///< Toggle mIRC formatting FORMATTER_ITEM_SIMPLE, ///< Toggle IRC formatting
FORMATTER_ITEM_IGNORE_ATTR ///< Un/set attribute ignoration FORMATTER_ITEM_IGNORE_ATTR ///< Un/set attribute ignoration
}; };
@@ -2089,7 +2089,7 @@ struct app_context
int *nick_palette; ///< A 256-colour palette for nicknames int *nick_palette; ///< A 256-colour palette for nicknames
size_t nick_palette_len; ///< Number of entries in nick_palette size_t nick_palette_len; ///< Number of entries in nick_palette
bool awaiting_mirc_escape; ///< Awaiting a mIRC attribute escape bool awaiting_formatting_escape; ///< Awaiting an IRC formatting escape
bool in_bracketed_paste; ///< User is pasting some content bool in_bracketed_paste; ///< User is pasting some content
struct str input_buffer; ///< Buffered pasted content struct str input_buffer; ///< Buffered pasted content
@@ -2797,7 +2797,8 @@ enum
TEXT_UNDERLINE = 1 << 2, TEXT_UNDERLINE = 1 << 2,
TEXT_INVERSE = 1 << 3, TEXT_INVERSE = 1 << 3,
TEXT_BLINK = 1 << 4, TEXT_BLINK = 1 << 4,
TEXT_CROSSED_OUT = 1 << 5 TEXT_CROSSED_OUT = 1 << 5,
TEXT_MONOSPACE = 1 << 6
}; };
struct attr_printer struct attr_printer
@@ -2960,6 +2961,7 @@ attr_printer_apply (struct attr_printer *self,
attr_printer_reset (self); attr_printer_reset (self);
// TEXT_MONOSPACE is unimplemented, for obvious reasons
if (text_attrs) if (text_attrs)
attr_printer_tputs (self, tparm (set_attributes, attr_printer_tputs (self, tparm (set_attributes,
0, // standout 0, // standout
@@ -3121,7 +3123,7 @@ irc_to_utf8 (const char *text)
// #l inserts a locale-encoded string // #l inserts a locale-encoded string
// //
// #S inserts a string from the server with unknown encoding // #S inserts a string from the server with unknown encoding
// #m inserts a mIRC-formatted string (auto-resets at boundaries) // #m inserts an IRC-formatted string (auto-resets at boundaries)
// #n cuts the nickname from a string and automatically colours it // #n cuts the nickname from a string and automatically colours it
// #N is like #n but also appends userhost, if present // #N is like #n but also appends userhost, if present
// //
@@ -3152,8 +3154,6 @@ formatter_add_item (struct formatter *self, struct formatter_item template_)
FORMATTER_ADD_ITEM ((self), ATTR, .attribute = ATTR_RESET) FORMATTER_ADD_ITEM ((self), ATTR, .attribute = ATTR_RESET)
#define FORMATTER_ADD_TEXT(self, text_) \ #define FORMATTER_ADD_TEXT(self, text_) \
FORMATTER_ADD_ITEM ((self), TEXT, .text = (text_)) FORMATTER_ADD_ITEM ((self), TEXT, .text = (text_))
#define FORMATTER_ADD_SIMPLE(self, attribute_) \
FORMATTER_ADD_ITEM ((self), SIMPLE, .attribute = TEXT_ ## attribute_)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -3190,7 +3190,7 @@ static const int g_mirc_to_terminal[] =
// https://modern.ircdocs.horse/formatting.html // https://modern.ircdocs.horse/formatting.html
// http://anti.teamidiot.de/static/nei/*/extended_mirc_color_proposal.html // http://anti.teamidiot.de/static/nei/*/extended_mirc_color_proposal.html
static const char g_extra_to_256[100 - 16] = static const int16_t g_extra_to_256[100 - 16] =
{ {
52, 94, 100, 58, 22, 29, 23, 24, 17, 54, 53, 89, 52, 94, 100, 58, 22, 29, 23, 24, 17, 54, 53, 89,
88, 130, 142, 64, 28, 35, 30, 25, 18, 91, 90, 125, 88, 130, 142, 64, 28, 35, 30, 25, 18, 91, 90, 125,
@@ -3202,42 +3202,127 @@ static const char g_extra_to_256[100 - 16] =
}; };
static const char * static const char *
formatter_parse_mirc_color (struct formatter *self, const char *s) irc_parse_mirc_color (const char *s, uint8_t *fg, uint8_t *bg)
{ {
if (!isdigit_ascii (*s)) if (!isdigit_ascii (*s))
{ {
FORMATTER_ADD_ITEM (self, FG_COLOR, .color = -1); *fg = *bg = 99;
FORMATTER_ADD_ITEM (self, BG_COLOR, .color = -1);
return s; return s;
} }
int fg = *s++ - '0'; *fg = *s++ - '0';
if (isdigit_ascii (*s)) if (isdigit_ascii (*s))
fg = fg * 10 + (*s++ - '0'); *fg = *fg * 10 + (*s++ - '0');
if (fg < 16)
FORMATTER_ADD_ITEM (self, FG_COLOR, .color = g_mirc_to_terminal[fg]);
else
FORMATTER_ADD_ITEM (self, FG_COLOR,
.color = COLOR_256 (DEFAULT, g_extra_to_256[fg]));
if (*s != ',' || !isdigit_ascii (s[1])) if (*s != ',' || !isdigit_ascii (s[1]))
return s; return s;
s++; s++;
int bg = *s++ - '0'; *bg = *s++ - '0';
if (isdigit_ascii (*s)) if (isdigit_ascii (*s))
bg = bg * 10 + (*s++ - '0'); *bg = *bg * 10 + (*s++ - '0');
return s;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct irc_char_attrs
{
uint8_t fg, bg; ///< {Fore,back}ground colour or 99
uint8_t attributes; ///< TEXT_* flags, except TEXT_BLINK
uint8_t starts_at_boundary; ///< Possible to split here?
};
static void
irc_serialize_char_attrs (const struct irc_char_attrs *attrs, struct str *out)
{
soft_assert (attrs->fg < 100 && attrs->bg < 100);
if (attrs->fg != 99 || attrs->bg != 99)
{
str_append_printf (out, "\x03%u", attrs->fg);
if (attrs->bg != 99)
str_append_printf (out, ",%02u", attrs->bg);
}
if (attrs->attributes & TEXT_BOLD) str_append_c (out, '\x02');
if (attrs->attributes & TEXT_ITALIC) str_append_c (out, '\x1d');
if (attrs->attributes & TEXT_UNDERLINE) str_append_c (out, '\x1f');
if (attrs->attributes & TEXT_INVERSE) str_append_c (out, '\x16');
if (attrs->attributes & TEXT_CROSSED_OUT) str_append_c (out, '\x1e');
if (attrs->attributes & TEXT_MONOSPACE) str_append_c (out, '\x11');
}
static int
irc_parse_attribute (char c)
{
switch (c)
{
case '\x02' /* ^B */: return TEXT_BOLD;
case '\x11' /* ^Q */: return TEXT_MONOSPACE;
case '\x16' /* ^V */: return TEXT_INVERSE;
case '\x1d' /* ^] */: return TEXT_ITALIC;
case '\x1e' /* ^^ */: return TEXT_CROSSED_OUT;
case '\x1f' /* ^_ */: return TEXT_UNDERLINE;
case '\x0f' /* ^O */: return -1;
}
return 0;
}
// The text needs to be NUL-terminated, and a valid UTF-8 string
static struct irc_char_attrs *
irc_analyze_text (const char *text, size_t len)
{
struct irc_char_attrs *attrs = xcalloc (len, sizeof *attrs),
blank = { .fg = 99, .bg = 99, .starts_at_boundary = true },
next = blank, cur = next;
for (size_t i = 0; i != len; cur = next)
{
const char *start = text;
hard_assert (utf8_decode (&text, len - i) >= 0);
int attribute = irc_parse_attribute (*start);
if (*start == '\x03')
text = irc_parse_mirc_color (text, &next.fg, &next.bg);
else if (attribute > 0)
next.attributes ^= attribute;
else if (attribute < 0)
next = blank;
while (start++ != text)
{
attrs[i++] = cur;
cur.starts_at_boundary = false;
}
}
return attrs;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static const char *
formatter_parse_mirc_color (struct formatter *self, const char *s)
{
uint8_t fg = 255, bg = 255;
s = irc_parse_mirc_color (s, &fg, &bg);
if (fg < 16)
FORMATTER_ADD_ITEM (self, FG_COLOR, .color = g_mirc_to_terminal[fg]);
else if (fg < 100)
FORMATTER_ADD_ITEM (self, FG_COLOR,
.color = COLOR_256 (DEFAULT, g_extra_to_256[fg - 16]));
if (bg < 16) if (bg < 16)
FORMATTER_ADD_ITEM (self, BG_COLOR, .color = g_mirc_to_terminal[bg]); FORMATTER_ADD_ITEM (self, BG_COLOR, .color = g_mirc_to_terminal[bg]);
else else if (bg < 100)
FORMATTER_ADD_ITEM (self, BG_COLOR, FORMATTER_ADD_ITEM (self, BG_COLOR,
.color = COLOR_256 (DEFAULT, g_extra_to_256[bg])); .color = COLOR_256 (DEFAULT, g_extra_to_256[bg - 16]));
return s; return s;
} }
static void static void
formatter_parse_mirc (struct formatter *self, const char *s) formatter_parse_message (struct formatter *self, const char *s)
{ {
FORMATTER_ADD_RESET (self); FORMATTER_ADD_RESET (self);
@@ -3251,24 +3336,15 @@ formatter_parse_mirc (struct formatter *self, const char *s)
str_reset (&buf); str_reset (&buf);
} }
switch (c) int attribute = irc_parse_attribute (c);
{ if (c == '\x03')
case '\x02': FORMATTER_ADD_SIMPLE (self, BOLD); break;
case '\x11': /* monospace, N/A */ break;
case '\x1d': FORMATTER_ADD_SIMPLE (self, ITALIC); break;
case '\x1e': FORMATTER_ADD_SIMPLE (self, CROSSED_OUT); break;
case '\x1f': FORMATTER_ADD_SIMPLE (self, UNDERLINE); break;
case '\x16': FORMATTER_ADD_SIMPLE (self, INVERSE); break;
case '\x03':
s = formatter_parse_mirc_color (self, s); s = formatter_parse_mirc_color (self, s);
break; else if (attribute > 0)
case '\x0f': FORMATTER_ADD_ITEM (self, SIMPLE, .attribute = attribute);
else if (attribute < 0)
FORMATTER_ADD_RESET (self); FORMATTER_ADD_RESET (self);
break; else
default:
str_append_c (&buf, c); str_append_c (&buf, c);
}
} }
if (buf.len) if (buf.len)
@@ -3378,7 +3454,7 @@ restart:
break; break;
case 'm': case 'm':
tmp = irc_to_utf8 ((s = va_arg (*ap, char *))); tmp = irc_to_utf8 ((s = va_arg (*ap, char *)));
formatter_parse_mirc (self, tmp); formatter_parse_message (self, tmp);
free (tmp); free (tmp);
break; break;
case 'n': case 'n':
@@ -4086,6 +4162,9 @@ log_full (struct app_context *ctx, struct server *s, struct buffer *buffer,
log_server_status ((s), (s)->buffer, "Notice -> #n: #m", (target), (text)) log_server_status ((s), (s)->buffer, "Notice -> #n: #m", (target), (text))
#define log_outcoming_orphan_privmsg(s, target, text) \ #define log_outcoming_orphan_privmsg(s, target, text) \
log_server_status ((s), (s)->buffer, "MSG(#n): #m", (target), (text)) log_server_status ((s), (s)->buffer, "MSG(#n): #m", (target), (text))
#define log_outcoming_orphan_action(s, target, text) \
log_server_status ((s), (s)->buffer, "MSG(#n): #a*#r #m", (target), \
ATTR_ACTION, (text))
#define log_ctcp_query(s, target, tag) \ #define log_ctcp_query(s, target, tag) \
log_server_status ((s), (s)->buffer, "CTCP query to #S: #S", target, tag) log_server_status ((s), (s)->buffer, "CTCP query to #S: #S", target, tag)
@@ -6210,7 +6289,7 @@ irc_is_highlight (struct server *s, const char *message)
// Strip formatting from the message so that it doesn't interfere // Strip formatting from the message so that it doesn't interfere
// with nickname detection (colour sequences in particular) // with nickname detection (colour sequences in particular)
struct formatter f = formatter_make (s->ctx, NULL); struct formatter f = formatter_make (s->ctx, NULL);
formatter_parse_mirc (&f, message); formatter_parse_message (&f, message);
struct str stripped = str_make (); struct str stripped = str_make ();
for (size_t i = 0; i < f.items_len; i++) for (size_t i = 0; i < f.items_len; i++)
@@ -6511,8 +6590,9 @@ irc_handle_sent_privmsg_text (struct server *s,
prefixes, s->irc_user->nickname, text->str); prefixes, s->irc_user->nickname, text->str);
free (prefixes); free (prefixes);
} }
else if (is_action)
log_outcoming_orphan_action (s, target, text->str);
else else
// TODO: also handle actions here
log_outcoming_orphan_privmsg (s, target, text->str); log_outcoming_orphan_privmsg (s, target, text->str);
} }
@@ -8227,12 +8307,12 @@ irc_process_message (const struct irc_message *msg, struct server *s)
// --- Message autosplitting magic --------------------------------------------- // --- Message autosplitting magic ---------------------------------------------
// This is the most basic acceptable algorithm; something like ICU with proper // This is a rather basic algorithm; something like ICU with proper
// locale specification would be needed to make it work better. // locale specification would be needed to make it work better.
static size_t static size_t
wrap_text_for_single_line (const char *text, size_t text_len, wrap_text_for_single_line (const char *text, struct irc_char_attrs *attrs,
size_t line_len, struct str *output) size_t text_len, size_t target_len, struct str *output)
{ {
size_t eaten = 0; size_t eaten = 0;
@@ -8240,7 +8320,7 @@ wrap_text_for_single_line (const char *text, size_t text_len,
const char *word_start; const char *word_start;
const char *word_end = text + strcspn (text, " "); const char *word_end = text + strcspn (text, " ");
size_t word_len = word_end - text; size_t word_len = word_end - text;
while (line_len && word_len <= line_len) while (target_len && word_len <= target_len)
{ {
if (word_len) if (word_len)
{ {
@@ -8248,7 +8328,7 @@ wrap_text_for_single_line (const char *text, size_t text_len,
text += word_len; text += word_len;
eaten += word_len; eaten += word_len;
line_len -= word_len; target_len -= word_len;
} }
// Find the next word's end // Find the next word's end
@@ -8262,53 +8342,60 @@ wrap_text_for_single_line (const char *text, size_t text_len,
return eaten + (word_start - text); return eaten + (word_start - text);
// And if that doesn't help, cut the longest valid block of characters // And if that doesn't help, cut the longest valid block of characters
for (const char *p = text; (size_t) (p - text) <= line_len; ) for (size_t i = 1; i <= text_len && i <= target_len; i++)
{ if (i == text_len || attrs[i].starts_at_boundary)
eaten = p - text; eaten = i;
hard_assert (utf8_decode (&p, text_len - eaten) >= 0);
}
str_append_data (output, text, eaten); str_append_data (output, text, eaten);
return eaten; return eaten;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // In practice, this should never fail at all, although it's not guaranteed
static bool static bool
wrap_message (const char *message, wrap_message (const char *message,
int line_max, struct strv *output, struct error **e) int line_max, struct strv *output, struct error **e)
{ {
size_t message_left = strlen (message), i = 0;
struct irc_char_attrs *attrs = irc_analyze_text (message, message_left);
struct str m = str_make ();
if (line_max <= 0) if (line_max <= 0)
goto error; goto error;
int message_left = strlen (message); while (m.len + message_left > (size_t) line_max)
while (message_left > line_max)
{ {
struct str m = str_make ();
size_t eaten = wrap_text_for_single_line size_t eaten = wrap_text_for_single_line
(message, message_left, line_max, &m); (message + i, attrs + i, message_left, line_max - m.len, &m);
if (!eaten) if (!eaten)
{
str_free (&m);
goto error; goto error;
}
strv_append_owned (output, str_steal (&m)); strv_append_owned (output, str_steal (&m));
message += eaten; m = str_make ();
message_left -= eaten;
i += eaten;
if (!(message_left -= eaten))
break;
irc_serialize_char_attrs (attrs + i, &m);
if (m.len >= (size_t) line_max)
{
print_debug ("formatting continuation too long");
str_reset (&m);
}
} }
if (message_left) if (message_left)
strv_append (output, message); strv_append_owned (output,
xstrdup_printf ("%s%s", m.str, message + i));
free (attrs);
str_free (&m);
return true; return true;
error: error:
// Well, that's just weird free (attrs);
error_set (e, str_free (&m);
return error_set (e,
"Message splitting was unsuccessful as there was " "Message splitting was unsuccessful as there was "
"too little room for UTF-8 characters"); "too little room for UTF-8 characters");
return false;
} }
/// Automatically splits messages that arrive at other clients with our prefix /// Automatically splits messages that arrive at other clients with our prefix
@@ -13417,7 +13504,7 @@ on_insert_attribute (int count, int key, void *user_data)
(void) key; (void) key;
struct app_context *ctx = user_data; struct app_context *ctx = user_data;
ctx->awaiting_mirc_escape = true; ctx->awaiting_formatting_escape = true;
return true; return true;
} }
@@ -13451,7 +13538,7 @@ input_add_functions (void *user_data)
XX ("toggle-unimportant", "Toggle junk msgs", on_toggle_unimportant) XX ("toggle-unimportant", "Toggle junk msgs", on_toggle_unimportant)
XX ("edit-input", "Edit input", on_edit_input) XX ("edit-input", "Edit input", on_edit_input)
XX ("redraw-screen", "Redraw screen", on_redraw_screen) XX ("redraw-screen", "Redraw screen", on_redraw_screen)
XX ("insert-attribute", "mIRC formatting", on_insert_attribute) XX ("insert-attribute", "IRC formatting", on_insert_attribute)
XX ("start-paste-mode", "Bracketed paste", on_start_paste_mode) XX ("start-paste-mode", "Bracketed paste", on_start_paste_mode)
#undef XX #undef XX
} }
@@ -13722,9 +13809,9 @@ static const char *g_first_time_help[] =
"F5/Ctrl-P\x02 or \x02" "F6/Ctrl-N\x02.", "F5/Ctrl-P\x02 or \x02" "F6/Ctrl-N\x02.",
"", "",
"Finally, adding a network is as simple as:", "Finally, adding a network is as simple as:",
" - \x02/server add freenode\x02", " - \x02/server add IRCnet\x02",
" - \x02/set servers.freenode.addresses = \"chat.freenode.net\"\x02", " - \x02/set servers.IRCnet.addresses = \"open.ircnet.net\"\x02",
" - \x02/connect freenode\x02", " - \x02/connect IRCnet\x02",
"", "",
"That should be enough to get you started. Have fun!", "That should be enough to get you started. Have fun!",
"" ""
@@ -13981,7 +14068,7 @@ on_signal_pipe_readable (const struct pollfd *fd, struct app_context *ctx)
} }
static void static void
process_mirc_escape (const struct pollfd *fd, struct app_context *ctx) process_formatting_escape (const struct pollfd *fd, struct app_context *ctx)
{ {
// There's no other way with libedit, as both el_getc() in a function // There's no other way with libedit, as both el_getc() in a function
// handler and CC_ARGHACK would block execution // handler and CC_ARGHACK would block execution
@@ -14033,7 +14120,7 @@ error:
CALL (ctx->input, ding); CALL (ctx->input, ding);
done: done:
str_reset (buf); str_reset (buf);
ctx->awaiting_mirc_escape = false; ctx->awaiting_formatting_escape = false;
} }
#define BRACKETED_PASTE_LIMIT 102400 ///< How much text can be pasted #define BRACKETED_PASTE_LIMIT 102400 ///< How much text can be pasted
@@ -14129,8 +14216,8 @@ on_tty_readable (const struct pollfd *fd, struct app_context *ctx)
if (fd->revents & ~(POLLIN | POLLHUP | POLLERR)) if (fd->revents & ~(POLLIN | POLLHUP | POLLERR))
print_debug ("fd %d: unexpected revents: %d", fd->fd, fd->revents); print_debug ("fd %d: unexpected revents: %d", fd->fd, fd->revents);
if (ctx->awaiting_mirc_escape) if (ctx->awaiting_formatting_escape)
process_mirc_escape (fd, ctx); process_formatting_escape (fd, ctx);
else if (ctx->in_bracketed_paste) else if (ctx->in_bracketed_paste)
process_bracketed_paste (fd, ctx); process_bracketed_paste (fd, ctx);
else if (!ctx->quitting) else if (!ctx->quitting)
@@ -14303,9 +14390,11 @@ test_aliases (void)
static void static void
test_wrapping (void) test_wrapping (void)
{ {
static const char *message = " foo bar foobar fóóbárbáz"; static const char *message = " foo bar foobar fóóbárbáz\002 a\0031 b";
static const char *split[] = // XXX: formatting continuation order is implementation-dependent here
{ " foo", "bar", "foob", "ar", "", "ób", "árb", "áz" }; // (irc_serialize_char_attrs() makes a choice in serialization)
static const char *split[] = { " foo", "bar", "foob", "ar",
"", "ób", "árb", "áz\x02", "\002a\0031", "\0031\002b" };
struct strv v = strv_make (); struct strv v = strv_make ();
hard_assert (wrap_message (message, 4, &v, NULL)); hard_assert (wrap_message (message, 4, &v, NULL));

20
xD.c
View File

@@ -1,7 +1,7 @@
/* /*
* xD.c: an IRC daemon * xD.c: an IRC daemon
* *
* Copyright (c) 2014 - 2020, Přemysl Eric Janouch <p@janouch.name> * Copyright (c) 2014 - 2021, Přemysl Eric Janouch <p@janouch.name>
* *
* Permission to use, copy, modify, and/or distribute this software for any * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted. * purpose with or without fee is hereby granted.
@@ -22,7 +22,9 @@
#define WANT_SYSLOG_LOGGING #define WANT_SYSLOG_LOGGING
#include "common.c" #include "common.c"
#include "xD-replies.c" #include "xD-replies.c"
#include <nl_types.h> #include <nl_types.h>
#include <sys/resource.h>
enum { PIPE_READ, PIPE_WRITE }; enum { PIPE_READ, PIPE_WRITE };
@@ -3984,6 +3986,21 @@ daemonize (struct server_context *ctx)
poller_post_fork (&ctx->poller); poller_post_fork (&ctx->poller);
} }
static void
setup_limits (void)
{
struct rlimit limit;
if (getrlimit (RLIMIT_NOFILE, &limit))
{
print_warning ("%s: %s", "getrlimit", strerror (errno));
return;
}
limit.rlim_cur = limit.rlim_max;
if (setrlimit (RLIMIT_NOFILE, &limit))
print_warning ("%s: %s", "setrlimit", strerror (errno));
}
int int
main (int argc, char *argv[]) main (int argc, char *argv[])
{ {
@@ -4030,6 +4047,7 @@ main (int argc, char *argv[])
print_status (PROGRAM_NAME " " PROGRAM_VERSION " starting"); print_status (PROGRAM_NAME " " PROGRAM_VERSION " starting");
setup_signal_handlers (); setup_signal_handlers ();
setup_limits ();
init_openssl (); init_openssl ();
struct server_context ctx; struct server_context ctx;