void trigger_callback_run_command (struct t_trigger *trigger, struct t_gui_buffer *buffer, struct t_hashtable *pointers, struct t_hashtable *extra_vars, int display_monitor) { char *command_eval; int i; if (!trigger->commands) return; if (!buffer) { buffer = weechat_buffer_search_main (); if (!buffer) return; } for (i = 0; trigger->commands[i]; i++) { command_eval = weechat_string_eval_expression (trigger->commands[i], pointers, extra_vars, NULL); if (command_eval) { /* display debug info on trigger buffer */ if (trigger_buffer && display_monitor) { weechat_printf_tags (trigger_buffer, "no_trigger", _("%s running command %s\"%s%s%s\"%s " "on buffer %s%s%s"), "\t", weechat_color ("chat_delimiters"), weechat_color ("reset"), command_eval, weechat_color ("chat_delimiters"), weechat_color ("reset"), weechat_color ("chat_buffer"), weechat_buffer_get_string (buffer, "full_name"), weechat_color ("reset")); } weechat_command (buffer, command_eval); trigger->hook_count_cmd++; } free (command_eval); } }
void relay_weechat_alloc (struct t_relay_client *client) { struct t_relay_weechat_data *weechat_data; char *password; password = weechat_string_eval_expression (weechat_config_string (relay_config_network_password), NULL, NULL, NULL); client->protocol_data = malloc (sizeof (*weechat_data)); if (client->protocol_data) { RELAY_WEECHAT_DATA(client, password_ok) = (password && password[0]) ? 0 : 1; RELAY_WEECHAT_DATA(client, compression) = RELAY_WEECHAT_COMPRESSION_ZLIB; RELAY_WEECHAT_DATA(client, buffers_sync) = weechat_hashtable_new (32, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_INTEGER, NULL, NULL); RELAY_WEECHAT_DATA(client, hook_signal_buffer) = NULL; RELAY_WEECHAT_DATA(client, hook_hsignal_nicklist) = NULL; RELAY_WEECHAT_DATA(client, hook_signal_upgrade) = NULL; RELAY_WEECHAT_DATA(client, buffers_nicklist) = weechat_hashtable_new (32, WEECHAT_HASHTABLE_POINTER, WEECHAT_HASHTABLE_POINTER, NULL, NULL); weechat_hashtable_set_pointer (RELAY_WEECHAT_DATA(client, buffers_nicklist), "callback_free_value", &relay_weechat_free_buffers_nicklist); RELAY_WEECHAT_DATA(client, hook_timer_nicklist) = NULL; relay_weechat_hook_signals (client); } if (password) free (password); }
int trigger_callback_check_conditions (struct t_trigger *trigger, struct t_hashtable *pointers, struct t_hashtable *extra_vars) { const char *conditions; char *value; int rc; conditions = weechat_config_string (trigger->options[TRIGGER_OPTION_CONDITIONS]); if (!conditions || !conditions[0]) return 1; value = weechat_string_eval_expression (conditions, pointers, extra_vars, trigger_callback_hashtable_options); rc = (value && (strcmp (value, "1") == 0)); if (value) free (value); return rc; }
void trigger_callback_replace_regex (struct t_trigger *trigger, struct t_hashtable *pointers, struct t_hashtable *extra_vars, int display_monitor) { char *value; const char *ptr_key, *ptr_value; int i, pointers_allocated; pointers_allocated = 0; if (trigger->regex_count == 0) return; if (!pointers) { pointers = weechat_hashtable_new (32, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_POINTER, NULL, NULL); if (!pointers) return; pointers_allocated = 1; } for (i = 0; i < trigger->regex_count; i++) { /* if regex is not set (invalid), skip it */ if (!trigger->regex[i].regex) continue; ptr_key = (trigger->regex[i].variable) ? trigger->regex[i].variable : trigger_hook_regex_default_var[weechat_config_integer (trigger->options[TRIGGER_OPTION_HOOK])]; if (!ptr_key || !ptr_key[0]) { if (trigger_buffer && display_monitor) { weechat_printf_tags (trigger_buffer, "no_trigger", "\t regex %d: %s", i + 1, _("no variable")); } continue; } ptr_value = weechat_hashtable_get (extra_vars, ptr_key); if (!ptr_value) { if (trigger_buffer && display_monitor) { weechat_printf_tags (trigger_buffer, "no_trigger", "\t regex %d (%s): %s", i + 1, ptr_key, _("empty variable")); } continue; } weechat_hashtable_set (pointers, "regex", trigger->regex[i].regex); weechat_hashtable_set (trigger_callback_hashtable_options_regex, "regex_replace", trigger->regex[i].replace_escaped); value = weechat_string_eval_expression ( ptr_value, pointers, extra_vars, trigger_callback_hashtable_options_regex); if (value) { /* display debug info on trigger buffer */ if (trigger_buffer && display_monitor) { weechat_printf_tags (trigger_buffer, "no_trigger", "\t regex %d %s(%s%s%s)%s: " "%s\"%s%s%s\"", i + 1, weechat_color ("chat_delimiters"), weechat_color ("reset"), ptr_key, weechat_color ("chat_delimiters"), weechat_color ("reset"), weechat_color ("chat_delimiters"), weechat_color ("reset"), value, weechat_color ("chat_delimiters")); } weechat_hashtable_set (extra_vars, ptr_key, value); free (value); } } if (pointers_allocated) weechat_hashtable_free (pointers); else weechat_hashtable_remove (pointers, "regex"); }
void trigger_callback_replace_regex (struct t_trigger *trigger, struct t_hashtable *pointers, struct t_hashtable *extra_vars, int display_monitor) { char *value, *replace_eval; const char *ptr_key, *ptr_value; int i; if (trigger->regex_count == 0) return; for (i = 0; i < trigger->regex_count; i++) { /* if regex is not set (invalid), skip it */ if (!trigger->regex[i].regex) continue; ptr_key = (trigger->regex[i].variable) ? trigger->regex[i].variable : trigger_hook_regex_default_var[weechat_config_integer (trigger->options[TRIGGER_OPTION_HOOK])]; if (!ptr_key || !ptr_key[0]) { if (trigger_buffer && display_monitor) { weechat_printf_tags (trigger_buffer, "no_trigger", "\t regex %d: %s", i + 1, _("no variable")); } continue; } ptr_value = weechat_hashtable_get (extra_vars, ptr_key); if (!ptr_value) { if (trigger_buffer && display_monitor) { weechat_printf_tags (trigger_buffer, "no_trigger", "\t regex %d (%s): %s", i + 1, ptr_key, _("empty variable")); } continue; } replace_eval = weechat_string_eval_expression ( trigger->regex[i].replace_escaped, pointers, extra_vars, NULL); if (replace_eval) { value = weechat_string_replace_regex (ptr_value, trigger->regex[i].regex, replace_eval, '$', NULL, NULL); if (value) { /* display debug info on trigger buffer */ if (trigger_buffer && display_monitor) { weechat_printf_tags (trigger_buffer, "no_trigger", "\t regex %d %s(%s%s%s)%s: " "%s\"%s%s%s\"", i + 1, weechat_color ("chat_delimiters"), weechat_color ("reset"), ptr_key, weechat_color ("chat_delimiters"), weechat_color ("reset"), weechat_color ("chat_delimiters"), weechat_color ("reset"), value, weechat_color ("chat_delimiters")); } weechat_hashtable_set (extra_vars, ptr_key, value); free (value); } free (replace_eval); } } }
int relay_server_sock_cb (const void *pointer, void *data, int fd) { struct t_relay_server *server; struct sockaddr_in client_addr; struct sockaddr_in6 client_addr6; struct sockaddr_un client_addr_unix; socklen_t client_addr_size; void *ptr_addr; int client_fd, flags, set, max_clients, num_clients_on_port; char ipv4_address[INET_ADDRSTRLEN + 1], ipv6_address[INET6_ADDRSTRLEN + 1]; char unix_address[sizeof (client_addr_unix.sun_path)]; char *ptr_ip_address, *relay_password, *relay_totp_secret; /* make C compiler happy */ (void) data; (void) fd; client_fd = -1; relay_password = NULL; relay_totp_secret = NULL; server = (struct t_relay_server *)pointer; if (server->ipv6) { ptr_addr = &client_addr6; client_addr_size = sizeof (struct sockaddr_in6); } else if (server->ipv4) { ptr_addr = &client_addr; client_addr_size = sizeof (struct sockaddr_in); } else { ptr_addr = &client_addr_unix; client_addr_size = sizeof (struct sockaddr_un); } memset (ptr_addr, 0, client_addr_size); client_fd = accept (server->sock, (struct sockaddr *)ptr_addr, &client_addr_size); if (client_fd < 0) { if (server->unix_socket) { weechat_printf (NULL, _("%s%s: cannot accept client on path %s (%s): " "error %d %s"), weechat_prefix ("error"), RELAY_PLUGIN_NAME, server->path, server->protocol_string, errno, strerror (errno)); } else { weechat_printf (NULL, _("%s%s: cannot accept client on port %d (%s): " "error %d %s"), weechat_prefix ("error"), RELAY_PLUGIN_NAME, server->port, server->protocol_string, errno, strerror (errno)); } goto error; } /* check if relay password is empty and if it is not allowed */ relay_password = weechat_string_eval_expression ( weechat_config_string (relay_config_network_password), NULL, NULL, NULL); if (!weechat_config_boolean (relay_config_network_allow_empty_password) && (!relay_password || !relay_password[0])) { weechat_printf (NULL, _("%s%s: cannot accept client because relay password " "is empty, and option " "relay.network.allow_empty_password is off"), weechat_prefix ("error"), RELAY_PLUGIN_NAME); goto error; } if (server->protocol == RELAY_PROTOCOL_WEECHAT) { /* * TOTP can be enabled only as second factor, in addition to the * password (only for weechat protocol) */ relay_totp_secret = weechat_string_eval_expression ( weechat_config_string (relay_config_network_totp_secret), NULL, NULL, NULL); if ((!relay_password || !relay_password[0]) && relay_totp_secret && relay_totp_secret[0]) { weechat_printf (NULL, _("%s%s: Time-based One-Time Password (TOTP) " "can be enabled only as second factor, if the " "password is not empty"), weechat_prefix ("error"), RELAY_PLUGIN_NAME); goto error; } if (!relay_config_check_network_totp_secret ( NULL, NULL, NULL, weechat_config_string (relay_config_network_totp_secret))) { goto error; } } /* check if we have reached the max number of clients on this port */ max_clients = weechat_config_integer (relay_config_network_max_clients); if (max_clients > 0) { num_clients_on_port = relay_client_count_active_by_port (server->port); if (num_clients_on_port >= max_clients) { weechat_printf ( NULL, NG_("%s%s: client not allowed (max %d client is " "allowed at same time)", "%s%s: client not allowed (max %d clients are " "allowed at same time)", max_clients), weechat_prefix ("error"), RELAY_PLUGIN_NAME, max_clients); goto error; } } /* get the IP address */ ptr_ip_address = NULL; if (server->ipv6) { if (inet_ntop (AF_INET6, &(client_addr6.sin6_addr), ipv6_address, INET6_ADDRSTRLEN)) { ptr_ip_address = ipv6_address; if (strncmp (ptr_ip_address, "::ffff:", 7) == 0) { /* actually an IPv4-mapped IPv6 address, so skip "::ffff:" */ ptr_ip_address += 7; } } } else if (server->ipv4) { if (inet_ntop (AF_INET, &(client_addr.sin_addr), ipv4_address, INET_ADDRSTRLEN)) { ptr_ip_address = ipv4_address; } } else { strncpy (unix_address, client_addr_unix.sun_path, sizeof (unix_address)); ptr_ip_address = unix_address; } /* check if IP is allowed, if not, just close socket */ if (relay_config_regex_allowed_ips && (regexec (relay_config_regex_allowed_ips, ptr_ip_address, 0, NULL, 0) != 0)) { if (weechat_relay_plugin->debug >= 1) { weechat_printf (NULL, _("%s%s: IP address \"%s\" not allowed for relay"), weechat_prefix ("error"), RELAY_PLUGIN_NAME, ptr_ip_address); } goto error; } /* set non-blocking mode for socket */ flags = fcntl (client_fd, F_GETFL); if (flags == -1) flags = 0; fcntl (client_fd, F_SETFL, flags | O_NONBLOCK); /* set socket option SO_REUSEADDR */ set = 1; if (setsockopt (client_fd, SOL_SOCKET, SO_REUSEADDR, (void *) &set, sizeof (set)) < 0) { weechat_printf (NULL, _("%s%s: cannot set socket option \"%s\" to %d: " "error %d %s"), weechat_prefix ("error"), RELAY_PLUGIN_NAME, "SO_REUSEADDR", set, errno, strerror (errno)); goto error; } /* add the client */ relay_client_new (client_fd, ptr_ip_address, server); goto end; error: if (client_fd >= 0) close (client_fd); end: if (relay_password) free (relay_password); if (relay_totp_secret) free (relay_totp_secret); return WEECHAT_RC_OK; }