diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/ignore.c | 38 | ||||
-rw-r--r-- | src/core/ignore.h | 10 | ||||
-rw-r--r-- | src/fe-common/core/command-history.c | 35 | ||||
-rw-r--r-- | src/fe-common/core/command-history.h | 1 | ||||
-rw-r--r-- | src/fe-common/core/fe-ignore.c | 8 | ||||
-rw-r--r-- | src/fe-common/core/fe-messages.c | 10 | ||||
-rw-r--r-- | src/fe-common/core/fe-windows.c | 7 | ||||
-rw-r--r-- | src/fe-common/core/fe-windows.h | 1 | ||||
-rw-r--r-- | src/fe-common/core/formats.h | 4 | ||||
-rw-r--r-- | src/fe-common/core/hilight-text.c | 10 | ||||
-rw-r--r-- | src/fe-common/core/hilight-text.h | 2 | ||||
-rw-r--r-- | src/fe-common/core/window-commands.c | 21 | ||||
-rw-r--r-- | src/fe-text/gui-readline.c | 166 | ||||
-rw-r--r-- | src/fe-text/term-terminfo.c | 8 | ||||
-rw-r--r-- | src/fe-text/term.h | 2 | ||||
-rw-r--r-- | src/irc/core/irc-commands.c | 202 | ||||
-rw-r--r-- | src/irc/flood/autoignore.c | 2 | ||||
-rw-r--r-- | src/irc/proxy/listen.c | 2 | ||||
-rw-r--r-- | src/perl/perl-common.c | 3 | ||||
-rw-r--r-- | src/perl/perl-core.c | 17 |
20 files changed, 382 insertions, 167 deletions
diff --git a/src/core/ignore.c b/src/core/ignore.c index fd3c8a38..8d5a27c2 100644 --- a/src/core/ignore.c +++ b/src/core/ignore.c @@ -186,15 +186,8 @@ int ignore_check(SERVER_REC *server, const char *nick, const char *host, return ignore_check_replies(chanrec, text, level); } -IGNORE_REC *ignore_find(const char *servertag, const char *mask, - char **channels) -{ - return ignore_find_noact(servertag, mask, channels, 0); -} - - -IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, - char **channels, int noact) +IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char *pattern, + char **channels, const int flags) { GSList *tmp; char **chan; @@ -216,18 +209,29 @@ IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, continue; } - if (noact && (rec->level & MSGLEVEL_NO_ACT) == 0) + if ((flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) == 0) continue; - if (!noact && (rec->level & MSGLEVEL_NO_ACT) != 0) + if (!(flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) != 0) continue; if ((rec->mask == NULL && mask != NULL) || - (rec->mask != NULL && mask == NULL)) continue; + (rec->mask != NULL && mask == NULL)) + continue; if (rec->mask != NULL && g_ascii_strcasecmp(rec->mask, mask) != 0) continue; + /* match the pattern too if requested */ + if (flags & IGNORE_FIND_PATTERN) { + if ((rec->pattern == NULL && pattern != NULL) || + (rec->pattern != NULL && pattern == NULL)) + continue; + + if (rec->pattern != NULL && g_ascii_strcasecmp(rec->pattern, pattern) != 0) + continue; + } + if ((channels == NULL && rec->channels == NULL)) return rec; /* no channels - ok */ @@ -253,6 +257,16 @@ IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, return NULL; } +IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels) +{ + return ignore_find_full(servertag, mask, NULL, channels, 0); +} + +IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact) +{ + return ignore_find_full(servertag, mask, NULL, channels, IGNORE_FIND_NOACT); +} + static void ignore_set_config(IGNORE_REC *rec) { CONFIG_NODE *node; diff --git a/src/core/ignore.h b/src/core/ignore.h index 46025d4c..f889740f 100644 --- a/src/core/ignore.h +++ b/src/core/ignore.h @@ -31,6 +31,16 @@ extern GSList *ignores; int ignore_check(SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level); +enum { + IGNORE_FIND_PATTERN = 0x01, // Match the pattern + IGNORE_FIND_NOACT = 0x02, // Exclude the targets with NOACT level +}; + +IGNORE_REC *ignore_find_full (const char *servertag, const char *mask, const char *pattern, + char **channels, const int flags); + +// Convenience wrappers around ignore_find_full, for compatibility purpose + IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels); IGNORE_REC *ignore_find_noact(const char *servertag, const char *mask, char **channels, int noact); diff --git a/src/fe-common/core/command-history.c b/src/fe-common/core/command-history.c index f9c3884c..1060744e 100644 --- a/src/fe-common/core/command-history.c +++ b/src/fe-common/core/command-history.c @@ -94,13 +94,13 @@ HISTORY_REC *command_history_current(WINDOW_REC *window) if (window == NULL) return global_history; - if (window_history) - return window->history; - rec = command_history_find_name(window->history_name); if (rec != NULL) return rec; + if (window_history) + return window->history; + return global_history; } @@ -178,6 +178,17 @@ HISTORY_REC *command_history_create(const char *name) return rec; } +void command_history_clear(HISTORY_REC *history) +{ + g_return_if_fail(history != NULL); + + command_history_clear_pos_func(history, NULL); + g_list_foreach(history->list, (GFunc) g_free, NULL); + g_list_free(history->list); + history->list = NULL; + history->lines = 0; +} + void command_history_destroy(HISTORY_REC *history) { g_return_if_fail(history != NULL); @@ -186,9 +197,7 @@ void command_history_destroy(HISTORY_REC *history) g_return_if_fail(history->refcount == 0); histories = g_slist_remove(histories, history); - - g_list_foreach(history->list, (GFunc) g_free, NULL); - g_list_free(history->list); + command_history_clear(history); g_free_not_null(history->name); g_free(history); @@ -229,6 +238,18 @@ static void sig_window_destroyed(WINDOW_REC *window) g_free_not_null(window->history_name); } +static void sig_window_history_cleared(WINDOW_REC *window, const char *name) { + HISTORY_REC *history; + + if (name == NULL || *name == '\0') { + history = command_history_current(window); + } else { + history = command_history_find_name(name); + } + + command_history_clear(history); +} + static void sig_window_history_changed(WINDOW_REC *window, const char *oldname) { command_history_link(window->history_name); @@ -279,6 +300,7 @@ void command_history_init(void) signal_add("window created", (SIGNAL_FUNC) sig_window_created); signal_add("window destroyed", (SIGNAL_FUNC) sig_window_destroyed); signal_add("window history changed", (SIGNAL_FUNC) sig_window_history_changed); + signal_add_last("window history cleared", (SIGNAL_FUNC) sig_window_history_cleared); signal_add("setup changed", (SIGNAL_FUNC) read_settings); } @@ -287,6 +309,7 @@ void command_history_deinit(void) signal_remove("window created", (SIGNAL_FUNC) sig_window_created); signal_remove("window destroyed", (SIGNAL_FUNC) sig_window_destroyed); signal_remove("window history changed", (SIGNAL_FUNC) sig_window_history_changed); + signal_remove("window history cleared", (SIGNAL_FUNC) sig_window_history_cleared); signal_remove("setup changed", (SIGNAL_FUNC) read_settings); command_history_destroy(global_history); diff --git a/src/fe-common/core/command-history.h b/src/fe-common/core/command-history.h index 7b76246b..a572216b 100644 --- a/src/fe-common/core/command-history.h +++ b/src/fe-common/core/command-history.h @@ -28,6 +28,7 @@ const char *command_history_next(WINDOW_REC *window, const char *text); void command_history_clear_pos(WINDOW_REC *window); HISTORY_REC *command_history_create(const char *name); +void command_history_clear(HISTORY_REC *history); void command_history_destroy(HISTORY_REC *history); void command_history_link(const char *name); void command_history_unlink(const char *name); diff --git a/src/fe-common/core/fe-ignore.c b/src/fe-common/core/fe-ignore.c index d2f9de27..a809ac91 100644 --- a/src/fe-common/core/fe-ignore.c +++ b/src/fe-common/core/fe-ignore.c @@ -158,8 +158,8 @@ static void cmd_ignore(const char *data) channels = (chanarg == NULL || *chanarg == '\0') ? NULL : g_strsplit(chanarg, ",", -1); - rec = patternarg != NULL ? NULL: ignore_find_noact(servertag, mask, channels, - (level & MSGLEVEL_NO_ACT)); + rec = ignore_find_full(servertag, mask, patternarg, channels, + IGNORE_FIND_PATTERN | ((level & MSGLEVEL_NO_ACT) ? IGNORE_FIND_NOACT : 0)); new_ignore = rec == NULL; if (rec == NULL) { @@ -237,9 +237,9 @@ static void cmd_unignore(const char *data) chans[0] = mask; mask = NULL; } - rec = ignore_find_noact("*", mask, (char **) chans, 0); + rec = ignore_find_full("*", mask, NULL, (char **) chans, 0); if (rec == NULL) { - rec = ignore_find_noact("*", mask, (char **) chans, 1); + rec = ignore_find_full("*", mask, NULL, (char **) chans, IGNORE_FIND_NOACT); } } diff --git a/src/fe-common/core/fe-messages.c b/src/fe-common/core/fe-messages.c index d09c1b0b..3240fd10 100644 --- a/src/fe-common/core/fe-messages.c +++ b/src/fe-common/core/fe-messages.c @@ -214,10 +214,12 @@ static void sig_message_public(SERVER_REC *server, const char *msg, if (printnick == NULL) printnick = nick; + TEXT_DEST_REC dest; + format_create_dest(&dest, server, target, level, NULL); + dest.address = address; + dest.nick = nick; if (color != NULL) { /* highlighted nick */ - TEXT_DEST_REC dest; - format_create_dest(&dest, server, target, level, NULL); hilight_update_text_dest(&dest,hilight); if (!print_channel) /* message to active channel in window */ printformat_dest(&dest, TXT_PUBMSG_HILIGHT, color, @@ -228,11 +230,11 @@ static void sig_message_public(SERVER_REC *server, const char *msg, nickmode); } else { if (!print_channel) - printformat(server, target, level, + printformat_dest(&dest, for_me ? TXT_PUBMSG_ME : TXT_PUBMSG, printnick, msg, nickmode); else - printformat(server, target, level, + printformat_dest(&dest, for_me ? TXT_PUBMSG_ME_CHANNEL : TXT_PUBMSG_CHANNEL, printnick, target, msg, nickmode); diff --git a/src/fe-common/core/fe-windows.c b/src/fe-common/core/fe-windows.c index 1049137f..46c1593b 100644 --- a/src/fe-common/core/fe-windows.c +++ b/src/fe-common/core/fe-windows.c @@ -229,11 +229,16 @@ void window_set_history(WINDOW_REC *window, const char *name) else window->history_name = g_strdup(name); - signal_emit("window history changed", 1, window, oldname); + signal_emit("window history changed", 2, window, oldname); g_free_not_null(oldname); } +void window_clear_history(WINDOW_REC *window, const char *name) +{ + signal_emit("window history cleared", 2, window, name); +} + void window_set_level(WINDOW_REC *window, int level) { g_return_if_fail(window != NULL); diff --git a/src/fe-common/core/fe-windows.h b/src/fe-common/core/fe-windows.h index 613f15f8..32d6cfcd 100644 --- a/src/fe-common/core/fe-windows.h +++ b/src/fe-common/core/fe-windows.h @@ -66,6 +66,7 @@ void window_change_server(WINDOW_REC *window, void *server); void window_set_refnum(WINDOW_REC *window, int refnum); void window_set_name(WINDOW_REC *window, const char *name); void window_set_history(WINDOW_REC *window, const char *name); +void window_clear_history(WINDOW_REC *window, const char *name); void window_set_level(WINDOW_REC *window, int level); void window_set_immortal(WINDOW_REC *window, int immortal); diff --git a/src/fe-common/core/formats.h b/src/fe-common/core/formats.h index 07e1832c..8efd204c 100644 --- a/src/fe-common/core/formats.h +++ b/src/fe-common/core/formats.h @@ -45,11 +45,15 @@ struct _FORMAT_REC { #define PRINT_FLAG_SET_SERVERTAG 0x0010 #define PRINT_FLAG_UNSET_SERVERTAG 0x0020 +typedef struct _HILIGHT_REC HILIGHT_REC; + typedef struct _TEXT_DEST_REC { WINDOW_REC *window; SERVER_REC *server; const char *server_tag; /* if server is non-NULL, must be server->tag */ const char *target; + const char *nick; + const char *address; int level; int hilight_priority; diff --git a/src/fe-common/core/hilight-text.c b/src/fe-common/core/hilight-text.c index 9822de1e..b746f636 100644 --- a/src/fe-common/core/hilight-text.c +++ b/src/fe-common/core/hilight-text.c @@ -325,11 +325,11 @@ static void sig_print_text(TEXT_DEST_REC *dest, const char *text, if (dest->level & MSGLEVEL_NOHILIGHT) return; - hilight_start = hilight_end = 0; - hilight = hilight_match(dest->server, dest->target, - NULL, NULL, dest->level, stripped, - &hilight_start, - &hilight_end); + hilight_start = hilight_end = 0; + hilight = hilight_match(dest->server, dest->target, dest->nick, + dest->address, dest->level, stripped, + &hilight_start, &hilight_end); + if (hilight == NULL) return; diff --git a/src/fe-common/core/hilight-text.h b/src/fe-common/core/hilight-text.h index 1692b8ab..3c897def 100644 --- a/src/fe-common/core/hilight-text.h +++ b/src/fe-common/core/hilight-text.h @@ -7,8 +7,6 @@ #include "formats.h" -typedef struct _HILIGHT_REC HILIGHT_REC; - struct _HILIGHT_REC { char *text; diff --git a/src/fe-common/core/window-commands.c b/src/fe-common/core/window-commands.c index c6ab68c0..9e4aab3a 100644 --- a/src/fe-common/core/window-commands.c +++ b/src/fe-common/core/window-commands.c @@ -33,6 +33,7 @@ #include "window-items.h" #include "windows-layout.h" #include "printtext.h" +#include "command-history.h" static void window_print_binds(WINDOW_REC *win) { @@ -615,10 +616,25 @@ static void cmd_window_name(const char *data) } } -/* SYNTAX: WINDOW HISTORY <name> */ +/* SYNTAX: WINDOW HISTORY [-clear] <name> */ void cmd_window_history(const char *data) { - window_set_history(active_win, data); + GHashTable *optlist; + char *name; + void *free_arg; + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, + "window history", &optlist, &name)) + return; + + if (g_hash_table_lookup(optlist, "clear") != NULL) { + signal_continue(1, data); + window_clear_history(active_win, name); + } else { + window_set_history(active_win, name); + } + + cmd_params_free(free_arg); } /* we're moving the first window to last - move the first contiguous block @@ -883,6 +899,7 @@ void window_commands_init(void) command_set_options("window number", "sticky"); command_set_options("window server", "sticky unsticky"); command_set_options("window theme", "delete"); + command_set_options("window history", "clear"); } void window_commands_deinit(void) diff --git a/src/fe-text/gui-readline.c b/src/fe-text/gui-readline.c index a8f3ba99..5acfaf60 100644 --- a/src/fe-text/gui-readline.c +++ b/src/fe-text/gui-readline.c @@ -37,6 +37,7 @@ #include "gui-windows.h" #include "utf8.h" +#include <string.h> #include <signal.h> typedef void (*ENTRY_REDIRECT_KEY_FUNC) (int key, void *data, SERVER_REC *server, WI_ITEM_REC *item); @@ -60,11 +61,21 @@ static int paste_detect_time, paste_verify_line_count; static char *paste_entry; static int paste_entry_pos; static GArray *paste_buffer; +static GArray *paste_buffer_rest; static char *paste_old_prompt; static int paste_prompt, paste_line_count; static int paste_join_multiline; static int paste_timeout_id; +static int paste_use_bracketed_mode; +static int paste_bracketed_mode; +static int paste_was_bracketed_mode; + +/* Terminal sequences that surround the input when the terminal has the + * bracketed paste mode active. Fror more details see + * https://cirw.in/blog/bracketed-paste */ +static const unichar bp_start[] = { 0x1b, '[', '2', '0', '0', '~' }; +static const unichar bp_end[] = { 0x1b, '[', '2', '0', '1', '~' }; static void sig_input(void); @@ -247,9 +258,16 @@ static void paste_buffer_join_lines(GArray *buf) g_array_set_size(buf, dest - arr); } +static void paste_send_line(char *text) +{ + /* we need to get the current history every time because it might change between calls */ + command_history_add(command_history_current(active_win), text); + + signal_emit("send command", 3, text, active_win->active_server, active_win->active); +} + static void paste_send(void) { - HISTORY_REC *history; unichar *arr; GString *str; char out[10], *text; @@ -274,11 +292,7 @@ static void paste_send(void) } text = gui_entry_get_text(active_entry); - history = command_history_current(active_win); - command_history_add(history, text); - - signal_emit("send command", 3, text, - active_win->active_server, active_win->active); + paste_send_line(text); g_free(text); } @@ -286,12 +300,7 @@ static void paste_send(void) str = g_string_new(NULL); for (; i < paste_buffer->len; i++) { if (arr[i] == '\r' || arr[i] == '\n') { - history = command_history_current(active_win); - command_history_add(history, str->str); - - signal_emit("send command", 3, str->str, - active_win->active_server, - active_win->active); + paste_send_line(str->str); g_string_truncate(str, 0); } else if (active_entry->utf8) { out[g_unichar_to_utf8(arr[i], out)] = '\0'; @@ -305,7 +314,14 @@ static void paste_send(void) } } - gui_entry_set_text(active_entry, str->str); + if (paste_was_bracketed_mode) { + /* the text before the bracket end should be sent along with the rest */ + paste_send_line(str->str); + gui_entry_set_text(active_entry, ""); + } else { + gui_entry_set_text(active_entry, str->str); + } + g_string_free(str, TRUE); } @@ -321,6 +337,12 @@ static void paste_flush(int send) paste_send(); g_array_set_size(paste_buffer, 0); + /* re-add anything that may have been after the bracketed paste end */ + if (paste_buffer_rest->len > 0) { + g_array_append_vals(paste_buffer, paste_buffer_rest->data, paste_buffer_rest->len); + g_array_set_size(paste_buffer_rest, 0); + } + gui_entry_set_prompt(active_entry, paste_old_prompt == NULL ? "" : paste_old_prompt); g_free(paste_old_prompt); paste_old_prompt = NULL; @@ -434,22 +456,21 @@ static void key_send_line(void) add_history = *str != '\0'; history = command_history_current(active_win); + if (redir != NULL && redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN) + add_history = 0; + + if (add_history && history != NULL) { + command_history_add(history, str); + } + if (redir == NULL) { signal_emit("send command", 3, str, active_win->active_server, active_win->active); } else { - if (redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN) - add_history = 0; handle_entry_redirect(str); } - if (add_history) { - history = command_history_find(history); - if (history != NULL) - command_history_add(history, str); - } - if (active_entry != NULL) gui_entry_set_text(active_entry, ""); command_history_clear_pos(active_win); @@ -615,6 +636,8 @@ static void key_delete_to_next_space(void) static gboolean paste_timeout(gpointer data) { + paste_was_bracketed_mode = paste_bracketed_mode; + if (paste_line_count == 0) { int i; @@ -633,6 +656,70 @@ static gboolean paste_timeout(gpointer data) return FALSE; } +static void paste_bracketed_end(int i, gboolean rest) +{ + unichar last_char; + + /* if there's stuff after the end bracket, save it for later */ + if (rest) { + unichar *start = ((unichar *) paste_buffer->data) + i + G_N_ELEMENTS(bp_end); + int len = paste_buffer->len - i - G_N_ELEMENTS(bp_end); + + g_array_set_size(paste_buffer_rest, 0); + g_array_append_vals(paste_buffer_rest, start, len); + } + + /* remove the rest, including the trailing sequence chars */ + g_array_set_size(paste_buffer, i); + + last_char = g_array_index(paste_buffer, unichar, i - 1); + + if (paste_line_count > 0 && last_char != '\n' && last_char != '\r') { + /* there are newlines, but there's also stuff after the newline + * adjust line count to reflect this */ + paste_line_count++; + } + + /* decide what to do with the buffer */ + paste_timeout(NULL); + + paste_bracketed_mode = FALSE; +} + +static void paste_bracketed_middle() +{ + int i; + int marklen = G_N_ELEMENTS(bp_end); + int len = paste_buffer->len - marklen; + unichar *ptr = (unichar *) paste_buffer->data; + + if (len < 0) { + return; + } + + for (i = 0; i <= len; i++, ptr++) { + if (ptr[0] == bp_end[0] && memcmp(ptr, bp_end, sizeof(bp_end)) == 0) { + + /* if there are at least 6 bytes after the end, + * check for another start marker right afterwards */ + if (i <= (len - marklen) && + memcmp(ptr + marklen, bp_start, sizeof(bp_start)) == 0) { + + /* remove both markers*/ + g_array_remove_range(paste_buffer, i, marklen * 2); + len -= marklen * 2; + + /* go one step back */ + i--; + ptr--; + continue; + } + paste_bracketed_end(i, i != len); + break; + } + } +} + static void sig_input(void) { if (!active_entry) { @@ -646,21 +733,37 @@ static void sig_input(void) unichar key; term_gets(buffer, &line_count); key = g_array_index(buffer, unichar, 0); + /* Either Ctrl-k or Ctrl-c is pressed */ if (key == 11 || key == 3) paste_flush(key == 11); g_array_free(buffer, TRUE); } else { term_gets(paste_buffer, &paste_line_count); - if (paste_detect_time > 0 && paste_buffer->len >= 3) { + + /* use the bracketed paste mode to detect when the user pastes + * some text into the entry */ + if (paste_bracketed_mode) { + paste_bracketed_middle(); + + } else if (!paste_use_bracketed_mode && paste_detect_time > 0 && paste_buffer->len >= 3) { if (paste_timeout_id != -1) g_source_remove(paste_timeout_id); paste_timeout_id = g_timeout_add(paste_detect_time, paste_timeout, NULL); - } else { + } else if (!paste_bracketed_mode) { int i; for (i = 0; i < paste_buffer->len; i++) { unichar key = g_array_index(paste_buffer, unichar, i); signal_emit("gui key pressed", 1, GINT_TO_POINTER(key)); + + if (paste_bracketed_mode) { + /* just enabled by the signal, remove what was processed so far */ + g_array_remove_range(paste_buffer, 0, i + 1); + + /* handle single-line / small pastes here */ + paste_bracketed_middle(); + return; + } } g_array_set_size(paste_buffer, 0); paste_line_count = 0; @@ -668,6 +771,11 @@ static void sig_input(void) } } +static void key_paste_start(void) +{ + paste_bracketed_mode = TRUE; +} + time_t get_idle_time(void) { return last_keypress.tv_sec; @@ -929,6 +1037,10 @@ static void setup_changed(void) paste_verify_line_count = settings_get_int("paste_verify_line_count"); paste_join_multiline = settings_get_bool("paste_join_multiline"); + paste_use_bracketed_mode = settings_get_bool("paste_use_bracketed_mode"); + + /* Enable the bracketed paste mode on demand */ + term_set_bracketed_paste_mode(paste_use_bracketed_mode); } void gui_readline_init(void) @@ -942,13 +1054,16 @@ void gui_readline_init(void) paste_entry = NULL; paste_entry_pos = 0; paste_buffer = g_array_new(FALSE, FALSE, sizeof(unichar)); + paste_buffer_rest = g_array_new(FALSE, FALSE, sizeof(unichar)); paste_old_prompt = NULL; paste_timeout_id = -1; + paste_bracketed_mode = FALSE; g_get_current_time(&last_keypress); input_listen_init(STDIN_FILENO); settings_add_str("history", "scroll_page_count", "/2"); settings_add_time("misc", "paste_detect_time", "5msecs"); + settings_add_bool("misc", "paste_use_bracketed_mode", FALSE); /* NOTE: function keys can generate at least 5 characters long keycodes. this must be larger to allow them to work. */ settings_add_int("misc", "paste_verify_line_count", 5); @@ -1021,6 +1136,8 @@ void gui_readline_init(void) key_bind("key", NULL, "meta-O-M", "return", (SIGNAL_FUNC) key_combo); + key_bind("paste_start", "Bracketed paste start", "meta2-200~", "paste_start", (SIGNAL_FUNC) key_paste_start); + /* cursor movement */ key_bind("backward_character", "Move the cursor a character backward", "left", NULL, (SIGNAL_FUNC) key_backward_character); key_bind("forward_character", "Move the cursor a character forward", "right", NULL, (SIGNAL_FUNC) key_forward_character); @@ -1116,6 +1233,8 @@ void gui_readline_deinit(void) key_configure_freeze(); + key_unbind("paste_start", (SIGNAL_FUNC) key_paste_start); + key_unbind("backward_character", (SIGNAL_FUNC) key_backward_character); key_unbind("forward_character", (SIGNAL_FUNC) key_forward_character); key_unbind("backward_word", (SIGNAL_FUNC) key_backward_word); @@ -1173,6 +1292,7 @@ void gui_readline_deinit(void) key_unbind("stop_irc", (SIGNAL_FUNC) key_sig_stop); keyboard_destroy(keyboard); g_array_free(paste_buffer, TRUE); + g_array_free(paste_buffer_rest, TRUE); key_configure_thaw(); diff --git a/src/fe-text/term-terminfo.c b/src/fe-text/term-terminfo.c index 27be904e..3582b9e4 100644 --- a/src/fe-text/term-terminfo.c +++ b/src/fe-text/term-terminfo.c @@ -710,3 +710,11 @@ void term_gets(GArray *buffer, int *line_count) } } } + +void term_set_bracketed_paste_mode(int enable) +{ + if (enable) + tputs("\e[?2004h", 0, term_putchar); + else + tputs("\e[?2004l", 0, term_putchar); +} diff --git a/src/fe-text/term.h b/src/fe-text/term.h index f0a76c42..5f0a799e 100644 --- a/src/fe-text/term.h +++ b/src/fe-text/term.h @@ -94,6 +94,8 @@ void term_refresh(TERM_WINDOW *window); void term_stop(void); +void term_set_bracketed_paste_mode(int enable); + /* keyboard input handling */ void term_set_input_type(int type); void term_gets(GArray *buffer, int *line_count); diff --git a/src/irc/core/irc-commands.c b/src/irc/core/irc-commands.c index 3cc105ba..6baf2f6d 100644 --- a/src/irc/core/irc-commands.c +++ b/src/irc/core/irc-commands.c @@ -61,16 +61,16 @@ static int knockout_tag; /* SYNTAX: NOTICE <targets> <message> */ static void cmd_notice(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { const char *target, *msg; char *recoded; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, - &target, &msg)) + &target, &msg)) return; if (g_strcmp0(target, "*") == 0) target = item == NULL ? NULL : window_item_get_target(item); @@ -88,16 +88,16 @@ static void cmd_notice(const char *data, IRC_SERVER_REC *server, /* SYNTAX: CTCP <targets> <ctcp command> [<ctcp data>] */ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { const char *target; char *ctcpcmd, *ctcpdata; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, - &target, &ctcpcmd, &ctcpdata)) + &target, &ctcpcmd, &ctcpdata)) return; if (g_strcmp0(target, "*") == 0) target = item == NULL ? NULL : window_item_get_target(item); @@ -122,16 +122,16 @@ static void cmd_ctcp(const char *data, IRC_SERVER_REC *server, /* SYNTAX: NCTCP <targets> <ctcp command> [<ctcp data>] */ static void cmd_nctcp(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { const char *target; char *ctcpcmd, *ctcpdata, *recoded; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, - &target, &ctcpcmd, &ctcpdata)) + &target, &ctcpcmd, &ctcpdata)) return; if (g_strcmp0(target, "*") == 0) target = item == NULL ? NULL : window_item_get_target(item); @@ -150,22 +150,22 @@ static void cmd_nctcp(const char *data, IRC_SERVER_REC *server, /* SYNTAX: PART [<channels>] [<message>] */ static void cmd_part(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { char *channame, *msg; char *recoded = NULL; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | - PARAM_FLAG_OPTCHAN, item, &channame, &msg)) + PARAM_FLAG_OPTCHAN, item, &channame, &msg)) return; if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*msg == '\0') msg = (char *) settings_get_str("part_message"); - if (server->cmdcount > MAX_COMMANDS_ON_PART_UNTIL_PURGE) + if (server->cmdcount > MAX_COMMANDS_ON_PART_UNTIL_PURGE) irc_server_purge_output(server, channame); if (*msg != '\0') @@ -186,11 +186,11 @@ static void cmd_kick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item char *channame, *nicks, *reason, *recoded; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST | - PARAM_FLAG_OPTCHAN, item, - &channame, &nicks, &reason)) + PARAM_FLAG_OPTCHAN, item, + &channame, &nicks, &reason)) return; if (*channame == '\0' || *nicks == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); @@ -213,11 +213,11 @@ static void cmd_topic(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *ite char *recoded = NULL; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | - PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, - item, "topic", &optlist, &channame, &topic)) + PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, + item, "topic", &optlist, &channame, &topic)) return; if (*topic != '\0' || g_hash_table_lookup(optlist, "delete") != NULL) @@ -239,7 +239,7 @@ static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *it char *nick, *channame; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2, &nick, &channame)) return; @@ -258,17 +258,17 @@ static void cmd_invite(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *it /* SYNTAX: LIST [-yes] [<channel>] */ static void cmd_list(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { GHashTable *optlist; char *str; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, - "list", &optlist, &str)) + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + "list", &optlist, &str)) return; if (*str == '\0' && g_hash_table_lookup(optlist, "yes") == NULL && @@ -282,7 +282,7 @@ static void cmd_list(const char *data, IRC_SERVER_REC *server, /* SYNTAX: WHO [<nicks> | <channels> | **] */ static void cmd_who(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { char *channel, *rest; void *free_arg; @@ -290,7 +290,7 @@ static void cmd_who(const char *data, IRC_SERVER_REC *server, CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | - PARAM_FLAG_STRIP_TRAILING_WS, &channel, &rest)) + PARAM_FLAG_STRIP_TRAILING_WS, &channel, &rest)) return; if (g_strcmp0(channel, "*") == 0 || *channel == '\0') { @@ -313,29 +313,29 @@ static void cmd_who(const char *data, IRC_SERVER_REC *server, } static void cmd_names(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { - GHashTable *optlist; + GHashTable *optlist; char *channel; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, - "names", &optlist, &channel)) + PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, + "names", &optlist, &channel)) return; if (g_strcmp0(channel, "*") == 0 || *channel == '\0') { if (!IS_IRC_CHANNEL(item)) - cmd_param_error(CMDERR_NOT_JOINED); + cmd_param_error(CMDERR_NOT_JOINED); channel = IRC_CHANNEL(item)->name; } if (g_strcmp0(channel, "**") == 0) { /* ** displays all nicks.. */ - irc_send_cmd(server, "NAMES"); + irc_send_cmd(server, "NAMES"); } else { irc_send_cmdv(server, "NAMES %s", channel); } @@ -346,12 +346,12 @@ static void cmd_names(const char *data, IRC_SERVER_REC *server, /* SYNTAX: NICK <new nick> */ static void cmd_nick(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { - char *nick; + char *nick; void *free_arg; g_return_if_fail(data != NULL); - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1, &nick)) return; @@ -388,23 +388,23 @@ static char *get_redirect_nicklist(const char *nicks, int *free) /* SYNTAX: WHOIS [-<server tag>] [<server>] [<nicks>] */ static void cmd_whois(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { GHashTable *optlist; char *qserver, *query, *event_402, *str; void *free_arg; int free_nick; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_UNKNOWN_OPTIONS, - "whois", &optlist, &qserver, &query)) + PARAM_FLAG_UNKNOWN_OPTIONS, + "whois", &optlist, &qserver, &query)) return; /* -<server tag> */ server = IRC_SERVER(cmd_options_get_server("whois", optlist, - SERVER(server))); + SERVER(server))); if (server == NULL) { cmd_params_free(free_arg); return; @@ -439,15 +439,15 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server, str = g_strconcat(qserver, " ", query, NULL); server_redirect_event(server, "whois", 1, str, TRUE, - NULL, - "event 318", "whois end", - "event 402", event_402, - "event 301", "whois away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ - "event 313", "whois oper", - "event 401", (settings_get_bool("auto_whowas") ? "whois try whowas" : "whois event not found"), - "event 311", "whois event", - "", "whois default event", NULL); - g_free(str); + NULL, + "event 318", "whois end", + "event 402", event_402, + "event 301", "whois away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ + "event 313", "whois oper", + "event 401", (settings_get_bool("auto_whowas") ? "whois try whowas" : "whois event not found"), + "event 311", "whois event", + "", "whois default event", NULL); + g_free(str); server->whois_found = FALSE; irc_send_cmd_split(server, tmpstr->str, 2, server->max_whois_in_cmd); @@ -457,7 +457,7 @@ static void cmd_whois(const char *data, IRC_SERVER_REC *server, } static void event_whois(IRC_SERVER_REC *server, const char *data, - const char *nick, const char *addr) + const char *nick, const char *addr) { server->whois_found = TRUE; signal_emit("event 311", 4, server, data, nick, addr); @@ -473,23 +473,23 @@ static void sig_whois_try_whowas(IRC_SERVER_REC *server, const char *data) server->whowas_found = FALSE; server_redirect_event(server, "whowas", 1, nick, -1, NULL, - "event 314", "whowas event", - "event 369", "whowas event end", - "event 406", "event empty", NULL); + "event 314", "whowas event", + "event 369", "whowas event end", + "event 406", "event empty", NULL); irc_send_cmdv(server, "WHOWAS %s 1", nick); g_free(params); } static void event_end_of_whois(IRC_SERVER_REC *server, const char *data, - const char *nick, const char *addr) + const char *nick, const char *addr) { signal_emit("event 318", 4, server, data, nick, addr); server->whois_found = FALSE; } static void event_whowas(IRC_SERVER_REC *server, const char *data, - const char *nick, const char *addr) + const char *nick, const char *addr) { server->whowas_found = TRUE; signal_emit("event 314", 4, server, data, nick, addr); @@ -502,17 +502,17 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server) void *free_arg; int free_nick; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, - &nicks, &rest)) + &nicks, &rest)) return; if (*nicks == '\0') nicks = server->nick; nicks_redir = get_redirect_nicklist(nicks, &free_nick); server_redirect_event(server, "whowas", 1, nicks_redir, -1, NULL, - "event 301", "whowas away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ - "event 314", "whowas event", NULL); + "event 301", "whowas away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */ + "event 314", "whowas event", NULL); if (free_nick) g_free(nicks_redir); server->whowas_found = FALSE; @@ -529,9 +529,9 @@ static void cmd_whowas(const char *data, IRC_SERVER_REC *server) static void cmd_ping(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { GTimeVal tv; - char *str; + char *str; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (*data == '\0') { if (!IS_QUERY(item)) @@ -554,7 +554,7 @@ static void cmd_away(const char *data, IRC_SERVER_REC *server) void *free_arg; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_GETREST, "away", &optlist, &reason)) return; + PARAM_FLAG_GETREST, "away", &optlist, &reason)) return; if (g_hash_table_lookup(optlist, "one") != NULL) irc_server_send_away(server, reason); @@ -567,7 +567,7 @@ static void cmd_away(const char *data, IRC_SERVER_REC *server) /* SYNTAX: SCONNECT <new server> [[<port>] <existing server>] */ static void cmd_sconnect(const char *data, IRC_SERVER_REC *server) { - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); irc_send_cmdv(server, "CONNECT %s", data); @@ -600,11 +600,11 @@ static void cmd_wait(const char *data, IRC_SERVER_REC *server) void *free_arg; int n; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | - PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, - NULL, &optlist, &msecs)) + PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST, + NULL, &optlist, &msecs)) return; if (*msecs == '\0') @@ -612,7 +612,7 @@ static void cmd_wait(const char *data, IRC_SERVER_REC *server) /* -<server tag> */ server = IRC_SERVER(cmd_options_get_server(NULL, optlist, - SERVER(server))); + SERVER(server))); n = atoi(msecs); if (server != NULL && n > 0) { @@ -635,10 +635,10 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item IRC_CHANNEL_REC *chanrec; GSList *tmp, *nicks; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | - PARAM_FLAG_GETREST, item, &channame, &msg)) + PARAM_FLAG_GETREST, item, &channame, &msg)) return; if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); @@ -654,11 +654,11 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item /* Fall back to manually noticing each op */ nicks = NULL; g_hash_table_foreach(chanrec->nicks, - (GHFunc) cmd_wall_hash, &nicks); + (GHFunc) cmd_wall_hash, &nicks); args = g_strconcat(chanrec->name, " ", recoded, NULL); msg = parse_special_string(settings_get_str("wall_format"), - SERVER(server), item, args, NULL, 0); + SERVER(server), item, args, NULL, 0); g_free(args); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { @@ -666,7 +666,7 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item if (rec != chanrec->ownnick) { irc_send_cmdv(server, "NOTICE %s :%s", - rec->nick, msg); + rec->nick, msg); } } @@ -680,17 +680,17 @@ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item /* SYNTAX: KICKBAN [<channel>] <nicks> <reason> */ static void cmd_kickban(const char *data, IRC_SERVER_REC *server, - WI_ITEM_REC *item) + WI_ITEM_REC *item) { - IRC_CHANNEL_REC *chanrec; + IRC_CHANNEL_REC *chanrec; char *channel, *nicks, *reason, *kickcmd, *bancmd, *recoded; - char **nicklist, *spacenicks; + char **nicklist, *spacenicks; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, - item, &channel, &nicks, &reason)) + item, &channel, &nicks, &reason)) return; if (*channel == '\0' || *nicks == '\0') @@ -701,7 +701,7 @@ static void cmd_kickban(const char *data, IRC_SERVER_REC *server, cmd_param_error(CMDERR_CHAN_NOT_FOUND); nicklist = g_strsplit(nicks, ",", -1); - spacenicks = g_strjoinv(" ", nicklist); + spacenicks = g_strjoinv(" ", nicklist); g_strfreev(nicklist); recoded = recode_out(SERVER(server), reason, channel); @@ -709,9 +709,9 @@ static void cmd_kickban(const char *data, IRC_SERVER_REC *server, g_free(recoded); bancmd = g_strdup_printf("%s %s", chanrec->name, spacenicks); - g_free(spacenicks); + g_free(spacenicks); - if (settings_get_bool("kick_first_on_kickban")) { + if (settings_get_bool("kick_first_on_kickban")) { signal_emit("command kick", 3, kickcmd, server, chanrec); signal_emit("command ban", 3, bancmd, server, chanrec); } else { @@ -742,14 +742,14 @@ static void knockout_timeout_server(IRC_SERVER_REC *server) if (!IS_IRC_SERVER(server)) return; - now = time(NULL); + now = time(NULL); for (tmp = server->knockoutlist; tmp != NULL; tmp = next) { KNOCKOUT_REC *rec = tmp->data; next = tmp->next; if (rec->unban_time <= now) { /* timeout, unban. */ - ban_remove(rec->channel, rec->ban); + signal_emit("command unban", 3, rec->ban, server, rec->channel); knockout_destroy(server, rec); } } @@ -763,16 +763,16 @@ static int knockout_timeout(void) /* SYNTAX: KNOCKOUT [<time>] <nicks> <reason> */ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, - IRC_CHANNEL_REC *channel) + IRC_CHANNEL_REC *channel) { KNOCKOUT_REC *rec; char *nicks, *reason, *timeoutstr, *kickcmd, *bancmd, *recoded; - char **nicklist, *spacenicks, *banmasks; + char **nicklist, *spacenicks, *banmasks; void *free_arg; int timeleft; GSList *ptr; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!IS_IRC_CHANNEL(channel)) cmd_return_error(CMDERR_NOT_JOINED); @@ -780,14 +780,14 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, if (i_isdigit(*data)) { /* first argument is the timeout */ if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_GETREST, - &timeoutstr, &nicks, &reason)) + &timeoutstr, &nicks, &reason)) return; if (!parse_time_interval(timeoutstr, &timeleft)) cmd_param_error(CMDERR_INVALID_TIME); } else { if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, - &nicks, &reason)) + &nicks, &reason)) return; timeleft = settings_get_time("knockout_time"); } @@ -795,7 +795,7 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, if (*nicks == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); nicklist = g_strsplit(nicks, ",", -1); - spacenicks = g_strjoinv(" ", nicklist); + spacenicks = g_strjoinv(" ", nicklist); g_strfreev(nicklist); banmasks = ban_get_masks(channel, spacenicks, 0); @@ -808,7 +808,7 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, bancmd = *banmasks == '\0'? NULL : g_strdup_printf("%s %s", channel->name, banmasks); - if (settings_get_bool("kick_first_on_kickban")) { + if (settings_get_bool("kick_first_on_kickban")) { signal_emit("command kick", 3, kickcmd, server, channel); if (bancmd != NULL) signal_emit("command ban", 3, bancmd, server, channel); @@ -827,7 +827,7 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, for (ptr = server->knockoutlist; ptr != NULL; ptr = ptr->next) { rec = ptr->data; if (channel == rec->channel && - !g_strcmp0(rec->ban, banmasks)) + !g_strcmp0(rec->ban, banmasks)) break; } if (ptr == NULL) { @@ -845,10 +845,10 @@ static void cmd_knockout(const char *data, IRC_SERVER_REC *server, /* SYNTAX: SERVER PURGE [<target>] */ static void cmd_server_purge(const char *data, IRC_SERVER_REC *server) { - char *target; + char *target; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 1, &target)) return; @@ -895,12 +895,12 @@ static void cmd_oper(const char *data, IRC_SERVER_REC *server) char *nick, *password; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); - /* asking for password is handled by fe-common */ + /* asking for password is handled by fe-common */ if (!cmd_get_params(data, &free_arg, 2, &nick, &password)) return; - if (*password == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); + if (*password == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); irc_send_cmdv(server, "OPER %s %s", nick, password); cmd_params_free(free_arg); @@ -909,7 +909,7 @@ static void cmd_oper(const char *data, IRC_SERVER_REC *server) /* SYNTAX: ACCEPT [[-]nick,...] */ static void cmd_accept(const char *data, IRC_SERVER_REC *server) { - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (*data == '\0') irc_send_cmd(server, "ACCEPT *"); @@ -920,7 +920,7 @@ static void cmd_accept(const char *data, IRC_SERVER_REC *server) /* SYNTAX: UNSILENCE <nick!user@host> */ static void cmd_unsilence(const char *data, IRC_SERVER_REC *server) { - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (*data == '\0') cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS); @@ -953,7 +953,7 @@ static void command_2self(const char *data, IRC_SERVER_REC *server) char *target, *text; void *free_arg; - CMD_IRC_SERVER(server); + CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST, &target, &text)) return; @@ -998,8 +998,8 @@ void irc_commands_init(void) command_bind_irc("admin", NULL, (SIGNAL_FUNC) command_self); /* SYNTAX: INFO [<server>] */ command_bind_irc("info", NULL, (SIGNAL_FUNC) command_self); - /* SYNTAX: KNOCK <channel> */ - command_bind_irc("knock", NULL, (SIGNAL_FUNC) command_self); + /* SYNTAX: KNOCK <channel> */ + command_bind_irc("knock", NULL, (SIGNAL_FUNC) command_self); /* SYNTAX: LINKS [[<server>] <mask>] */ command_bind_irc("links", NULL, (SIGNAL_FUNC) command_self); /* SYNTAX: LUSERS [<server mask> [<remote server>]] */ @@ -1081,7 +1081,7 @@ void irc_commands_deinit(void) command_unbind("accept", (SIGNAL_FUNC) cmd_accept); command_unbind("admin", (SIGNAL_FUNC) command_self); command_unbind("info", (SIGNAL_FUNC) command_self); - command_unbind("knock", (SIGNAL_FUNC) command_self); + command_unbind("knock", (SIGNAL_FUNC) command_self); command_unbind("links", (SIGNAL_FUNC) command_self); command_unbind("lusers", (SIGNAL_FUNC) command_self); command_unbind("map", (SIGNAL_FUNC) command_self); diff --git a/src/irc/flood/autoignore.c b/src/irc/flood/autoignore.c index 250a1fe8..86ff3ec5 100644 --- a/src/irc/flood/autoignore.c +++ b/src/irc/flood/autoignore.c @@ -66,7 +66,7 @@ static void sig_flood(IRC_SERVER_REC *server, const char *nick, const char *host mask = g_strdup_printf("%s!%s", nick, host); if (level & check_level) { - rec = ignore_find(server->tag, mask, NULL); + rec = ignore_find_full(server->tag, mask, NULL, NULL, 0); if (rec == NULL) autoignore_add(server, mask, level); else diff --git a/src/irc/proxy/listen.c b/src/irc/proxy/listen.c index dcc94e6b..5dc9a704 100644 --- a/src/irc/proxy/listen.c +++ b/src/irc/proxy/listen.c @@ -681,8 +681,8 @@ static void read_settings(void) while (add_listens != NULL) { rec = add_listens->data; add_listen(rec->ircnet, rec->port); + add_listens = g_slist_remove(add_listens, rec); g_free(rec); - add_listens = g_slist_remove(add_listens, add_listens->data); } g_strfreev(ports); diff --git a/src/perl/perl-common.c b/src/perl/perl-common.c index d7a428e5..b641867f 100644 --- a/src/perl/perl-common.c +++ b/src/perl/perl-common.c @@ -246,10 +246,7 @@ char *perl_get_use_list(void) void irssi_callXS(void (*subaddr)(pTHX_ CV* cv), CV *cv, SV **mark) { - dSP; - PUSHMARK(mark); - PUTBACK; (*subaddr)(aTHX_ cv); } diff --git a/src/perl/perl-core.c b/src/perl/perl-core.c index 2f28c718..cb690906 100644 --- a/src/perl/perl-core.c +++ b/src/perl/perl-core.c @@ -82,16 +82,18 @@ static void perl_script_destroy(PERL_SCRIPT_REC *script) extern void boot_DynaLoader(pTHX_ CV* cv); #if PERL_STATIC_LIBS == 1 -extern void boot_Irssi(CV *cv); +extern void boot_Irssi(pTHX_ CV *cv); XS(boot_Irssi_Core) { dXSARGS; + PERL_UNUSED_VAR(items); irssi_callXS(boot_Irssi, cv, mark); irssi_boot(Irc); irssi_boot(UI); irssi_boot(TextUI); + /* Make sure to keep this in line with perl_scripts_deinit below. */ XSRETURN_YES; } #endif @@ -123,7 +125,7 @@ void perl_scripts_init(void) perl_parse(my_perl, xs_init, G_N_ELEMENTS(perl_args), perl_args, NULL); #if PERL_STATIC_LIBS == 1 - perl_eval_pv("Irssi::Core::boot_Irssi_Core();", TRUE); + perl_eval_pv("Irssi::Core::->boot_Irssi_Core(0.9);", TRUE); #endif perl_common_start(); @@ -155,6 +157,17 @@ void perl_scripts_deinit(void) /* Unload all perl libraries loaded with dynaloader */ perl_eval_pv("foreach my $lib (@DynaLoader::dl_modules) { if ($lib =~ /^Irssi\\b/) { $lib .= '::deinit();'; eval $lib; } }", TRUE); +#if PERL_STATIC_LIBS == 1 + /* If perl is statically built we should manually deinit the modules + which are booted in boot_Irssi_Core above */ + perl_eval_pv("foreach my $lib (qw(" + "Irssi" " " + "Irssi::Irc" " " + "Irssi::UI" " " + "Irssi::TextUI" + ")) { eval $lib . '::deinit();'; }", TRUE); +#endif + /* We could unload all libraries .. but this crashes with some libraries, probably because we don't call some deinit function.. Anyway, this would free some memory with /SCRIPT RESET, but it |