void gui_mouse_event_init () { gui_mouse_event_pending = 1; if (gui_mouse_event_timer) unhook (gui_mouse_event_timer); gui_mouse_event_timer = hook_timer (NULL, CONFIG_INTEGER(config_look_mouse_timer_delay), 0, 1, &gui_mouse_event_timer_cb, NULL); }
int gui_color_get_pair (int fg, int bg) { int index; /* only one color when displaying terminal colors */ if (gui_color_use_term_colors) return COLOR_WHITE; /* if invalid color, use default fg/bg */ if (fg > gui_color_term_colors) fg = -1; if (bg > gui_color_term_colors) bg = -1; /* compute index for gui_color_pairs with foreground and background */ index = ((bg + 1) * (gui_color_term_colors + 2)) + (fg + 1); /* pair not allocated for this fg/bg? */ if (gui_color_pairs[index] == 0) { if (gui_color_pairs_used >= gui_color_num_pairs) { /* oh no, no more pair available! */ if (!gui_color_warning_pairs_full && (CONFIG_INTEGER(config_look_color_pairs_auto_reset) < 0)) { /* display warning if auto reset of pairs is disabled */ hook_timer (NULL, 1, 0, 1, &gui_color_timer_warning_pairs_full, NULL); gui_color_warning_pairs_full = 1; } return 1; } /* create a new pair if no pair exists for this fg/bg */ gui_color_pairs_used++; gui_color_pairs[index] = gui_color_pairs_used; init_pair (gui_color_pairs_used, fg, bg); if ((gui_color_num_pairs > 1) && !gui_color_pairs_auto_reset_pending && (CONFIG_INTEGER(config_look_color_pairs_auto_reset) >= 0) && (gui_color_num_pairs - gui_color_pairs_used <= CONFIG_INTEGER(config_look_color_pairs_auto_reset))) { gui_color_pairs_auto_reset = 1; } gui_color_buffer_refresh_needed = 1; } return gui_color_pairs[index]; }
void gui_color_switch_colors () { if (gui_color_hook_timer) { unhook (gui_color_hook_timer); gui_color_hook_timer = NULL; } /* * when we press alt-c many times quickly, this just adds some time for * display of terminal colors */ if (gui_color_use_term_colors && (gui_color_timer > 0) && (gui_color_timer % 10 == 0)) { if (gui_color_timer < 120) gui_color_timer += 10; gui_color_buffer_display_timer (); } else { gui_color_use_term_colors ^= 1; if (gui_color_use_term_colors) gui_color_init_pairs_terminal (); else gui_color_init_pairs_weechat (); gui_color_buffer_refresh_needed = 1; gui_window_ask_refresh (1); if (gui_color_use_term_colors) gui_color_timer = GUI_COLOR_TIMER_TERM_COLORS; } if (gui_color_use_term_colors) { gui_color_hook_timer = hook_timer (NULL, 1000, 0, 0, &gui_color_timer_cb, NULL); } }
void network_connect_with_fork (struct t_hook *hook_connect) { int child_pipe[2]; #ifdef HAVE_GNUTLS int rc; const char *pos_error; #endif pid_t pid; #ifdef HAVE_GNUTLS /* initialize GnuTLS if SSL asked */ if (HOOK_CONNECT(hook_connect, gnutls_sess)) { if (gnutls_init (HOOK_CONNECT(hook_connect, gnutls_sess), GNUTLS_CLIENT) != GNUTLS_E_SUCCESS) { (void) (HOOK_CONNECT(hook_connect, callback)) (hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR, 0, NULL, NULL); unhook (hook_connect); return; } rc = gnutls_priority_set_direct (*HOOK_CONNECT(hook_connect, gnutls_sess), HOOK_CONNECT(hook_connect, gnutls_priorities), &pos_error); if (rc != GNUTLS_E_SUCCESS) { (void) (HOOK_CONNECT(hook_connect, callback)) (hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR, 0, _("invalid priorities"), NULL); unhook (hook_connect); return; } gnutls_credentials_set (*HOOK_CONNECT(hook_connect, gnutls_sess), GNUTLS_CRD_CERTIFICATE, gnutls_xcred); gnutls_transport_set_ptr (*HOOK_CONNECT(hook_connect, gnutls_sess), (gnutls_transport_ptr) ((unsigned long) HOOK_CONNECT(hook_connect, sock))); } #endif /* create pipe for child process */ if (pipe (child_pipe) < 0) { (void) (HOOK_CONNECT(hook_connect, callback)) (hook_connect->callback_data, WEECHAT_HOOK_CONNECT_MEMORY_ERROR, 0, NULL, NULL); unhook (hook_connect); return; } HOOK_CONNECT(hook_connect, child_read) = child_pipe[0]; HOOK_CONNECT(hook_connect, child_write) = child_pipe[1]; switch (pid = fork ()) { /* fork failed */ case -1: (void) (HOOK_CONNECT(hook_connect, callback)) (hook_connect->callback_data, WEECHAT_HOOK_CONNECT_MEMORY_ERROR, 0, NULL, NULL); unhook (hook_connect); return; /* child process */ case 0: setuid (getuid ()); close (HOOK_CONNECT(hook_connect, child_read)); network_connect_child (hook_connect); _exit (EXIT_SUCCESS); } /* parent process */ HOOK_CONNECT(hook_connect, child_pid) = pid; close (HOOK_CONNECT(hook_connect, child_write)); HOOK_CONNECT(hook_connect, child_write) = -1; HOOK_CONNECT(hook_connect, hook_child_timer) = hook_timer (hook_connect->plugin, CONFIG_INTEGER(config_network_connection_timeout) * 1000, 0, 1, &network_connect_child_timer_cb, hook_connect); HOOK_CONNECT(hook_connect, hook_fd) = hook_fd (hook_connect->plugin, HOOK_CONNECT(hook_connect, child_read), 1, 0, 0, &network_connect_child_read_cb, hook_connect); }
int network_connect_child_read_cb (void *arg_hook_connect, int fd) { struct t_hook *hook_connect; char buffer[1], buf_size[6], *cb_error, *cb_ip_address, *error; int num_read; long size_msg; #ifdef HAVE_GNUTLS int rc, direction; #endif /* make C compiler happy */ (void) fd; hook_connect = (struct t_hook *)arg_hook_connect; cb_error = NULL; cb_ip_address = NULL; num_read = read (HOOK_CONNECT(hook_connect, child_read), buffer, sizeof (buffer)); if (num_read > 0) { if (buffer[0] - '0' == WEECHAT_HOOK_CONNECT_OK) { /* connection ok, read IP address */ buf_size[5] = '\0'; num_read = read (HOOK_CONNECT(hook_connect, child_read), buf_size, 5); if (num_read == 5) { error = NULL; size_msg = strtol (buf_size, &error, 10); if (error && !error[0] && (size_msg > 0)) { cb_ip_address = malloc (size_msg + 1); if (cb_ip_address) { num_read = read (HOOK_CONNECT(hook_connect, child_read), cb_ip_address, size_msg); if (num_read == size_msg) cb_ip_address[size_msg] = '\0'; else { free (cb_ip_address); cb_ip_address = NULL; } } } } #ifdef HAVE_GNUTLS if (HOOK_CONNECT(hook_connect, gnutls_sess)) { /* * the socket needs to be non-blocking since the call to * gnutls_handshake can block */ HOOK_CONNECT(hook_connect, handshake_fd_flags) = fcntl (HOOK_CONNECT(hook_connect, sock), F_GETFL); if (HOOK_CONNECT(hook_connect, handshake_fd_flags) == -1) HOOK_CONNECT(hook_connect, handshake_fd_flags) = 0; fcntl (HOOK_CONNECT(hook_connect, sock), F_SETFL, HOOK_CONNECT(hook_connect, handshake_fd_flags) | O_NONBLOCK); gnutls_transport_set_ptr (*HOOK_CONNECT(hook_connect, gnutls_sess), (gnutls_transport_ptr) ((ptrdiff_t) HOOK_CONNECT(hook_connect, sock))); if (HOOK_CONNECT(hook_connect, gnutls_dhkey_size) > 0) { gnutls_dh_set_prime_bits (*HOOK_CONNECT(hook_connect, gnutls_sess), (unsigned int) HOOK_CONNECT(hook_connect, gnutls_dhkey_size)); } rc = gnutls_handshake (*HOOK_CONNECT(hook_connect, gnutls_sess)); if ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)) { /* * gnutls was unable to proceed with the handshake without * blocking: non fatal error, we just have to wait for an * event about handshake */ unhook (HOOK_CONNECT(hook_connect, hook_fd)); HOOK_CONNECT(hook_connect, hook_fd) = NULL; direction = gnutls_record_get_direction (*HOOK_CONNECT(hook_connect, gnutls_sess)); HOOK_CONNECT(hook_connect, handshake_ip_address) = cb_ip_address; HOOK_CONNECT(hook_connect, handshake_hook_fd) = hook_fd (hook_connect->plugin, HOOK_CONNECT(hook_connect, sock), (!direction ? 1 : 0), (direction ? 1 : 0), 0, &network_connect_gnutls_handshake_fd_cb, hook_connect); HOOK_CONNECT(hook_connect, handshake_hook_timer) = hook_timer (hook_connect->plugin, CONFIG_INTEGER(config_network_gnutls_handshake_timeout) * 1000, 0, 1, &network_connect_gnutls_handshake_timer_cb, hook_connect); return WEECHAT_RC_OK; } else if (rc != GNUTLS_E_SUCCESS) { (void) (HOOK_CONNECT(hook_connect, callback)) (hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR, rc, gnutls_strerror (rc), cb_ip_address); unhook (hook_connect); if (cb_ip_address) free (cb_ip_address); return WEECHAT_RC_OK; } fcntl (HOOK_CONNECT(hook_connect, sock), F_SETFL, HOOK_CONNECT(hook_connect, handshake_fd_flags)); #if LIBGNUTLS_VERSION_NUMBER < 0x02090a /* * gnutls only has the gnutls_certificate_set_verify_function() * function since version 2.9.10. We need to call our verify * function manually after the handshake for old gnutls versions */ if (hook_connect_gnutls_verify_certificates (*HOOK_CONNECT(hook_connect, gnutls_sess)) != 0) { (void) (HOOK_CONNECT(hook_connect, callback)) (hook_connect->callback_data, WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR, rc, "Error in the certificate.", cb_ip_address); unhook (hook_connect); if (cb_ip_address) free (cb_ip_address); return WEECHAT_RC_OK; } #endif } #endif } else { /* connection error, read error */ buf_size[5] = '\0'; num_read = read (HOOK_CONNECT(hook_connect, child_read), buf_size, 5); if (num_read == 5) { error = NULL; size_msg = strtol (buf_size, &error, 10); if (error && !error[0] && (size_msg > 0)) { cb_error = malloc (size_msg + 1); if (cb_error) { num_read = read (HOOK_CONNECT(hook_connect, child_read), cb_error, size_msg); if (num_read == size_msg) cb_error[size_msg] = '\0'; else { free (cb_error); cb_error = NULL; } } } } } (void) (HOOK_CONNECT(hook_connect, callback)) (hook_connect->callback_data, buffer[0] - '0', 0, cb_error, cb_ip_address); unhook (hook_connect); } if (cb_error) free (cb_error); if (cb_ip_address) free (cb_ip_address); return WEECHAT_RC_OK; }