10 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
5 changed files with 201 additions and 82 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required (VERSION 3.0) cmake_minimum_required (VERSION 3.0)
project (uirc3 VERSION 1.3.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)

12
NEWS
View File

@@ -1,3 +1,15 @@
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" 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

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;