|
|
@@ -526,7 +526,7 @@ input_set_prompt (struct input *self, char *prompt) |
|
|
|
free (self->prompt); |
|
|
|
self->prompt = prompt; |
|
|
|
|
|
|
|
if (self->prompt_shown) |
|
|
|
if (self->prompt_shown > 0) |
|
|
|
input_redisplay (self); |
|
|
|
} |
|
|
|
|
|
|
@@ -568,7 +568,7 @@ input_insert_c (struct input *self, int c) |
|
|
|
char s[2] = { c, 0 }; |
|
|
|
el_insertstr (self->editline, s); |
|
|
|
|
|
|
|
if (self->prompt_shown) |
|
|
|
if (self->prompt_shown > 0) |
|
|
|
input_redisplay (self); |
|
|
|
} |
|
|
|
|
|
|
@@ -1409,12 +1409,7 @@ app_context_free (struct app_context *self) |
|
|
|
input_free (&self->input); |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: see if we can reorder the code to get rid of these |
|
|
|
static void refresh_prompt (struct app_context *ctx); |
|
|
|
static char *irc_cut_nickname (const char *prefix); |
|
|
|
static const char *irc_find_userhost (const char *prefix); |
|
|
|
static char *irc_to_utf8 (struct app_context *ctx, const char *text); |
|
|
|
static bool irc_is_this_us (struct server *s, const char *prefix); |
|
|
|
|
|
|
|
// --- Configuration ----------------------------------------------------------- |
|
|
|
|
|
|
@@ -2119,6 +2114,90 @@ attribute_printer_update (struct attribute_printer *self) |
|
|
|
self->dirty = true; |
|
|
|
} |
|
|
|
|
|
|
|
// --- Helpers ----------------------------------------------------------------- |
|
|
|
|
|
|
|
static int |
|
|
|
irc_server_strcmp (struct server *s, const char *a, const char *b) |
|
|
|
{ |
|
|
|
int x; |
|
|
|
while (*a || *b) |
|
|
|
if ((x = s->irc_tolower (*a++) - s->irc_tolower (*b++))) |
|
|
|
return x; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
irc_server_strncmp (struct server *s, const char *a, const char *b, size_t n) |
|
|
|
{ |
|
|
|
int x; |
|
|
|
while (n-- && (*a || *b)) |
|
|
|
if ((x = s->irc_tolower (*a++) - s->irc_tolower (*b++))) |
|
|
|
return x; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static char * |
|
|
|
irc_cut_nickname (const char *prefix) |
|
|
|
{ |
|
|
|
return xstrndup (prefix, strcspn (prefix, "!@")); |
|
|
|
} |
|
|
|
|
|
|
|
static const char * |
|
|
|
irc_find_userhost (const char *prefix) |
|
|
|
{ |
|
|
|
const char *p = strchr (prefix, '!'); |
|
|
|
return p ? p + 1 : NULL; |
|
|
|
} |
|
|
|
|
|
|
|
static bool |
|
|
|
irc_is_this_us (struct server *s, const char *prefix) |
|
|
|
{ |
|
|
|
// This shouldn't be called before successfully registering. |
|
|
|
// Better safe than sorry, though. |
|
|
|
if (!s->irc_user) |
|
|
|
return false; |
|
|
|
|
|
|
|
char *nick = irc_cut_nickname (prefix); |
|
|
|
bool result = !irc_server_strcmp (s, nick, s->irc_user->nickname); |
|
|
|
free (nick); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
static bool |
|
|
|
irc_is_channel (struct server *s, const char *ident) |
|
|
|
{ |
|
|
|
return *ident |
|
|
|
&& (!!strchr (s->irc_chantypes, *ident) || |
|
|
|
!!strchr (s->irc_idchan_prefixes, *ident)); |
|
|
|
} |
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
|
|
|
|
|
|
// As of 2015, everything should be in UTF-8. And if it's not, we'll decode it |
|
|
|
// as ISO Latin 1. This function should not be called on the whole message. |
|
|
|
static char * |
|
|
|
irc_to_utf8 (struct app_context *ctx, const char *text) |
|
|
|
{ |
|
|
|
if (!text) |
|
|
|
return NULL; |
|
|
|
size_t len = strlen (text) + 1; |
|
|
|
if (utf8_validate (text, len)) |
|
|
|
return xstrdup (text); |
|
|
|
return iconv_xstrdup (ctx->latin1_to_utf8, (char *) text, len, NULL); |
|
|
|
} |
|
|
|
|
|
|
|
// This function is used to output debugging IRC traffic to the terminal. |
|
|
|
// It's far from ideal, as any non-UTF-8 text degrades the entire line to |
|
|
|
// ISO Latin 1. But it should work good enough most of the time. |
|
|
|
static char * |
|
|
|
irc_to_term (struct app_context *ctx, const char *text) |
|
|
|
{ |
|
|
|
char *utf8 = irc_to_utf8 (ctx, text); |
|
|
|
char *term = iconv_xstrdup (ctx->term_from_utf8, utf8, -1, NULL); |
|
|
|
free (utf8); |
|
|
|
return term; |
|
|
|
} |
|
|
|
|
|
|
|
// --- Output formatter -------------------------------------------------------- |
|
|
|
|
|
|
|
// This complicated piece of code makes attributed text formatting simple. |
|
|
@@ -2778,6 +2857,8 @@ static void |
|
|
|
buffer_remove (struct app_context *ctx, struct buffer *buffer) |
|
|
|
{ |
|
|
|
hard_assert (buffer != ctx->current_buffer); |
|
|
|
hard_assert (buffer != ctx->global_buffer); |
|
|
|
hard_assert (buffer->type != BUFFER_SERVER); |
|
|
|
|
|
|
|
input_destroy_buffer (&ctx->input, buffer->input_data); |
|
|
|
buffer->input_data = NULL; |
|
|
@@ -2789,13 +2870,6 @@ buffer_remove (struct app_context *ctx, struct buffer *buffer) |
|
|
|
if (buffer->user) |
|
|
|
str_map_set (&s->irc_buffer_map, buffer->user->nickname, NULL); |
|
|
|
|
|
|
|
// It's not a good idea to remove these buffers, but it's even a worse |
|
|
|
// one to leave the pointers point to invalid memory |
|
|
|
if (buffer == ctx->global_buffer) |
|
|
|
ctx->global_buffer = NULL; |
|
|
|
if (buffer->type == BUFFER_SERVER) |
|
|
|
buffer->server->buffer = NULL; |
|
|
|
|
|
|
|
if (buffer == ctx->last_buffer) |
|
|
|
ctx->last_buffer = NULL; |
|
|
|
|
|
|
@@ -2851,7 +2925,6 @@ buffer_merge (struct app_context *ctx, |
|
|
|
{ |
|
|
|
// XXX: anything better to do? This situation is arguably rare and I'm |
|
|
|
// not entirely sure what action to take. |
|
|
|
// XXX: what good is log_*_status() when we can't use it? |
|
|
|
log_full (ctx, NULL, buffer, BUFFER_LINE_STATUS, |
|
|
|
"Buffer #s was merged into this buffer", merged->name); |
|
|
|
|
|
|
@@ -3118,7 +3191,6 @@ irc_remove_user_from_channel (struct user *user, struct channel *channel) |
|
|
|
static void |
|
|
|
irc_left_channel (struct channel *channel) |
|
|
|
{ |
|
|
|
// TODO: shouldn't we decrease reference count on the channel? |
|
|
|
LIST_FOR_EACH (struct channel_user, iter, channel->users) |
|
|
|
irc_channel_unlink_user (channel, iter); |
|
|
|
} |
|
|
@@ -3295,33 +3367,6 @@ irc_queue_reconnect (struct server *s) |
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
|
|
|
|
|
|
// As of 2015, everything should be in UTF-8. And if it's not, we'll decode it |
|
|
|
// as ISO Latin 1. This function should not be called on the whole message. |
|
|
|
static char * |
|
|
|
irc_to_utf8 (struct app_context *ctx, const char *text) |
|
|
|
{ |
|
|
|
if (!text) |
|
|
|
return NULL; |
|
|
|
size_t len = strlen (text) + 1; |
|
|
|
if (utf8_validate (text, len)) |
|
|
|
return xstrdup (text); |
|
|
|
return iconv_xstrdup (ctx->latin1_to_utf8, (char *) text, len, NULL); |
|
|
|
} |
|
|
|
|
|
|
|
// This function is used to output debugging IRC traffic to the terminal. |
|
|
|
// It's far from ideal, as any non-UTF-8 text degrades the entire line to |
|
|
|
// ISO Latin 1. But it should work good enough most of the time. |
|
|
|
static char * |
|
|
|
irc_to_term (struct app_context *ctx, const char *text) |
|
|
|
{ |
|
|
|
char *utf8 = irc_to_utf8 (ctx, text); |
|
|
|
char *term = iconv_xstrdup (ctx->term_from_utf8, utf8, -1, NULL); |
|
|
|
free (utf8); |
|
|
|
return term; |
|
|
|
} |
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
|
|
|
|
|
|
static void irc_send (struct server *s, |
|
|
|
const char *format, ...) ATTRIBUTE_PRINTF (2, 3); |
|
|
|
|
|
|
@@ -3750,7 +3795,7 @@ transport_tls_init_ctx (struct server *s, SSL_CTX *ssl_ctx, struct error **e) |
|
|
|
goto ca_error; |
|
|
|
} |
|
|
|
|
|
|
|
// XXX: maybe we should call SSL_CTX_set_options() for some workarounds |
|
|
|
// TODO: allow specifying SSL_CTX_set_cipher_list() |
|
|
|
SSL_CTX_set_mode (ssl_ctx, |
|
|
|
SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
|
|
|
return true; |
|
|
@@ -4209,12 +4254,9 @@ irc_initiate_connect (struct server *s) |
|
|
|
|
|
|
|
// --- Input prompt ------------------------------------------------------------ |
|
|
|
|
|
|
|
static char * |
|
|
|
make_unseen_prefix (struct app_context *ctx) |
|
|
|
static void |
|
|
|
make_unseen_prefix (struct app_context *ctx, struct str *active_buffers) |
|
|
|
{ |
|
|
|
struct str active_buffers; |
|
|
|
str_init (&active_buffers); |
|
|
|
|
|
|
|
size_t i = 0; |
|
|
|
LIST_FOR_EACH (struct buffer, iter, ctx->buffers) |
|
|
|
{ |
|
|
@@ -4222,41 +4264,51 @@ make_unseen_prefix (struct app_context *ctx) |
|
|
|
if (!iter->unseen_messages_count) |
|
|
|
continue; |
|
|
|
|
|
|
|
if (active_buffers.len) |
|
|
|
str_append_c (&active_buffers, ','); |
|
|
|
if (active_buffers->len) |
|
|
|
str_append_c (active_buffers, ','); |
|
|
|
if (iter->highlighted) |
|
|
|
str_append_c (&active_buffers, '!'); |
|
|
|
str_append_printf (&active_buffers, "%zu", i); |
|
|
|
str_append_c (active_buffers, '!'); |
|
|
|
str_append_printf (active_buffers, "%zu", i); |
|
|
|
} |
|
|
|
|
|
|
|
if (active_buffers.len) |
|
|
|
return str_steal (&active_buffers); |
|
|
|
|
|
|
|
str_free (&active_buffers); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
static char * |
|
|
|
make_chanmode_postfix (struct channel *channel) |
|
|
|
static void |
|
|
|
make_chanmode_postfix (struct channel *channel, struct str *modes) |
|
|
|
{ |
|
|
|
struct str modes; |
|
|
|
str_init (&modes); |
|
|
|
if (channel->no_param_modes.len) |
|
|
|
str_append (&modes, channel->no_param_modes.str); |
|
|
|
str_append (modes, channel->no_param_modes.str); |
|
|
|
|
|
|
|
struct str_map_iter iter; |
|
|
|
str_map_iter_init (&iter, &channel->param_modes); |
|
|
|
|
|
|
|
char *param; |
|
|
|
while ((param = str_map_iter_next (&iter))) |
|
|
|
str_append_c (&modes, iter.link->key[0]); |
|
|
|
|
|
|
|
if (modes.len) |
|
|
|
return str_steal (&modes); |
|
|
|
|
|
|
|
str_free (&modes); |
|
|
|
return NULL; |
|
|
|
str_append_c (modes, iter.link->key[0]); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
make_server_postfix (struct buffer *buffer, struct str *output) |
|
|
|
{ |
|
|
|
struct server *s = buffer->server; |
|
|
|
str_append_c (output, ' '); |
|
|
|
if (!irc_is_connected (s)) |
|
|
|
str_append (output, "(disconnected)"); |
|
|
|
else if (s->state != IRC_REGISTERED) |
|
|
|
str_append (output, "(unregistered)"); |
|
|
|
else |
|
|
|
{ |
|
|
|
if (buffer->type == BUFFER_CHANNEL) |
|
|
|
{ |
|
|
|
struct channel_user *channel_user = |
|
|
|
irc_channel_get_user (buffer->channel, s->irc_user); |
|
|
|
if (channel_user) |
|
|
|
str_append (output, channel_user->prefixes.str); |
|
|
|
} |
|
|
|
str_append (output, s->irc_user->nickname); |
|
|
|
if (s->irc_user_mode.len) |
|
|
|
str_append_printf (output, "(%s)", s->irc_user_mode.str); |
|
|
|
} |
|
|
|
} |
|
|
|
static void |
|
|
|
make_prompt (struct app_context *ctx, struct str *output) |
|
|
|
{ |
|
|
@@ -4266,43 +4318,27 @@ make_prompt (struct app_context *ctx, struct str *output) |
|
|
|
|
|
|
|
str_append_c (output, '['); |
|
|
|
|
|
|
|
char *unseen_prefix = make_unseen_prefix (ctx); |
|
|
|
if (unseen_prefix) |
|
|
|
str_append_printf (output, "(%s) ", unseen_prefix); |
|
|
|
free (unseen_prefix); |
|
|
|
struct str active_buffers; |
|
|
|
str_init (&active_buffers); |
|
|
|
make_unseen_prefix (ctx, &active_buffers); |
|
|
|
if (active_buffers.len) |
|
|
|
str_append_printf (output, "(%s) ", active_buffers.str); |
|
|
|
str_free (&active_buffers); |
|
|
|
|
|
|
|
str_append_printf (output, "%d:%s", |
|
|
|
buffer_get_index (ctx, buffer), buffer->name); |
|
|
|
if (buffer->type == BUFFER_CHANNEL) |
|
|
|
{ |
|
|
|
char *modes = make_chanmode_postfix (buffer->channel); |
|
|
|
if (modes) |
|
|
|
str_append_printf (output, "(+%s)", modes); |
|
|
|
free (modes); |
|
|
|
struct str modes; |
|
|
|
str_init (&modes); |
|
|
|
make_chanmode_postfix (buffer->channel, &modes); |
|
|
|
if (modes.len) |
|
|
|
str_append_printf (output, "(+%s)", modes.str); |
|
|
|
str_free (&modes); |
|
|
|
} |
|
|
|
|
|
|
|
if (buffer != ctx->global_buffer) |
|
|
|
{ |
|
|
|
struct server *s = buffer->server; |
|
|
|
str_append_c (output, ' '); |
|
|
|
if (!irc_is_connected (s)) |
|
|
|
str_append (output, "(disconnected)"); |
|
|
|
else if (s->state != IRC_REGISTERED) |
|
|
|
str_append (output, "(unregistered)"); |
|
|
|
else |
|
|
|
{ |
|
|
|
if (buffer->type == BUFFER_CHANNEL) |
|
|
|
{ |
|
|
|
struct channel_user *channel_user = |
|
|
|
irc_channel_get_user (buffer->channel, s->irc_user); |
|
|
|
if (channel_user) |
|
|
|
str_append (output, channel_user->prefixes.str); |
|
|
|
} |
|
|
|
str_append (output, s->irc_user->nickname); |
|
|
|
if (s->irc_user_mode.len) |
|
|
|
str_append_printf (output, "(%s)", s->irc_user_mode.str); |
|
|
|
} |
|
|
|
} |
|
|
|
make_server_postfix (buffer, output); |
|
|
|
|
|
|
|
str_append_c (output, ']'); |
|
|
|
} |
|
|
@@ -4334,63 +4370,6 @@ refresh_prompt (struct app_context *ctx) |
|
|
|
|
|
|
|
// --- Helpers ----------------------------------------------------------------- |
|
|
|
|
|
|
|
static int |
|
|
|
irc_server_strcmp (struct server *s, const char *a, const char *b) |
|
|
|
{ |
|
|
|
int x; |
|
|
|
while (*a || *b) |
|
|
|
if ((x = s->irc_tolower (*a++) - s->irc_tolower (*b++))) |
|
|
|
return x; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
irc_server_strncmp (struct server *s, const char *a, const char *b, size_t n) |
|
|
|
{ |
|
|
|
int x; |
|
|
|
while (n-- && (*a || *b)) |
|
|
|
if ((x = s->irc_tolower (*a++) - s->irc_tolower (*b++))) |
|
|
|
return x; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static char * |
|
|
|
irc_cut_nickname (const char *prefix) |
|
|
|
{ |
|
|
|
return xstrndup (prefix, strcspn (prefix, "!@")); |
|
|
|
} |
|
|
|
|
|
|
|
static const char * |
|
|
|
irc_find_userhost (const char *prefix) |
|
|
|
{ |
|
|
|
const char *p = strchr (prefix, '!'); |
|
|
|
return p ? p + 1 : NULL; |
|
|
|
} |
|
|
|
|
|
|
|
static bool |
|
|
|
irc_is_this_us (struct server *s, const char *prefix) |
|
|
|
{ |
|
|
|
// This shouldn't be called before successfully registering. |
|
|
|
// Better safe than sorry, though. |
|
|
|
if (!s->irc_user) |
|
|
|
return false; |
|
|
|
|
|
|
|
char *nick = irc_cut_nickname (prefix); |
|
|
|
bool result = !irc_server_strcmp (s, nick, s->irc_user->nickname); |
|
|
|
free (nick); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
static bool |
|
|
|
irc_is_channel (struct server *s, const char *ident) |
|
|
|
{ |
|
|
|
return *ident |
|
|
|
&& (!!strchr (s->irc_chantypes, *ident) || |
|
|
|
!!strchr (s->irc_idchan_prefixes, *ident)); |
|
|
|
} |
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
|
|
|
|
|
|
static struct buffer * |
|
|
|
irc_get_buffer_for_message (struct server *s, |
|
|
|
const struct irc_message *msg, const char *target) |
|
|
@@ -4435,11 +4414,11 @@ irc_is_highlight (struct server *s, const char *message) |
|
|
|
// Ideally we could do this at least in proper Unicode. |
|
|
|
char *copy = xstrdup (message); |
|
|
|
for (char *p = copy; *p; p++) |
|
|
|
*p = irc_tolower (*p); |
|
|
|
*p = s->irc_tolower (*p); |
|
|
|
|
|
|
|
char *nick = xstrdup (s->irc_user->nickname); |
|
|
|
for (char *p = nick; *p; p++) |
|
|
|
*p = irc_tolower (*p); |
|
|
|
*p = s->irc_tolower (*p); |
|
|
|
|
|
|
|
// Special characters allowed in nicknames by RFC 2812: []\`_^{|} and - |
|
|
|
// Also excluded from the ASCII: common user channel prefixes: +%@&~ |
|
|
@@ -4855,10 +4834,6 @@ irc_handle_mode (struct server *s, const struct irc_message *msg) |
|
|
|
log_server_status (s, s->buffer, |
|
|
|
"User mode [#S] by #n", modes, msg->prefix); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
// XXX: this shouldn't happen, reconnect? |
|
|
|
} |
|
|
|
|
|
|
|
free (modes); |
|
|
|
|
|
|
@@ -4928,7 +4903,7 @@ irc_handle_nick (struct server *s, const struct irc_message *msg) |
|
|
|
pm_buffer = buffer_collision; |
|
|
|
} |
|
|
|
|
|
|
|
// The colliding user should be completely destroyed by now |
|
|
|
// The colliding user should be completely gone by now |
|
|
|
if (lexicographically_different) |
|
|
|
hard_assert (!str_map_find (&s->irc_users, new_nickname)); |
|
|
|
|
|
|
@@ -5234,7 +5209,7 @@ irc_handle_quit (struct server *s, const struct irc_message *msg) |
|
|
|
if (!msg->prefix) |
|
|
|
return; |
|
|
|
|
|
|
|
// What the fuck |
|
|
|
// What the fuck, the server never sends this back |
|
|
|
if (irc_is_this_us (s, msg->prefix)) |
|
|
|
return; |
|
|
|
|
|
|
@@ -5450,7 +5425,7 @@ irc_handle_rpl_namreply (struct server *s, const struct irc_message *msg) |
|
|
|
const char *channel_name = msg->params.vector[2]; |
|
|
|
const char *nicks = msg->params.vector[3]; |
|
|
|
|
|
|
|
// Just push the nicknames to a string vector for later processing |
|
|
|
// Just push the nicknames to a string vector to process later |
|
|
|
struct channel *channel = str_map_find (&s->irc_channels, channel_name); |
|
|
|
if (channel) |
|
|
|
split_str_ignore_empty (nicks, ' ', &channel->names_buf); |
|
|
@@ -5518,7 +5493,6 @@ irc_process_names (struct server *s, struct channel *channel) |
|
|
|
char *all_users = join_str_vector (&v, ' '); |
|
|
|
str_vector_free (&v); |
|
|
|
|
|
|
|
// XXX: only do this after joining the channel? |
|
|
|
struct buffer *buffer = str_map_find (&s->irc_buffer_map, channel->name); |
|
|
|
if (buffer) |
|
|
|
{ |
|
|
@@ -5837,9 +5811,6 @@ irc_process_numeric (struct server *s, |
|
|
|
const struct irc_message *msg, unsigned long numeric) |
|
|
|
{ |
|
|
|
// Numerics typically have human-readable information |
|
|
|
// TODO: try to output certain replies in more specific buffers |
|
|
|
|
|
|
|
// TODO: fail the connection if there's no first parameter |
|
|
|
|
|
|
|
// Get rid of the first parameter, if there's any at all, |
|
|
|
// as it contains our nickname and is of no practical use to the user |
|
|
@@ -5896,10 +5867,10 @@ irc_process_numeric (struct server *s, |
|
|
|
|
|
|
|
default: |
|
|
|
// If the second parameter is something we have a buffer for |
|
|
|
// (a channel, a PM buffer), log it in that buffer. This is very basic |
|
|
|
// and we should whitelist/blacklist a lot more replies here. |
|
|
|
// TODO: if this happens, we should either strip the first parameter |
|
|
|
// from the buffer line, or at least put it in brackets |
|
|
|
// (a channel, a PM buffer), log it in that buffer. This is very basic. |
|
|
|
// TODO: whitelist/blacklist a lot more replies in here. |
|
|
|
// TODO: we should either strip the first parameter from the resulting |
|
|
|
// buffer line, or at least put it in brackets |
|
|
|
if (msg->params.len > 1) |
|
|
|
{ |
|
|
|
struct buffer *x; |
|
|
@@ -5910,8 +5881,7 @@ irc_process_numeric (struct server *s, |
|
|
|
|
|
|
|
if (buffer) |
|
|
|
{ |
|
|
|
// Join the parameter vector back, recode it to our internal encoding |
|
|
|
// and send it to the server buffer |
|
|
|
// Join the parameter vector back and send it to the server buffer |
|
|
|
log_server (s, buffer, BUFFER_LINE_STATUS, |
|
|
|
"#&m", join_str_vector (©, ' ')); |
|
|
|
} |
|
|
@@ -7675,11 +7645,6 @@ send_message_to_current_buffer (struct app_context *ctx, char *message) |
|
|
|
|
|
|
|
switch (buffer->type) |
|
|
|
{ |
|
|
|
case BUFFER_GLOBAL: |
|
|
|
case BUFFER_SERVER: |
|
|
|
log_full (ctx, NULL, buffer, BUFFER_LINE_ERROR, |
|
|
|
"This buffer is not a channel"); |
|
|
|
break; |
|
|
|
case BUFFER_CHANNEL: |
|
|
|
send_message_to_target (buffer->server, |
|
|
|
buffer->channel->name, message, buffer); |
|
|
@@ -7688,6 +7653,9 @@ send_message_to_current_buffer (struct app_context *ctx, char *message) |
|
|
|
send_message_to_target (buffer->server, |
|
|
|
buffer->user->nickname, message, buffer); |
|
|
|
break; |
|
|
|
default: |
|
|
|
log_full (ctx, NULL, buffer, BUFFER_LINE_ERROR, |
|
|
|
"This buffer is not a channel"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -8211,7 +8179,7 @@ on_readline_input (char *line) |
|
|
|
if (*line) |
|
|
|
add_history (line); |
|
|
|
|
|
|
|
// The text is deleted _afterwards_ |
|
|
|
// Normally, the text is deleted _afterwards_ |
|
|
|
rl_replace_line ("", false); |
|
|
|
process_input (ctx, line); |
|
|
|
free (line); |