void gui_bar_window_set_current_size (struct t_gui_bar_window *bar_window, struct t_gui_window *window, int size) { int new_size, max_size; if (size == 0) new_size = 1; else { new_size = size; if ((size != 0) && (CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE_MAX]) > 0) && (size > CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE_MAX]))) { new_size = CONFIG_INTEGER(bar_window->bar->options[GUI_BAR_OPTION_SIZE_MAX]); if (new_size < 1) new_size = 1; } } if (bar_window->current_size != new_size) { max_size = gui_bar_window_get_max_size (bar_window, window); new_size = (max_size < new_size) ? max_size : new_size; if (bar_window->current_size != new_size) { bar_window->current_size = new_size; if (!CONFIG_BOOLEAN(bar_window->bar->options[GUI_BAR_OPTION_HIDDEN])) { gui_bar_window_calculate_pos_size (bar_window, window); gui_bar_window_create_win (bar_window); if (window) window->refresh_needed = 1; else gui_window_ask_refresh (1); } } } }
struct t_gui_nick * gui_nicklist_add_nick (struct t_gui_buffer *buffer, struct t_gui_nick_group *group, const char *name, const char *color, const char *prefix, const char *prefix_color, int visible) { struct t_gui_nick *new_nick; if (!buffer || !name || gui_nicklist_search_nick (buffer, NULL, name)) return NULL; new_nick = malloc (sizeof (*new_nick)); if (!new_nick) return NULL; new_nick->group = (group) ? group : buffer->nicklist_root; new_nick->name = (char *)string_shared_get (name); new_nick->color = (color) ? (char *)string_shared_get (color) : NULL; new_nick->prefix = (prefix) ? (char *)string_shared_get (prefix) : NULL; new_nick->prefix_color = (prefix_color) ? (char *)string_shared_get (prefix_color) : NULL; new_nick->visible = visible; gui_nicklist_insert_nick_sorted (new_nick->group, new_nick); buffer->nicklist_count++; buffer->nicklist_nicks_count++; if (visible) buffer->nicklist_visible_count++; if (CONFIG_BOOLEAN(config_look_color_nick_offline)) gui_buffer_ask_chat_refresh (buffer, 1); gui_nicklist_send_signal ("nicklist_nick_added", buffer, name); gui_nicklist_send_hsignal ("nicklist_nick_added", buffer, NULL, new_nick); return new_nick; }
void weechat_end (void (*gui_end_cb)(int clean_exit)) { gui_layout_store_on_exit (); /* store layout */ plugin_end (); /* end plugin interface(s) */ if (CONFIG_BOOLEAN(config_look_save_config_on_exit)) (void) config_weechat_write (); /* save WeeChat config file */ (void) secure_write (); /* save secured data */ if (gui_end_cb) (*gui_end_cb) (1); /* shut down WeeChat GUI */ proxy_free_all (); /* free all proxies */ config_weechat_free (); /* free WeeChat options */ secure_free (); /* free secured data options */ config_file_free_all (); /* free all configuration files */ gui_key_end (); /* remove all keys */ unhook_all (); /* remove all hooks */ hdata_end (); /* end hdata */ secure_end (); /* end secured data */ string_end (); /* end string */ weechat_shutdown (-1, 0); /* end other things */ }
void gui_main_init () { struct t_gui_buffer *ptr_buffer; struct t_gui_bar *ptr_bar; struct t_gui_bar_window *ptr_bar_win; char title[256]; initscr (); if (CONFIG_BOOLEAN(config_look_eat_newline_glitch)) gui_term_set_eat_newline_glitch (0); curs_set (1); noecho (); nodelay (stdscr, TRUE); raw (); gui_color_init (); /* build prefixes according to configuration */ gui_chat_prefix_build (); refresh (); gui_term_cols = COLS; gui_term_lines = LINES; gui_window_read_terminal_size (); /* init clipboard buffer */ gui_input_clipboard = NULL; /* get time length */ gui_chat_time_length = gui_chat_get_time_length (); /* init bar items */ gui_bar_item_init (); gui_init_ok = 0; /* create core buffer */ ptr_buffer = gui_buffer_new (NULL, GUI_BUFFER_MAIN, NULL, NULL, NULL, NULL); if (ptr_buffer) { gui_init_ok = 1; ptr_buffer->num_displayed = 1; /* set short name */ if (!ptr_buffer->short_name) ptr_buffer->short_name = strdup (GUI_BUFFER_MAIN); /* set title for core buffer */ snprintf (title, sizeof (title), "WeeChat %s %s - %s", version_get_version (), WEECHAT_COPYRIGHT_DATE, WEECHAT_WEBSITE); gui_buffer_set_title (ptr_buffer, title); /* create main window (using full space) */ if (gui_window_new (NULL, ptr_buffer, 0, 0, gui_term_cols, gui_term_lines, 100, 100)) { gui_current_window = gui_windows; if (CONFIG_STRING(config_look_window_title) && CONFIG_STRING(config_look_window_title)[0]) { gui_window_set_title (CONFIG_STRING(config_look_window_title)); } } /* * create bar windows for root bars (they were read from config, * but no window was created, GUI was not initialized) */ for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) { if ((CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) && (!ptr_bar->bar_window)) { gui_bar_window_new (ptr_bar, NULL); } } for (ptr_bar_win = gui_windows->bar_windows; ptr_bar_win; ptr_bar_win = ptr_bar_win->next_bar_window) { gui_bar_window_calculate_pos_size (ptr_bar_win, gui_windows); gui_bar_window_create_win (ptr_bar_win); } } if (CONFIG_BOOLEAN(config_look_mouse)) gui_mouse_enable (); else gui_mouse_disable (); gui_window_set_bracketed_paste_mode (CONFIG_BOOLEAN(config_look_paste_bracketed)); }
void gui_main_end (int clean_exit) { if (clean_exit) { /* * final refreshs, to see messages just before exiting * (if we are upgrading, don't refresh anything!) */ if (!weechat_upgrading) { gui_main_refreshs (); if (gui_window_refresh_needed) gui_main_refreshs (); } /* disable bracketed paste mode */ gui_window_set_bracketed_paste_mode (0); /* disable mouse */ gui_mouse_disable (); /* remove bar items and bars */ gui_bar_item_end (); gui_bar_free_all (); /* remove filters */ gui_filter_free_all (); /* free clipboard buffer */ if (gui_input_clipboard) free (gui_input_clipboard); /* delete layouts */ gui_layout_remove_all (); /* delete all windows */ while (gui_windows) { gui_window_free (gui_windows); } gui_window_tree_free (&gui_windows_tree); /* delete all buffers */ while (gui_buffers) { gui_buffer_close (gui_buffers); } gui_init_ok = 0; /* delete global history */ gui_history_global_free (); /* reset title */ if (CONFIG_BOOLEAN(config_look_set_title)) gui_window_set_title (NULL); /* end color */ gui_color_end (); /* free some variables used for chat area */ gui_chat_end (); } /* end of Curses output */ refresh (); endwin (); }
void gui_color_init_weechat () { if (CONFIG_BOOLEAN(config_look_color_basic_force_bold) || (gui_color_term_colors < 16)) { gui_weechat_colors = gui_weechat_colors_bold; } else { gui_weechat_colors = gui_weechat_colors_no_bold; } gui_color_build (GUI_COLOR_SEPARATOR, CONFIG_COLOR(config_color_separator), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT, CONFIG_COLOR(config_color_chat), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_TIME, CONFIG_COLOR(config_color_chat_time), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_TIME_DELIMITERS, CONFIG_COLOR(config_color_chat_time_delimiters), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_ERROR, CONFIG_COLOR(config_color_chat_prefix[GUI_CHAT_PREFIX_ERROR]), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_NETWORK, CONFIG_COLOR(config_color_chat_prefix[GUI_CHAT_PREFIX_NETWORK]), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_ACTION, CONFIG_COLOR(config_color_chat_prefix[GUI_CHAT_PREFIX_ACTION]), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_JOIN, CONFIG_COLOR(config_color_chat_prefix[GUI_CHAT_PREFIX_JOIN]), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_QUIT, CONFIG_COLOR(config_color_chat_prefix[GUI_CHAT_PREFIX_QUIT]), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_MORE, CONFIG_COLOR(config_color_chat_prefix_more), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_SUFFIX, CONFIG_COLOR(config_color_chat_prefix_suffix), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_BUFFER, CONFIG_COLOR(config_color_chat_buffer), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_SERVER, CONFIG_COLOR(config_color_chat_server), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_CHANNEL, CONFIG_COLOR(config_color_chat_channel), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK, CONFIG_COLOR(config_color_chat_nick), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK_SELF, CONFIG_COLOR(config_color_chat_nick_self), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK_OTHER, CONFIG_COLOR(config_color_chat_nick_other), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_HOST, CONFIG_COLOR(config_color_chat_host), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_DELIMITERS, CONFIG_COLOR(config_color_chat_delimiters), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_HIGHLIGHT, CONFIG_COLOR(config_color_chat_highlight), CONFIG_COLOR(config_color_chat_highlight_bg)); gui_color_build (GUI_COLOR_CHAT_READ_MARKER, CONFIG_COLOR(config_color_chat_read_marker), CONFIG_COLOR(config_color_chat_read_marker_bg)); gui_color_build (GUI_COLOR_CHAT_TEXT_FOUND, CONFIG_COLOR(config_color_chat_text_found), CONFIG_COLOR(config_color_chat_text_found_bg)); gui_color_build (GUI_COLOR_CHAT_VALUE, CONFIG_COLOR(config_color_chat_value), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_BUFFER, CONFIG_COLOR(config_color_chat_prefix_buffer), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_TAGS, CONFIG_COLOR(config_color_chat_tags), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_INACTIVE_WINDOW, CONFIG_COLOR(config_color_chat_inactive_window), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_INACTIVE_BUFFER, CONFIG_COLOR(config_color_chat_inactive_buffer), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_PREFIX_BUFFER_INACTIVE_BUFFER, CONFIG_COLOR(config_color_chat_prefix_buffer_inactive_buffer), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK_OFFLINE, CONFIG_COLOR(config_color_chat_nick_offline), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK_OFFLINE_HIGHLIGHT, CONFIG_COLOR(config_color_chat_nick_offline_highlight), CONFIG_COLOR(config_color_chat_nick_offline_highlight_bg)); gui_color_build (GUI_COLOR_CHAT_NICK_PREFIX, CONFIG_COLOR(config_color_chat_nick_prefix), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK_SUFFIX, CONFIG_COLOR(config_color_chat_nick_suffix), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_EMPHASIS, CONFIG_COLOR(config_color_emphasized), CONFIG_COLOR(config_color_emphasized_bg)); gui_color_build (GUI_COLOR_CHAT_DAY_CHANGE, CONFIG_COLOR(config_color_chat_day_change), CONFIG_COLOR(config_color_chat_bg)); /* * define old nick colors for compatibility on /upgrade with previous * versions: these colors have been removed in version 0.3.4 and replaced * by new option "weechat.color.chat_nick_colors", which is a list of * colors (without limit on number of colors) */ gui_color_build (GUI_COLOR_CHAT_NICK1_OBSOLETE, gui_color_search ("cyan"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK2_OBSOLETE, gui_color_search ("magenta"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK3_OBSOLETE, gui_color_search ("green"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK4_OBSOLETE, gui_color_search ("brown"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK5_OBSOLETE, gui_color_search ("lightblue"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK6_OBSOLETE, gui_color_search ("default"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK7_OBSOLETE, gui_color_search ("lightcyan"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK8_OBSOLETE, gui_color_search ("lightmagenta"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK9_OBSOLETE, gui_color_search ("lightgreen"), CONFIG_COLOR(config_color_chat_bg)); gui_color_build (GUI_COLOR_CHAT_NICK10_OBSOLETE, gui_color_search ("blue"), CONFIG_COLOR(config_color_chat_bg)); }
int main (int argc, char *argv[]) { weechat_first_start_time = time (NULL); /* initialize start time */ gettimeofday (&weechat_current_start_timeval, NULL); setlocale (LC_ALL, ""); /* initialize gettext */ #ifdef ENABLE_NLS bindtextdomain (PACKAGE, LOCALEDIR); bind_textdomain_codeset (PACKAGE, "UTF-8"); textdomain (PACKAGE); #endif #ifdef HAVE_LANGINFO_CODESET weechat_local_charset = strdup (nl_langinfo (CODESET)); #else weechat_local_charset = strdup (""); #endif utf8_init (); util_catch_signal (SIGINT, SIG_IGN); /* ignore SIGINT signal */ util_catch_signal (SIGQUIT, SIG_IGN); /* ignore SIGQUIT signal */ util_catch_signal (SIGPIPE, SIG_IGN); /* ignore SIGPIPE signal */ util_catch_signal (SIGSEGV, &debug_sigsegv); /* crash dump for SIGSEGV signal */ hdata_init (); /* initialize hdata */ hook_init (); /* initialize hooks */ debug_init (); /* hook signals for debug */ gui_main_pre_init (&argc, &argv); /* pre-initialize interface */ command_init (); /* initialize WeeChat commands */ completion_init (); /* add core completion hooks */ gui_key_init (); /* init keys */ network_init_gcrypt (); /* init gcrypt */ if (!secure_init ()) /* init secured data options (sec.*)*/ weechat_shutdown (EXIT_FAILURE, 0); if (!config_weechat_init ()) /* init WeeChat options (weechat.*) */ weechat_shutdown (EXIT_FAILURE, 0); weechat_parse_args (argc, argv); /* parse command line args */ weechat_create_home_dir (); /* create WeeChat home directory */ log_init (); /* init log file */ plugin_api_init (); /* create some hooks (info,hdata,..)*/ secure_read (); /* read secured data options */ config_weechat_read (); /* read WeeChat options */ network_init_gnutls (); /* init GnuTLS */ gui_main_init (); /* init WeeChat interface */ if (weechat_upgrading) { upgrade_weechat_load (); /* upgrade with session file */ weechat_upgrade_count++; /* increase /upgrade count */ } weechat_welcome_message (); /* display WeeChat welcome message */ gui_chat_print_lines_waiting_buffer (NULL); /* display lines waiting */ command_startup (0); /* command executed before plugins */ plugin_init (weechat_auto_load_plugins, /* init plugin interface(s) */ argc, argv); command_startup (1); /* commands executed after plugins */ if (!weechat_upgrading) gui_layout_window_apply (gui_layout_current, -1); if (weechat_upgrading) upgrade_weechat_end (); /* remove .upgrade files + signal */ gui_main_loop (); /* WeeChat main loop */ gui_layout_store_on_exit (); /* store layout */ plugin_end (); /* end plugin interface(s) */ if (CONFIG_BOOLEAN(config_look_save_config_on_exit)) (void) config_weechat_write (); /* save WeeChat config file */ (void) secure_write (); /* save secured data */ gui_main_end (1); /* shut down WeeChat GUI */ proxy_free_all (); /* free all proxies */ config_weechat_free (); /* free WeeChat options */ secure_free (); /* free secured data options */ config_file_free_all (); /* free all configuration files */ gui_key_end (); /* remove all keys */ unhook_all (); /* remove all hooks */ hdata_end (); /* end hdata */ secure_end (); /* end secured data */ string_end (); /* end string */ weechat_shutdown (EXIT_SUCCESS, 0); /* quit WeeChat (oh no, why?) */ return EXIT_SUCCESS; /* make C compiler happy */ }
void secure_buffer_display () { int line, count, count_encrypted; if (!secure_buffer) return; gui_buffer_clear (secure_buffer); /* set title buffer */ gui_buffer_set_title (secure_buffer, _("WeeChat secured data (sec.conf) | " "Keys: [alt-v] Toggle values")); line = 0; gui_chat_printf_y (secure_buffer, line++, "Hash algo: %s Cipher: %s Salt: %s", secure_hash_algo_string[CONFIG_INTEGER(secure_config_crypt_hash_algo)], secure_cipher_string[CONFIG_INTEGER(secure_config_crypt_cipher)], (CONFIG_BOOLEAN(secure_config_crypt_salt)) ? _("on") : _("off")); /* display passphrase */ line++; if (secure_passphrase) { if (secure_buffer_display_values) { gui_chat_printf_y (secure_buffer, line++, "%s%s = %s\"%s%s%s\"", _("Passphrase"), GUI_COLOR(GUI_COLOR_CHAT_DELIMITERS), GUI_COLOR(GUI_COLOR_CHAT), GUI_COLOR(GUI_COLOR_CHAT_VALUE), secure_passphrase, GUI_COLOR(GUI_COLOR_CHAT)); } else gui_chat_printf_y (secure_buffer, line++, _("Passphrase is set")); } else { gui_chat_printf_y (secure_buffer, line++, _("Passphrase is NOT set")); } /* display secured data */ count = secure_hashtable_data->items_count; count_encrypted = secure_hashtable_data_encrypted->items_count; if (count > 0) { line++; gui_chat_printf_y (secure_buffer, line++, _("Secured data:")); line++; hashtable_map (secure_hashtable_data, &secure_buffer_display_data, &line); } /* display secured data not decrypted */ if (count_encrypted > 0) { line++; gui_chat_printf_y (secure_buffer, line++, _("Secured data STILL ENCRYPTED: (use /secure decrypt, " "see /help secure)")); line++; hashtable_map (secure_hashtable_data_encrypted, &secure_buffer_display_data, &line); } if ((count == 0) && (count_encrypted == 0)) { line++; gui_chat_printf_y (secure_buffer, line++, _("No secured data set")); } }
void gui_key_flush (int paste) { int i, key, last_key_used, insert_ok, undo_done; static char key_str[64] = { '\0' }; static int length_key_str = 0; char key_temp[2], *key_utf, *input_old, *ptr_char, *next_char, *ptr_error; char utf_partial_char[16]; struct t_gui_buffer *old_buffer; /* if paste pending or bracketed paste detected, just return */ if (gui_key_paste_pending || gui_key_paste_bracketed) return; /* if buffer is empty, just return */ if (gui_key_buffer_size == 0) return; /* * if there's no paste pending, then we use buffer and do actions * according to keys */ gui_key_last_activity_time = time (NULL); last_key_used = -1; undo_done = 0; old_buffer = NULL; for (i = 0; i < gui_key_buffer_size; i++) { key = gui_key_buffer[i]; insert_ok = 1; utf_partial_char[0] = '\0'; if (gui_mouse_event_pending || (key < 32) || (key == 127)) { if (gui_mouse_event_pending) { insert_ok = 0; key_str[0] = (char)key; key_str[1] = '\0'; length_key_str = 1; } else if (key < 32) { insert_ok = 0; key_str[0] = '\x01'; key_str[1] = (char)key + '@'; key_str[2] = '\0'; length_key_str = 2; } else if (key == 127) { key_str[0] = '\x01'; key_str[1] = '?'; key_str[2] = '\0'; length_key_str = 2; } } else { if (local_utf8) { key_str[length_key_str] = (char)key; key_str[length_key_str + 1] = '\0'; length_key_str++; /* * replace invalid chars by "?", but NOT last char of * string, if it is incomplete UTF-8 char (another char * will be added to the string on next iteration) */ ptr_char = key_str; while (ptr_char && ptr_char[0]) { (void) utf8_is_valid (ptr_char, -1, &ptr_error); if (!ptr_error) break; next_char = (char *)utf8_next_char (ptr_error); if (next_char && next_char[0]) { ptr_char = ptr_error; while (ptr_char < next_char) { ptr_char[0] = '?'; ptr_char++; } } else { strcpy (utf_partial_char, ptr_char); ptr_char[0] = '\0'; break; } ptr_char = next_char; } } else { /* convert input to UTF-8 */ key_temp[0] = (char)key; key_temp[1] = '\0'; key_utf = string_iconv_to_internal (NULL, key_temp); strcat (key_str, key_utf); } } if (key_str[0]) { (void) hook_signal_send ("key_pressed", WEECHAT_HOOK_SIGNAL_STRING, key_str); if (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) input_old = (gui_current_window->buffer->input_buffer) ? strdup (gui_current_window->buffer->input_buffer) : strdup (""); else input_old = NULL; old_buffer = gui_current_window->buffer; if ((gui_key_pressed (key_str) != 0) && (insert_ok) && (!gui_cursor_mode)) { if (!paste || !undo_done) gui_buffer_undo_snap (gui_current_window->buffer); gui_input_insert_string (gui_current_window->buffer, key_str, -1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, (!paste || !undo_done) ? 1 : 0, 1); /* stop completion */ undo_done = 1; } /* incremental text search in buffer */ if ((old_buffer == gui_current_window->buffer) && (gui_current_window->buffer->text_search != GUI_TEXT_SEARCH_DISABLED) && ((input_old == NULL) || (gui_current_window->buffer->input_buffer == NULL) || (strcmp (input_old, gui_current_window->buffer->input_buffer) != 0))) { /* * if following conditions are all true, then do not search * again (search will not find any result and can take some time * on a buffer with many lines): * - old search was not successful * - searching a string (not a regex) * - current input is longer than old input * - beginning of current input is exactly equal to old input. */ if (!gui_current_window->buffer->text_search_found && !gui_current_window->buffer->text_search_regex && (input_old != NULL) && (input_old[0]) && (gui_current_window->buffer->input_buffer != NULL) && (gui_current_window->buffer->input_buffer[0]) && (strlen (gui_current_window->buffer->input_buffer) > strlen (input_old)) && (strncmp (gui_current_window->buffer->input_buffer, input_old, strlen (input_old)) == 0)) { /* * do not search text in buffer, just alert about text not * found */ if (CONFIG_BOOLEAN(config_look_search_text_not_found_alert)) { fprintf (stderr, "\a"); fflush (stderr); } } else { gui_window_search_restart (gui_current_window); } } if (input_old) free (input_old); } /* prepare incomplete UTF-8 char for next iteration */ if (utf_partial_char[0]) strcpy (key_str, utf_partial_char); else key_str[0] = '\0'; length_key_str = strlen (key_str); /* set last key used in buffer if combo buffer is empty */ if (gui_key_grab || gui_mouse_event_pending || !gui_key_combo_buffer[0]) last_key_used = i; } if (last_key_used == gui_key_buffer_size - 1) gui_key_buffer_reset (); else if (last_key_used >= 0) gui_key_buffer_remove (0, last_key_used + 1); if (!gui_key_grab && !gui_mouse_event_pending) gui_key_combo_buffer[0] = '\0'; }
char * eval_replace_vars_cb (void *data, const char *text) { struct t_hashtable *pointers, *extra_vars; struct t_config_option *ptr_option; struct t_gui_buffer *ptr_buffer; char str_value[64], *value, *pos, *pos1, *pos2, *hdata_name, *list_name; char *tmp, *info_name, *hide_char, *hidden_string; const char *ptr_value, *ptr_arguments, *ptr_string; struct t_hdata *hdata; void *pointer; int i, length_hide_char, length, index; pointers = (struct t_hashtable *)(((void **)data)[0]); extra_vars = (struct t_hashtable *)(((void **)data)[1]); /* 1. look for var in hashtable "extra_vars" */ if (extra_vars) { ptr_value = hashtable_get (extra_vars, text); if (ptr_value) return strdup (ptr_value); } /* 2. convert escaped chars */ if (strncmp (text, "esc:", 4) == 0) return string_convert_escaped_chars (text + 4); if ((text[0] == '\\') && text[1] && (text[1] != '\\')) return string_convert_escaped_chars (text); /* 3. hide chars: replace all chars by a given char */ if (strncmp (text, "hide:", 5) == 0) { hidden_string = NULL; ptr_string = strchr (text + 5, (text[5] == ',') ? ';' : ','); if (!ptr_string) return strdup (""); hide_char = string_strndup (text + 5, ptr_string - text - 5); if (hide_char) { length_hide_char = strlen (hide_char); length = utf8_strlen (ptr_string + 1); hidden_string = malloc ((length * length_hide_char) + 1); if (hidden_string) { index = 0; for (i = 0; i < length; i++) { memcpy (hidden_string + index, hide_char, length_hide_char); index += length_hide_char; } hidden_string[length * length_hide_char] = '\0'; } free (hide_char); } return (hidden_string) ? hidden_string : strdup (""); } /* 4. look for a color */ if (strncmp (text, "color:", 6) == 0) { ptr_value = gui_color_get_custom (text + 6); return strdup ((ptr_value) ? ptr_value : ""); } /* 5. look for an info */ if (strncmp (text, "info:", 5) == 0) { ptr_value = NULL; ptr_arguments = strchr (text + 5, ','); if (ptr_arguments) { info_name = string_strndup (text + 5, ptr_arguments - text - 5); ptr_arguments++; } else info_name = strdup (text + 5); if (info_name) { ptr_value = hook_info_get (NULL, info_name, ptr_arguments); free (info_name); } return strdup ((ptr_value) ? ptr_value : ""); } /* 6. look for name of option: if found, return this value */ if (strncmp (text, "sec.data.", 9) == 0) { ptr_value = hashtable_get (secure_hashtable_data, text + 9); return strdup ((ptr_value) ? ptr_value : ""); } else { config_file_search_with_string (text, NULL, NULL, &ptr_option, NULL); if (ptr_option) { if (!ptr_option->value) return strdup (""); switch (ptr_option->type) { case CONFIG_OPTION_TYPE_BOOLEAN: return strdup (CONFIG_BOOLEAN(ptr_option) ? EVAL_STR_TRUE : EVAL_STR_FALSE); case CONFIG_OPTION_TYPE_INTEGER: if (ptr_option->string_values) return strdup (ptr_option->string_values[CONFIG_INTEGER(ptr_option)]); snprintf (str_value, sizeof (str_value), "%d", CONFIG_INTEGER(ptr_option)); return strdup (str_value); case CONFIG_OPTION_TYPE_STRING: return strdup (CONFIG_STRING(ptr_option)); case CONFIG_OPTION_TYPE_COLOR: return strdup (gui_color_get_name (CONFIG_COLOR(ptr_option))); case CONFIG_NUM_OPTION_TYPES: return strdup (""); } } } /* 7. look for local variable in buffer */ ptr_buffer = hashtable_get (pointers, "buffer"); if (ptr_buffer) { ptr_value = hashtable_get (ptr_buffer->local_variables, text); if (ptr_value) return strdup (ptr_value); } /* 8. look for hdata */ value = NULL; hdata_name = NULL; list_name = NULL; pointer = NULL; pos = strchr (text, '.'); if (pos > text) hdata_name = string_strndup (text, pos - text); else hdata_name = strdup (text); if (!hdata_name) goto end; pos1 = strchr (hdata_name, '['); if (pos1 > hdata_name) { pos2 = strchr (pos1 + 1, ']'); if (pos2 > pos1 + 1) { list_name = string_strndup (pos1 + 1, pos2 - pos1 - 1); } tmp = string_strndup (hdata_name, pos1 - hdata_name); if (tmp) { free (hdata_name); hdata_name = tmp; } } hdata = hook_hdata_get (NULL, hdata_name); if (!hdata) goto end; if (list_name) pointer = hdata_get_list (hdata, list_name); if (!pointer) { pointer = hashtable_get (pointers, hdata_name); if (!pointer) goto end; } value = eval_hdata_get_value (hdata, pointer, (pos) ? pos + 1 : NULL); end: if (hdata_name) free (hdata_name); if (list_name) free (list_name); return (value) ? value : strdup (""); }
int completion_list_add_config_option_values_cb (void *data, const char *completion_item, struct t_gui_buffer *buffer, struct t_gui_completion *completion) { char *pos_space, *option_full_name, *pos_section, *pos_option; char *file, *section, *value_string, str_number[64]; const char *color_name; int length, i, num_colors; struct t_config_file *ptr_config; struct t_config_section *ptr_section, *section_found; struct t_config_option *option_found; struct t_gui_color_palette *color_palette; /* make C compiler happy */ (void) data; (void) completion_item; (void) buffer; if (completion->args) { pos_space = strchr (completion->args, ' '); if (pos_space) option_full_name = string_strndup (completion->args, pos_space - completion->args); else option_full_name = strdup (completion->args); if (option_full_name) { file = NULL; section = NULL; pos_option = NULL; pos_section = strchr (option_full_name, '.'); pos_option = (pos_section) ? strchr (pos_section + 1, '.') : NULL; if (pos_section && pos_option) { file = string_strndup (option_full_name, pos_section - option_full_name); section = string_strndup (pos_section + 1, pos_option - pos_section - 1); pos_option++; } if (file && section && pos_option) { ptr_config = config_file_search (file); if (ptr_config) { ptr_section = config_file_search_section (ptr_config, section); if (ptr_section) { config_file_search_section_option (ptr_config, ptr_section, pos_option, §ion_found, &option_found); if (option_found) { switch (option_found->type) { case CONFIG_OPTION_TYPE_BOOLEAN: gui_completion_list_add (completion, "on", 0, WEECHAT_LIST_POS_SORT); gui_completion_list_add (completion, "off", 0, WEECHAT_LIST_POS_SORT); gui_completion_list_add (completion, "toggle", 0, WEECHAT_LIST_POS_END); if (option_found->value) { if (CONFIG_BOOLEAN(option_found) == CONFIG_BOOLEAN_TRUE) gui_completion_list_add (completion, "on", 0, WEECHAT_LIST_POS_BEGINNING); else gui_completion_list_add (completion, "off", 0, WEECHAT_LIST_POS_BEGINNING); } else { gui_completion_list_add (completion, WEECHAT_CONFIG_OPTION_NULL, 0, WEECHAT_LIST_POS_BEGINNING); } break; case CONFIG_OPTION_TYPE_INTEGER: if (option_found->string_values) { for (i = 0; option_found->string_values[i]; i++) { gui_completion_list_add (completion, option_found->string_values[i], 0, WEECHAT_LIST_POS_SORT); } gui_completion_list_add (completion, "++1", 0, WEECHAT_LIST_POS_END); gui_completion_list_add (completion, "--1", 0, WEECHAT_LIST_POS_END); if (option_found->value) { gui_completion_list_add (completion, option_found->string_values[CONFIG_INTEGER(option_found)], 0, WEECHAT_LIST_POS_BEGINNING); } else { gui_completion_list_add (completion, WEECHAT_CONFIG_OPTION_NULL, 0, WEECHAT_LIST_POS_BEGINNING); } } else { if (option_found->value && CONFIG_INTEGER(option_found) > option_found->min) gui_completion_list_add (completion, "--1", 0, WEECHAT_LIST_POS_BEGINNING); if (option_found->value && CONFIG_INTEGER(option_found) < option_found->max) gui_completion_list_add (completion, "++1", 0, WEECHAT_LIST_POS_BEGINNING); if (option_found->value) { length = 64; value_string = malloc (length); if (value_string) { snprintf (value_string, length, "%d", CONFIG_INTEGER(option_found)); gui_completion_list_add (completion, value_string, 0, WEECHAT_LIST_POS_BEGINNING); free (value_string); } } else { gui_completion_list_add (completion, WEECHAT_CONFIG_OPTION_NULL, 0, WEECHAT_LIST_POS_BEGINNING); } } break; case CONFIG_OPTION_TYPE_STRING: gui_completion_list_add (completion, "\"\"", 0, WEECHAT_LIST_POS_BEGINNING); if (option_found->value) { length = strlen (CONFIG_STRING(option_found)) + 2 + 1; value_string = malloc (length); if (value_string) { snprintf (value_string, length, "\"%s\"", CONFIG_STRING(option_found)); gui_completion_list_add (completion, value_string, 0, WEECHAT_LIST_POS_BEGINNING); free (value_string); } } else { gui_completion_list_add (completion, WEECHAT_CONFIG_OPTION_NULL, 0, WEECHAT_LIST_POS_BEGINNING); } break; case CONFIG_OPTION_TYPE_COLOR: num_colors = gui_color_get_weechat_colors_number (); for (i = 0; i < num_colors; i++) { color_name = gui_color_get_name (i); if (color_name) { gui_completion_list_add (completion, color_name, 0, WEECHAT_LIST_POS_SORT); } } num_colors = gui_color_get_term_colors (); for (i = 0; i <= num_colors; i++) { color_palette = gui_color_palette_get (i); if (color_palette) { gui_completion_list_add (completion, color_palette->alias, 0, WEECHAT_LIST_POS_END); } else { snprintf (str_number, sizeof (str_number), "%d", i); gui_completion_list_add (completion, str_number, 0, WEECHAT_LIST_POS_END); } } gui_completion_list_add (completion, "++1", 0, WEECHAT_LIST_POS_END); gui_completion_list_add (completion, "--1", 0, WEECHAT_LIST_POS_END); if (option_found->value) { color_name = gui_color_get_name (CONFIG_INTEGER(option_found)); if (color_name) { gui_completion_list_add (completion, color_name, 0, WEECHAT_LIST_POS_BEGINNING); } } else { gui_completion_list_add (completion, WEECHAT_CONFIG_OPTION_NULL, 0, WEECHAT_LIST_POS_BEGINNING); } break; case CONFIG_NUM_OPTION_TYPES: break; } if (option_found->value && option_found->null_value_allowed) { gui_completion_list_add (completion, WEECHAT_CONFIG_OPTION_NULL, 0, WEECHAT_LIST_POS_END); } } } } } if (file) free (file); if (section) free (section); } } return WEECHAT_RC_OK; }
struct t_gui_hotlist * gui_hotlist_add (struct t_gui_buffer *buffer, enum t_gui_hotlist_priority priority, struct timeval *creation_time) { struct t_gui_hotlist *new_hotlist, *ptr_hotlist; int i, count[GUI_HOTLIST_NUM_PRIORITIES]; const char *away; if (!buffer || !gui_add_hotlist) return NULL; /* do not add core buffer if upgrading */ if (weechat_upgrading && (buffer == gui_buffer_search_main ())) return NULL; /* do not add buffer if it is displayed and away is not set */ away = hashtable_get (buffer->local_variables, "away"); if ((buffer->num_displayed > 0) && ((!away || !away[0]) || !CONFIG_BOOLEAN(config_look_hotlist_add_buffer_if_away))) return NULL; if (priority > GUI_HOTLIST_MAX) priority = GUI_HOTLIST_MAX; /* check if priority is OK according to buffer notify level value */ if (!gui_hotlist_check_buffer_notify (buffer, priority)) return NULL; /* init count */ for (i = 0; i < GUI_HOTLIST_NUM_PRIORITIES; i++) { count[i] = 0; } ptr_hotlist = gui_hotlist_search (gui_hotlist, buffer); if (ptr_hotlist) { /* return if priority is greater or equal than the one to add */ if (ptr_hotlist->priority >= priority) { ptr_hotlist->count[priority]++; gui_hotlist_changed_signal (); return ptr_hotlist; } /* * if buffer is present with lower priority: save counts, remove it * and go on */ memcpy (count, ptr_hotlist->count, sizeof (ptr_hotlist->count)); gui_hotlist_free (&gui_hotlist, &last_gui_hotlist, ptr_hotlist); } new_hotlist = malloc (sizeof (*new_hotlist)); if (!new_hotlist) { log_printf (_("Error: not enough memory to add a buffer to " "hotlist")); return NULL; } new_hotlist->priority = priority; if (creation_time) { memcpy (&(new_hotlist->creation_time), creation_time, sizeof (*creation_time)); } else gettimeofday (&(new_hotlist->creation_time), NULL); new_hotlist->buffer = buffer; memcpy (new_hotlist->count, count, sizeof (new_hotlist->count)); new_hotlist->count[priority]++; new_hotlist->next_hotlist = NULL; new_hotlist->prev_hotlist = NULL; gui_hotlist_add_hotlist (&gui_hotlist, &last_gui_hotlist, new_hotlist); gui_hotlist_changed_signal (); return new_hotlist; }
void network_connect_child (struct t_hook *hook_connect) { struct t_proxy *ptr_proxy; struct addrinfo hints, *res, *res_local, *ptr_res; char status_str[2], *ptr_address, *status_with_string; char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1]; char status_without_string[1 + 5 + 1]; const char *error; int rc, length, num_written; res = NULL; res_local = NULL; status_str[1] = '\0'; ptr_address = NULL; ptr_proxy = NULL; if (HOOK_CONNECT(hook_connect, proxy) && HOOK_CONNECT(hook_connect, proxy)[0]) { ptr_proxy = proxy_search (HOOK_CONNECT(hook_connect, proxy)); if (!ptr_proxy) { /* proxy not found */ snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_PROXY_ERROR); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; return; } } if (ptr_proxy) { /* get info about peer */ memset (&hints, 0, sizeof (hints)); hints.ai_family = (CONFIG_BOOLEAN(ptr_proxy->options[PROXY_OPTION_IPV6])) ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; rc = getaddrinfo (CONFIG_STRING(ptr_proxy->options[PROXY_OPTION_ADDRESS]), NULL, &hints, &res); if (rc != 0) { /* address not found */ status_with_string = NULL; error = gai_strerror (rc); if (error) { length = 1 + 5 + strlen (error) + 1; status_with_string = malloc (length); if (status_with_string) { snprintf (status_with_string, length, "%c%05d%s", '0' + WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND, (int)strlen (error), error); } } if (status_with_string) { num_written = write (HOOK_CONNECT(hook_connect, child_write), status_with_string, strlen (status_with_string)); } else { snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); } if (status_with_string) free (status_with_string); (void) num_written; return; } if (!res) { /* adddress not found */ snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; return; } if ((CONFIG_BOOLEAN(ptr_proxy->options[PROXY_OPTION_IPV6]) && (res->ai_family != AF_INET6)) || ((!CONFIG_BOOLEAN(ptr_proxy->options[PROXY_OPTION_IPV6]) && (res->ai_family != AF_INET)))) { /* IP address not found */ snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; freeaddrinfo (res); return; } if (CONFIG_BOOLEAN(ptr_proxy->options[PROXY_OPTION_IPV6])) ((struct sockaddr_in6 *)(res->ai_addr))->sin6_port = htons (CONFIG_INTEGER(ptr_proxy->options[PROXY_OPTION_PORT])); else ((struct sockaddr_in *)(res->ai_addr))->sin_port = htons (CONFIG_INTEGER(ptr_proxy->options[PROXY_OPTION_PORT])); /* connect to peer */ if (!network_connect (HOOK_CONNECT(hook_connect, sock), res->ai_addr, res->ai_addrlen)) { /* connection refused */ snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; freeaddrinfo (res); return; } if (!network_pass_proxy (HOOK_CONNECT(hook_connect, proxy), HOOK_CONNECT(hook_connect, sock), HOOK_CONNECT(hook_connect, address), HOOK_CONNECT(hook_connect, port))) { /* proxy fails to connect to peer */ snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_PROXY_ERROR); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; freeaddrinfo (res); return; } status_str[0] = '0' + WEECHAT_HOOK_CONNECT_OK; } else { /* set local hostname/IP if asked by user */ if (HOOK_CONNECT(hook_connect, local_hostname) && HOOK_CONNECT(hook_connect, local_hostname[0])) { memset (&hints, 0, sizeof(hints)); hints.ai_family = (HOOK_CONNECT(hook_connect, ipv6)) ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; rc = getaddrinfo (HOOK_CONNECT(hook_connect, local_hostname), NULL, &hints, &res_local); if (rc != 0) { /* fails to set local hostname/IP */ status_with_string = NULL; error = gai_strerror (rc); if (error) { length = 1 + 5 + strlen (error) + 1; status_with_string = malloc (length); if (status_with_string) { snprintf (status_with_string, length, "%c%05d%s", '0' + WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR, (int)strlen (error), error); } } if (status_with_string) { num_written = write (HOOK_CONNECT(hook_connect, child_write), status_with_string, strlen (status_with_string)); } else { snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); } if (status_with_string) free (status_with_string); (void) num_written; if (res_local) freeaddrinfo (res_local); return; } else if (!res_local || (HOOK_CONNECT(hook_connect, ipv6) && (res_local->ai_family != AF_INET6)) || ((!HOOK_CONNECT(hook_connect, ipv6) && (res_local->ai_family != AF_INET)))) { /* fails to set local hostname/IP */ snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; if (res_local) freeaddrinfo (res_local); return; } if (bind (HOOK_CONNECT(hook_connect, sock), res_local->ai_addr, res_local->ai_addrlen) < 0) { /* fails to set local hostname/IP */ snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; if (res_local) freeaddrinfo (res_local); return; } } /* get info about peer */ memset (&hints, 0, sizeof(hints)); hints.ai_family = (HOOK_CONNECT(hook_connect, ipv6)) ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; rc = getaddrinfo (HOOK_CONNECT(hook_connect, address), NULL, &hints, &res); if (rc != 0) { status_with_string = NULL; error = gai_strerror (rc); if (error) { length = 1 + 5 + strlen (error) + 1; status_with_string = malloc (length); if (status_with_string) { snprintf (status_with_string, length, "%c%05d%s", '0' + WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND, (int)strlen (error), error); } } if (status_with_string) { num_written = write (HOOK_CONNECT(hook_connect, child_write), status_with_string, strlen (status_with_string)); } else { snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); } if (status_with_string) free (status_with_string); (void) num_written; if (res) freeaddrinfo (res); if (res_local) freeaddrinfo (res_local); return; } else if (!res) { /* address not found */ snprintf (status_without_string, sizeof (status_without_string), "%c00000", '0' + WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; if (res) freeaddrinfo (res); if (res_local) freeaddrinfo (res_local); return; } status_str[0] = '0' + WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND; /* try all IP addresses found, stop when connection is ok */ for (ptr_res = res; ptr_res; ptr_res = ptr_res->ai_next) { /* skip IP address if it's not good family */ if ((HOOK_CONNECT(hook_connect, ipv6) && (ptr_res->ai_family != AF_INET6)) || ((!HOOK_CONNECT(hook_connect, ipv6) && (ptr_res->ai_family != AF_INET)))) continue; /* connect to peer */ if (HOOK_CONNECT(hook_connect, ipv6)) ((struct sockaddr_in6 *)(ptr_res->ai_addr))->sin6_port = htons (HOOK_CONNECT(hook_connect, port)); else ((struct sockaddr_in *)(ptr_res->ai_addr))->sin_port = htons (HOOK_CONNECT(hook_connect, port)); if (network_connect (HOOK_CONNECT(hook_connect, sock), ptr_res->ai_addr, ptr_res->ai_addrlen)) { status_str[0] = '0' + WEECHAT_HOOK_CONNECT_OK; if (HOOK_CONNECT(hook_connect, ipv6)) { if (inet_ntop (AF_INET6, &((struct sockaddr_in6 *)(ptr_res->ai_addr))->sin6_addr, ipv6_address, INET6_ADDRSTRLEN)) { ptr_address = ipv6_address; } } else { if (inet_ntop (AF_INET, &((struct sockaddr_in *)(ptr_res->ai_addr))->sin_addr, ipv4_address, INET_ADDRSTRLEN)) { ptr_address = ipv4_address; } } break; } else status_str[0] = '0' + WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED; } } if (status_str[0] == '0' + WEECHAT_HOOK_CONNECT_OK) { status_with_string = NULL; if (ptr_address) { length = strlen (status_str) + 5 + strlen (ptr_address) + 1; status_with_string = malloc (length); if (status_with_string) { snprintf (status_with_string, length, "%s%05d%s", status_str, (int)strlen (ptr_address), ptr_address); } } if (status_with_string) { num_written = write (HOOK_CONNECT(hook_connect, child_write), status_with_string, strlen (status_with_string)); (void) num_written; free (status_with_string); } else { snprintf (status_without_string, sizeof (status_without_string), "%s00000", status_str); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; } } else { snprintf (status_without_string, sizeof (status_without_string), "%s00000", status_str); num_written = write (HOOK_CONNECT(hook_connect, child_write), status_without_string, strlen (status_without_string)); (void) num_written; } if (res) freeaddrinfo (res); if (res_local) freeaddrinfo (res_local); }
int secure_encrypt_data (const char *data, int length_data, int hash_algo, int cipher, const char *passphrase, char **encrypted, int *length_encrypted) { int rc, length_salt, length_hash, length_hash_data, length_key; int hd_md_opened, hd_cipher_opened; gcry_md_hd_t *hd_md; gcry_cipher_hd_t *hd_cipher; char salt[SALT_SIZE]; unsigned char *ptr_hash, *key, *hash_and_data; rc = -1; hd_md = NULL; hd_md_opened = 0; hd_cipher = NULL; hd_cipher_opened = 0; key = NULL; hash_and_data = NULL; hd_md = malloc (sizeof (gcry_md_hd_t)); if (!hd_md) return -1; hd_cipher = malloc (sizeof (gcry_cipher_hd_t)); if (!hd_cipher) { free (hd_md); return -1; } /* derive a key from the passphrase */ length_key = gcry_cipher_get_algo_keylen (cipher); key = malloc (length_key); if (!key) goto encend; if (CONFIG_BOOLEAN(secure_config_crypt_salt)) gcry_randomize (salt, SALT_SIZE, GCRY_STRONG_RANDOM); else { length_salt = strlen (SECURE_SALT_DEFAULT); if (length_salt < SALT_SIZE) memset (salt, 0, SALT_SIZE); memcpy (salt, SECURE_SALT_DEFAULT, (length_salt <= SALT_SIZE) ? length_salt : SALT_SIZE); } if (!secure_derive_key (salt, passphrase, key, length_key)) { rc = -2; goto encend; } /* compute hash of data */ if (gcry_md_open (hd_md, hash_algo, 0) != 0) { rc = -3; goto encend; } hd_md_opened = 1; length_hash = gcry_md_get_algo_dlen (hash_algo); gcry_md_write (*hd_md, data, length_data); ptr_hash = gcry_md_read (*hd_md, hash_algo); if (!ptr_hash) { rc = -3; goto encend; } /* build a buffer with hash + data */ length_hash_data = length_hash + length_data; hash_and_data = malloc (length_hash_data); if (!hash_and_data) goto encend; memcpy (hash_and_data, ptr_hash, length_hash); memcpy (hash_and_data + length_hash, data, length_data); /* encrypt hash + data */ if (gcry_cipher_open (hd_cipher, cipher, GCRY_CIPHER_MODE_CFB, 0) != 0) { rc = -4; goto encend; } hd_cipher_opened = 1; if (gcry_cipher_setkey (*hd_cipher, key, length_key) != 0) { rc = -5; goto encend; } if (gcry_cipher_encrypt (*hd_cipher, hash_and_data, length_hash_data, NULL, 0) != 0) { rc = -6; goto encend; } /* create buffer and copy salt + encrypted hash/data into this buffer*/ *length_encrypted = SALT_SIZE + length_hash_data; *encrypted = malloc (*length_encrypted); if (!*encrypted) goto encend; memcpy (*encrypted, salt, SALT_SIZE); memcpy (*encrypted + SALT_SIZE, hash_and_data, length_hash_data); rc = 0; encend: if (hd_md) { if (hd_md_opened) gcry_md_close (*hd_md); free (hd_md); } if (hd_cipher) { if (hd_cipher_opened) gcry_cipher_close (*hd_cipher); free (hd_cipher); } if (key) free (key); if (hash_and_data) free (hash_and_data); return rc; }
char * eval_replace_vars_cb (void *data, const char *text) { struct t_hashtable *pointers, *extra_vars; struct t_eval_regex *eval_regex; struct t_config_option *ptr_option; struct t_gui_buffer *ptr_buffer; char str_value[512], *value, *pos, *pos1, *pos2, *hdata_name, *list_name; char *tmp, *info_name, *hide_char, *hidden_string, *error; const char *prefix, *suffix, *ptr_value, *ptr_arguments, *ptr_string; struct t_hdata *hdata; void *pointer; int i, length_hide_char, length, index, rc, extra_vars_eval; long number; long unsigned int ptr; time_t date; struct tm *date_tmp; pointers = (struct t_hashtable *)(((void **)data)[0]); extra_vars = (struct t_hashtable *)(((void **)data)[1]); extra_vars_eval = *(int *)(((void **)data)[2]); prefix = (const char *)(((void **)data)[3]); suffix = (const char *)(((void **)data)[4]); eval_regex = (struct t_eval_regex *)(((void **)data)[5]); /* 1. variable in hashtable "extra_vars" */ if (extra_vars) { ptr_value = hashtable_get (extra_vars, text); if (ptr_value) { if (extra_vars_eval) { return eval_replace_vars (ptr_value, pointers, extra_vars, extra_vars_eval, prefix, suffix, eval_regex); } else { return strdup (ptr_value); } } } /* * 2. force evaluation of string (recursive call) * --> use with caution: the text must be safe! */ if (strncmp (text, "eval:", 5) == 0) { return eval_replace_vars (text + 5, pointers, extra_vars, extra_vars_eval, prefix, suffix, eval_regex); } /* 3. convert escaped chars */ if (strncmp (text, "esc:", 4) == 0) return string_convert_escaped_chars (text + 4); if ((text[0] == '\\') && text[1] && (text[1] != '\\')) return string_convert_escaped_chars (text); /* 4. hide chars: replace all chars by a given char/string */ if (strncmp (text, "hide:", 5) == 0) { hidden_string = NULL; ptr_string = strchr (text + 5, (text[5] == ',') ? ';' : ','); if (!ptr_string) return strdup (""); hide_char = string_strndup (text + 5, ptr_string - text - 5); if (hide_char) { length_hide_char = strlen (hide_char); length = utf8_strlen (ptr_string + 1); hidden_string = malloc ((length * length_hide_char) + 1); if (hidden_string) { index = 0; for (i = 0; i < length; i++) { memcpy (hidden_string + index, hide_char, length_hide_char); index += length_hide_char; } hidden_string[length * length_hide_char] = '\0'; } free (hide_char); } return (hidden_string) ? hidden_string : strdup (""); } /* 5. regex group captured */ if (strncmp (text, "re:", 3) == 0) { if (eval_regex && eval_regex->result) { if (strcmp (text + 3, "+") == 0) number = eval_regex->last_match; else { number = strtol (text + 3, &error, 10); if (!error || error[0]) number = -1; } if ((number >= 0) && (number <= eval_regex->last_match)) { return string_strndup ( eval_regex->result + eval_regex->match[number].rm_so, eval_regex->match[number].rm_eo - eval_regex->match[number].rm_so); } } return strdup (""); } /* 6. color code */ if (strncmp (text, "color:", 6) == 0) { ptr_value = gui_color_search_config (text + 6); if (ptr_value) return strdup (ptr_value); ptr_value = gui_color_get_custom (text + 6); return strdup ((ptr_value) ? ptr_value : ""); } /* 7. info */ if (strncmp (text, "info:", 5) == 0) { ptr_value = NULL; ptr_arguments = strchr (text + 5, ','); if (ptr_arguments) { info_name = string_strndup (text + 5, ptr_arguments - text - 5); ptr_arguments++; } else info_name = strdup (text + 5); if (info_name) { ptr_value = hook_info_get (NULL, info_name, ptr_arguments); free (info_name); } return strdup ((ptr_value) ? ptr_value : ""); } /* 8. current date/time */ if ((strncmp (text, "date", 4) == 0) && (!text[4] || (text[4] == ':'))) { date = time (NULL); date_tmp = localtime (&date); if (!date_tmp) return strdup (""); rc = (int) strftime (str_value, sizeof (str_value), (text[4] == ':') ? text + 5 : "%F %T", date_tmp); return strdup ((rc > 0) ? str_value : ""); } /* 9. environment variable */ if (strncmp (text, "env:", 4) == 0) { ptr_value = getenv (text + 4); if (ptr_value) return strdup (ptr_value); } /* 10. option: if found, return this value */ if (strncmp (text, "sec.data.", 9) == 0) { ptr_value = hashtable_get (secure_hashtable_data, text + 9); return strdup ((ptr_value) ? ptr_value : ""); } else { config_file_search_with_string (text, NULL, NULL, &ptr_option, NULL); if (ptr_option) { if (!ptr_option->value) return strdup (""); switch (ptr_option->type) { case CONFIG_OPTION_TYPE_BOOLEAN: return strdup (CONFIG_BOOLEAN(ptr_option) ? EVAL_STR_TRUE : EVAL_STR_FALSE); case CONFIG_OPTION_TYPE_INTEGER: if (ptr_option->string_values) return strdup (ptr_option->string_values[CONFIG_INTEGER(ptr_option)]); snprintf (str_value, sizeof (str_value), "%d", CONFIG_INTEGER(ptr_option)); return strdup (str_value); case CONFIG_OPTION_TYPE_STRING: return strdup (CONFIG_STRING(ptr_option)); case CONFIG_OPTION_TYPE_COLOR: return strdup (gui_color_get_name (CONFIG_COLOR(ptr_option))); case CONFIG_NUM_OPTION_TYPES: return strdup (""); } } } /* 11. local variable in buffer */ ptr_buffer = hashtable_get (pointers, "buffer"); if (ptr_buffer) { ptr_value = hashtable_get (ptr_buffer->local_variables, text); if (ptr_value) return strdup (ptr_value); } /* 12. hdata */ value = NULL; hdata_name = NULL; list_name = NULL; pointer = NULL; pos = strchr (text, '.'); if (pos > text) hdata_name = string_strndup (text, pos - text); else hdata_name = strdup (text); if (!hdata_name) goto end; pos1 = strchr (hdata_name, '['); if (pos1 > hdata_name) { pos2 = strchr (pos1 + 1, ']'); if (pos2 > pos1 + 1) { list_name = string_strndup (pos1 + 1, pos2 - pos1 - 1); } tmp = string_strndup (hdata_name, pos1 - hdata_name); if (tmp) { free (hdata_name); hdata_name = tmp; } } hdata = hook_hdata_get (NULL, hdata_name); if (!hdata) goto end; if (list_name) { if (strncmp (list_name, "0x", 2) == 0) { rc = sscanf (list_name, "%lx", &ptr); if ((rc != EOF) && (rc != 0)) { pointer = (void *)ptr; if (!hdata_check_pointer (hdata, NULL, pointer)) goto end; } else goto end; } else pointer = hdata_get_list (hdata, list_name); } if (!pointer) { pointer = hashtable_get (pointers, hdata_name); if (!pointer) goto end; } value = eval_hdata_get_value (hdata, pointer, (pos) ? pos + 1 : NULL); end: if (hdata_name) free (hdata_name); if (list_name) free (list_name); return (value) ? value : strdup (""); }
void weechat_startup_message () { if (weechat_headless) { string_fprintf (stdout, _("WeeChat is running in headless mode " "(Ctrl-C to quit).")); string_fprintf (stdout, "\n"); } if (CONFIG_BOOLEAN(config_startup_display_logo)) { gui_chat_printf ( NULL, "%s ___ __ ______________ _____ \n" "%s __ | / /___________ ____/__ /_______ __ /_\n" "%s __ | /| / /_ _ \\ _ \\ / __ __ \\ __ `/ __/\n" "%s __ |/ |/ / / __/ __/ /___ _ / / / /_/ // /_ \n" "%s ____/|__/ \\___/\\___/\\____/ /_/ /_/\\__,_/ \\__/ ", GUI_COLOR(GUI_COLOR_CHAT_NICK), GUI_COLOR(GUI_COLOR_CHAT_NICK), GUI_COLOR(GUI_COLOR_CHAT_NICK), GUI_COLOR(GUI_COLOR_CHAT_NICK), GUI_COLOR(GUI_COLOR_CHAT_NICK)); } if (CONFIG_BOOLEAN(config_startup_display_version)) { command_version_display (NULL, 0, 0, 0); } if (CONFIG_BOOLEAN(config_startup_display_logo) || CONFIG_BOOLEAN(config_startup_display_version)) { gui_chat_printf ( NULL, "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); } if (weechat_first_start) { /* message on first run (when weechat.conf is created) */ gui_chat_printf (NULL, ""); gui_chat_printf ( NULL, _("Welcome to WeeChat!\n" "\n" "If you are discovering WeeChat, it is recommended to read at " "least the quickstart guide, and the user's guide if you have " "some time; they explain main WeeChat concepts.\n" "All WeeChat docs are available at: https://weechat.org/doc\n" "\n" "Moreover, there is inline help with /help on all commands and " "options (use Tab key to complete the name).\n" "The command /fset can help to customize WeeChat.\n" "\n" "You can add and connect to an IRC server with /server and " "/connect commands (see /help server).")); gui_chat_printf (NULL, ""); gui_chat_printf (NULL, "---"); gui_chat_printf (NULL, ""); } }
void gui_main_init () { struct t_gui_buffer *ptr_buffer; struct t_gui_bar *ptr_bar; struct t_gui_bar_window *ptr_bar_win; GdkColor color_fg, color_bg; gui_color_init (); gui_ok = 1; /* build prefixes according to config */ gui_chat_prefix_build (); /* init clipboard buffer */ gui_input_clipboard = NULL; /* create Gtk widgets */ gdk_color_parse ("white", &color_fg); gdk_color_parse ("black", &color_bg); gui_gtk_main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (gui_gtk_main_window), PACKAGE_STRING); g_signal_connect (G_OBJECT (gui_gtk_main_window), "destroy", gtk_main_quit, NULL); gui_gtk_vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (gui_gtk_vbox1); gtk_container_add (GTK_CONTAINER (gui_gtk_main_window), gui_gtk_vbox1); gui_gtk_entry_topic = gtk_entry_new (); gtk_widget_show (gui_gtk_entry_topic); gtk_box_pack_start (GTK_BOX (gui_gtk_vbox1), gui_gtk_entry_topic, FALSE, FALSE, 0); gtk_widget_modify_text (gui_gtk_entry_topic, GTK_STATE_NORMAL, &color_fg); gtk_widget_modify_base (gui_gtk_entry_topic, GTK_STATE_NORMAL, &color_bg); gui_gtk_notebook1 = gtk_notebook_new (); gtk_widget_show (gui_gtk_notebook1); gtk_box_pack_start (GTK_BOX (gui_gtk_vbox1), gui_gtk_notebook1, TRUE, TRUE, 0); gtk_notebook_set_tab_pos (GTK_NOTEBOOK (gui_gtk_notebook1), GTK_POS_BOTTOM); gui_gtk_vbox2 = gtk_vbox_new (FALSE, 0); gtk_widget_show (gui_gtk_vbox2); gtk_container_add (GTK_CONTAINER (gui_gtk_notebook1), gui_gtk_vbox2); gui_gtk_hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (gui_gtk_hbox1); gtk_box_pack_start (GTK_BOX (gui_gtk_vbox2), gui_gtk_hbox1, TRUE, TRUE, 0); gui_gtk_hpaned1 = gtk_hpaned_new (); gtk_widget_show (gui_gtk_hpaned1); gtk_box_pack_start (GTK_BOX (gui_gtk_hbox1), gui_gtk_hpaned1, TRUE, TRUE, 0); gtk_paned_set_position (GTK_PANED (gui_gtk_hpaned1), 0); gui_gtk_scrolledwindow_chat = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (gui_gtk_scrolledwindow_chat); gtk_paned_pack1 (GTK_PANED (gui_gtk_hpaned1), gui_gtk_scrolledwindow_chat, FALSE, TRUE); //gtk_box_pack_start (GTK_PANED (hpaned1), scrolledwindow_chat, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (gui_gtk_scrolledwindow_chat), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_widget_modify_text (gui_gtk_scrolledwindow_chat, GTK_STATE_NORMAL, &color_fg); gtk_widget_modify_base (gui_gtk_scrolledwindow_chat, GTK_STATE_NORMAL, &color_bg); gui_gtk_scrolledwindow_nick = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (gui_gtk_scrolledwindow_nick); gtk_paned_pack2 (GTK_PANED (gui_gtk_hpaned1), gui_gtk_scrolledwindow_nick, FALSE, TRUE); //gtk_box_pack_start (GTK_PANED (hpaned1), scrolledwindow_nick, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (gui_gtk_scrolledwindow_nick), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_widget_modify_text (gui_gtk_scrolledwindow_nick, GTK_STATE_NORMAL, &color_fg); gtk_widget_modify_base (gui_gtk_scrolledwindow_nick, GTK_STATE_NORMAL, &color_bg); gui_gtk_entry_input = gtk_entry_new (); gtk_widget_show (gui_gtk_entry_input); gtk_box_pack_start (GTK_BOX (gui_gtk_vbox2), gui_gtk_entry_input, FALSE, FALSE, 0); gtk_widget_modify_text (gui_gtk_entry_input, GTK_STATE_NORMAL, &color_fg); gtk_widget_modify_base (gui_gtk_entry_input, GTK_STATE_NORMAL, &color_bg); gui_gtk_label1 = gtk_label_new (_("server")); gtk_widget_show (gui_gtk_label1); gtk_notebook_set_tab_label (GTK_NOTEBOOK (gui_gtk_notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (gui_gtk_notebook1), 0), gui_gtk_label1); gtk_label_set_justify (GTK_LABEL (gui_gtk_label1), GTK_JUSTIFY_LEFT); gtk_widget_show_all (gui_gtk_main_window); gui_init_ok = 0; /* create core buffer */ ptr_buffer = gui_buffer_new (NULL, "weechat", NULL, NULL, NULL, NULL); if (ptr_buffer) { gui_init_ok = 1; /* set title for core buffer */ gui_buffer_set_title (ptr_buffer, "WeeChat " WEECHAT_COPYRIGHT_DATE " - " WEECHAT_WEBSITE); /* create main window (using full space) */ if (gui_window_new (NULL, ptr_buffer, 0, 0, 0, 0, 100, 100)) { gui_current_window = gui_windows; if (CONFIG_BOOLEAN(config_look_set_title)) gui_window_set_title (PACKAGE_NAME " " PACKAGE_VERSION); } /* create bar windows for root bars (they were read from config, but no window was created (GUI was not initialized) */ for (ptr_bar = gui_bars; ptr_bar; ptr_bar = ptr_bar->next_bar) { if ((CONFIG_INTEGER(ptr_bar->options[GUI_BAR_OPTION_TYPE]) == GUI_BAR_TYPE_ROOT) && (!ptr_bar->bar_window)) { gui_bar_window_new (ptr_bar, NULL); } } for (ptr_bar_win = gui_windows->bar_windows; ptr_bar_win; ptr_bar_win = ptr_bar_win->next_bar_window) { gui_bar_window_calculate_pos_size (ptr_bar_win, gui_windows); gui_bar_window_create_win (ptr_bar_win); } } }
int gui_chat_hsignal_quote_line_cb (void *data, const char *signal, struct t_hashtable *hashtable) { const char *time, *prefix, *message, *date, *nick, *tags; unsigned int length_time, length_prefix, length_message, length; char *str, *ptr_str_time, *custom_nick_prefix; static char str_time[128]; struct tm local_time; int tags_count, i, custom_nick_ok = 0; char **tags_array; /* make C compiler happy */ (void) data; if (!gui_current_window->buffer->input) return WEECHAT_RC_OK; if (strstr(signal, "time")) { if (!CONFIG_STRING(config_look_quote_time_format) || !CONFIG_STRING(config_look_quote_time_format)[0]) time = hashtable_get (hashtable, "_chat_line_time"); else { date = hashtable_get (hashtable, "_chat_line_date"); if (date && date[0] && strptime (date, "%s", &local_time) && mktime(&local_time) != 0) { str_time[0] = '\0'; strftime (str_time, sizeof (str_time), CONFIG_STRING(config_look_quote_time_format), &local_time); length_time = strlen(str_time); ptr_str_time = malloc (length_time); strncpy (ptr_str_time, str_time, length_time); time = ptr_str_time; } else time = NULL; } } else time = NULL; prefix = (strstr (signal, "prefix")) ? hashtable_get (hashtable, "_chat_line_prefix") : NULL; message = hashtable_get (hashtable, "_chat_line_message"); if (!message) return WEECHAT_RC_OK; length_time = (time) ? strlen (time) : 0; length_prefix = (prefix) ? strlen (prefix) : 0; length_message = strlen (message); nick = hashtable_get (hashtable, "_chat_line_nick"); tags = hashtable_get (hashtable, "_chat_line_tags"); if (prefix && nick && nick[0] && CONFIG_STRING(config_look_quote_nick_format) && CONFIG_STRING(config_look_quote_nick_format)[0]) { tags_array = string_split (tags, ",", 0, 0, &tags_count); if (tags_array) { for (i = 0; i < tags_count; i++) { if (!strcmp (tags_array[i], "irc_privmsg")) custom_nick_ok = 1; else if (!strcmp (tags_array[i], "irc_action")) { custom_nick_ok = 0; break; } } string_free_split(tags_array); if (custom_nick_ok) { custom_nick_prefix = malloc (255); length_prefix = snprintf (custom_nick_prefix, sizeof (custom_nick_prefix), CONFIG_STRING(config_look_quote_nick_format), nick); if (length_prefix >= sizeof (custom_nick_prefix)) { custom_nick_prefix = realloc (custom_nick_prefix, length_prefix + 1); snprintf (custom_nick_prefix, length_prefix, CONFIG_STRING(config_look_quote_nick_format), nick); } } } } length = length_time + 1 + length_prefix + 1 + strlen (CONFIG_STRING(config_look_prefix_suffix)) + 1 + length_message + 1 + 1; str = malloc (length); if (str) { if (custom_nick_ok) { snprintf (str, length, "%s%s%s%s%s ", (time) ? time : "", (time) ? " " : "", (prefix) ? custom_nick_prefix : "", (prefix) ? " " : "", message); } else { snprintf (str, length, "%s%s%s%s%s%s%s ", (time) ? time : "", (time && !(prefix && prefix[0] == ' ')) ? " " : "", (prefix) ? prefix : "", (prefix && prefix[0]) ? " " : "", ((time || prefix) && CONFIG_BOOLEAN(config_look_quote_show_prefix_suffix)) ? CONFIG_STRING(config_look_prefix_suffix) : "", ((time || prefix) && CONFIG_BOOLEAN(config_look_quote_show_prefix_suffix) && CONFIG_STRING(config_look_prefix_suffix) && CONFIG_STRING(config_look_prefix_suffix)[0]) ? " " : "", message); } gui_input_insert_string (gui_current_window->buffer, str, -1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer, 1, /* save undo */ 1); /* stop completion */ free (str); } return WEECHAT_RC_OK; }