struct t_rmodifier * rmodifier_new_with_string (const char *name, const char *value) { struct t_rmodifier *new_rmodifier; char *pos1, *pos2, *modifiers, *str_regex; new_rmodifier = NULL; pos1 = strchr (value, ';'); pos2 = rindex (value, ';'); if (pos1 && pos2 && (pos2 > pos1)) { modifiers = weechat_strndup (value, pos1 - value); str_regex = weechat_strndup (pos1 + 1, pos2 - (pos1 + 1)); if (modifiers && str_regex) { new_rmodifier = rmodifier_new (name, modifiers, str_regex, pos2 + 1); } if (modifiers) free (modifiers); if (str_regex) free (str_regex); } return new_rmodifier; }
void irc_redirect_init_command (struct t_irc_redirect *redirect, const char *command) { char *pos; if (!redirect) return; if (command) { pos = strchr (command, '\r'); if (!pos) pos = strchr (command, '\n'); if (pos) redirect->command = weechat_strndup (command, pos - command); else redirect->command = strdup (command); } else redirect->command = NULL; redirect->assigned_to_command = 1; redirect->start_time = time (NULL); if (weechat_irc_plugin->debug >= 2) { weechat_printf ( redirect->server->buffer, _("%s: starting redirection for command \"%s\" on server \"%s\" " "(redirect pattern: \"%s\")"), IRC_PLUGIN_NAME, redirect->command, redirect->server->name, redirect->pattern); } }
/** * Called when a profile option is read. */ int twc_config_profile_read_callback(void *data, struct t_config_file *config_file, struct t_config_section *section, const char *option_name, const char *value) { int rc = WEECHAT_CONFIG_OPTION_SET_ERROR; if (option_name) { char *dot_pos = strrchr(option_name, '.'); if (dot_pos) { char *profile_name = weechat_strndup(option_name, dot_pos-option_name); char *option_name = dot_pos + 1; if (profile_name) { int option_index = twc_config_profile_option_search(option_name); if (option_index >= 0) { struct t_twc_profile *profile = twc_profile_search_name(profile_name); if (!profile) profile = twc_profile_new(profile_name); if (profile) { rc = weechat_config_option_set(profile->options[option_index], value, 1); } else { weechat_printf(NULL, "%s%s: error creating profile \"%s\"", weechat_prefix("error"), weechat_plugin->name, profile_name); } } free(profile_name); } } } if (rc == WEECHAT_CONFIG_OPTION_SET_ERROR) { weechat_printf(NULL, "%s%s: error creating profile option \"%s\"", weechat_prefix("error"), weechat_plugin->name, option_name); } return rc; }
char * irc_bar_item_buffer_modes (void *data, struct t_gui_bar_item *item, struct t_gui_window *window, struct t_gui_buffer *buffer, struct t_hashtable *extra_info) { char modes[128], *modes_without_args; const char *pos_space, *pos_key; int part_from_channel; struct t_irc_server *server; struct t_irc_channel *channel; /* make C compiler happy */ (void) data; (void) item; (void) window; (void) extra_info; if (!buffer) return NULL; modes[0] = '\0'; irc_buffer_get_server_and_channel (buffer, &server, &channel); if (!channel) return NULL; part_from_channel = ((channel->type == IRC_CHANNEL_TYPE_CHANNEL) && !channel->nicks); if (!part_from_channel && channel->modes && channel->modes[0] && (strcmp (channel->modes, "+") != 0)) { modes_without_args = NULL; if (weechat_config_boolean (irc_config_look_item_channel_modes_hide_key)) { pos_space = strchr(channel->modes, ' '); if (pos_space) { pos_key = strchr(channel->modes, 'k'); if (pos_key && (pos_key < pos_space)) { modes_without_args = weechat_strndup (channel->modes, pos_space - channel->modes); } } } snprintf (modes, sizeof (modes), "%s%s", IRC_COLOR_ITEM_CHANNEL_MODES, (modes_without_args) ? modes_without_args : channel->modes); if (modes_without_args) free (modes_without_args); return strdup (modes); } return NULL; }
char * rmodifier_replace_groups (const char *string, regmatch_t regex_match[], const char *groups) { char *result, *result2, *str_group, *string_to_add; const char *ptr_groups; int length, num_group; length = 1; result = malloc (length); if (!result) return NULL; result[0] = '\0'; ptr_groups = groups; while (ptr_groups && ptr_groups[0]) { if ((ptr_groups[0] >= '1') && (ptr_groups[0] <= '9')) { num_group = ptr_groups[0] - '0'; if (regex_match[num_group].rm_so >= 0) { str_group = weechat_strndup (string + regex_match[num_group].rm_so, regex_match[num_group].rm_eo -regex_match[num_group].rm_so); if (str_group) { string_to_add = NULL; if (ptr_groups[1] == '*') string_to_add = rmodifier_hide_string (str_group); else string_to_add = strdup (str_group); if (string_to_add) { length += strlen (string_to_add); result2 = realloc (result, length); if (!result2) { if (result) free (result); return NULL; } result = result2; strcat (result, string_to_add); free (string_to_add); } free (str_group); } } } ptr_groups = weechat_utf8_next_char (ptr_groups); } return result; }
void weechat_aspell_enchant_dict_describe_cb (const char *lang_tag, const char *provider_name, const char *provider_desc, const char *provider_file, void *user_data) { char *country, *lang, *pos, *iso; char str_dict[256]; /* make C compiler happy */ (void) provider_name; (void) provider_desc; (void) provider_file; (void) user_data; lang = NULL; country = NULL; pos = strchr (lang_tag, '_'); if (pos) { iso = weechat_strndup (lang_tag, pos - lang_tag); if (iso) { lang = weechat_aspell_command_iso_to_lang (iso); country = weechat_aspell_command_iso_to_country (pos + 1); free (iso); } } else lang = weechat_aspell_command_iso_to_lang ((char *)lang_tag); if (lang) { if (country) { snprintf (str_dict, sizeof (str_dict), "%-22s %s (%s)", lang_tag, lang, country); } else { snprintf (str_dict, sizeof (str_dict), "%-22s %s", lang_tag, lang); } weechat_printf (NULL, " %s", str_dict); } if (lang) free (lang); if (country) free (country); }
char * irc_ctcp_dcc_filename_without_quotes (const char *filename) { int length; length = strlen (filename); if (length > 0) { if ((filename[0] == '\"') && (filename[length - 1] == '\"')) return weechat_strndup (filename + 1, length - 2); } return strdup (filename); }
void alias_string_add_word_range (char **alias, int *length, const char *start, const char *end) { char *word; word = weechat_strndup (start, end - start); if (word) { alias_string_add_word (alias, length, word); free (word); } }
struct t_gui_buffer * relay_weechat_protocol_get_buffer (const char *arg) { struct t_gui_buffer *ptr_buffer; long unsigned int value; int rc; char *pos, *plugin; struct t_hdata *ptr_hdata; ptr_buffer = NULL; if (strncmp (arg, "0x", 2) == 0) { rc = sscanf (arg, "%lx", &value); if ((rc != EOF) && (rc != 0)) ptr_buffer = (struct t_gui_buffer *)value; if (ptr_buffer) { ptr_hdata = weechat_hdata_get ("buffer"); if (!weechat_hdata_check_pointer (ptr_hdata, weechat_hdata_get_list (ptr_hdata, "gui_buffers"), ptr_buffer)) { /* invalid pointer! */ ptr_buffer = NULL; } } } else { pos = strchr (arg, '.'); if (pos) { plugin = weechat_strndup (arg, pos - arg); if (plugin) { ptr_buffer = weechat_buffer_search (plugin, pos + 1); free (plugin); } } } return ptr_buffer; }
void relay_server_get_protocol_args (const char *protocol_and_args, char **protocol, char **protocol_args) { char *pos; pos = strchr (protocol_and_args, '.'); if (pos) { *protocol = weechat_strndup (protocol_and_args, pos - protocol_and_args); *protocol_args = strdup (pos + 1); } else { *protocol = strdup (protocol_and_args); *protocol_args = NULL; } }
void irc_message_parse (struct t_irc_server *server, const char *message, char **tags, char **message_without_tags, char **nick, char **host, char **command, char **channel, char **arguments) { const char *ptr_message, *pos, *pos2, *pos3, *pos4; if (tags) *tags = NULL; if (message_without_tags) *message_without_tags = NULL; if (nick) *nick = NULL; if (host) *host = NULL; if (command) *command = NULL; if (channel) *channel = NULL; if (arguments) *arguments = NULL; if (!message) return; ptr_message = message; /* * we will use this message as example: * * @tags :[email protected] PRIVMSG #channel :hello! */ if (ptr_message[0] == '@') { /* * read tags (they are optional and enabled only if client enabled * a server capability, see: * http://ircv3.atheme.org/specification/message-tags-3.2) */ pos = strchr (ptr_message, ' '); if (pos) { if (tags) *tags = weechat_strndup (message + 1, pos - (message + 1)); ptr_message = pos + 1; while (ptr_message[0] == ' ') { ptr_message++; } } } if (message_without_tags) *message_without_tags = strdup (ptr_message); /* now we have: ptr_message --> ":[email protected] PRIVMSG #channel :hello!" */ if (ptr_message[0] == ':') { /* read host/nick */ pos2 = strchr (ptr_message, '!'); pos = strchr (ptr_message, ' '); if (pos2 && (!pos || pos > pos2)) { if (nick) *nick = weechat_strndup (ptr_message + 1, pos2 - (ptr_message + 1)); } else if (pos) { if (nick) *nick = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); } if (pos) { if (host) *host = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); ptr_message = pos + 1; while (ptr_message[0] == ' ') { ptr_message++; } } } /* now we have: ptr_message --> "PRIVMSG #channel :hello!" */ if (ptr_message[0]) { pos = strchr (ptr_message, ' '); if (pos) { if (command) *command = weechat_strndup (ptr_message, pos - ptr_message); pos++; while (pos[0] == ' ') { pos++; } /* now we have: pos --> "#channel :hello!" */ if (arguments) *arguments = strdup (pos); if (pos[0] != ':') { if (irc_channel_is_channel (server, pos)) { pos2 = strchr (pos, ' '); if (channel) { if (pos2) *channel = weechat_strndup (pos, pos2 - pos); else *channel = strdup (pos); } } else { pos2 = strchr (pos, ' '); if (nick && !*nick) { if (pos2) *nick = weechat_strndup (pos, pos2 - pos); else *nick = strdup (pos); } if (pos2) { pos3 = pos2; pos2++; while (pos2[0] == ' ') { pos2++; } if (irc_channel_is_channel (server, pos2)) { pos4 = strchr (pos2, ' '); if (channel) { if (pos4) *channel = weechat_strndup (pos2, pos4 - pos2); else *channel = strdup (pos2); } } else if (channel && !*channel) { *channel = weechat_strndup (pos, pos3 - pos); } } } } } else { if (command) *command = strdup (ptr_message); } } }
void relay_weechat_msg_add_hdata (struct t_relay_weechat_msg *msg, const char *path, const char *keys) { struct t_hdata *ptr_hdata_head, *ptr_hdata; char *hdata_head, *pos, **list_keys, *keys_types, **list_path; char *path_returned; const char *hdata_name, *array_size; void *pointer, **path_pointers; long unsigned int value; int num_keys, num_path, i, type, pos_count, count, rc; uint32_t count32; hdata_head = NULL; list_keys = NULL; num_keys = 0; keys_types = NULL; list_path = NULL; num_path = 0; path_returned = NULL; /* extract hdata name (head) from path */ pos = strchr (path, ':'); if (!pos) goto end; hdata_head = weechat_strndup (path, pos - path); if (!hdata_head) goto end; ptr_hdata_head = weechat_hdata_get (hdata_head); if (!ptr_hdata_head) goto end; /* split path */ list_path = weechat_string_split (pos + 1, "/", 0, 0, &num_path); if (!list_path) goto end; /* extract pointer from first path (direct pointer or list name) */ pointer = NULL; pos = strchr (list_path[0], '('); if (pos) pos[0] = '\0'; if (strncmp (list_path[0], "0x", 2) == 0) { rc = sscanf (list_path[0], "%lx", &value); if ((rc != EOF) && (rc != 0)) pointer = (void *)value; } else pointer = weechat_hdata_get_list (ptr_hdata_head, list_path[0]); if (pos) pos[0] = '('; if (!pointer) goto end; /* * build string with path where: * - counters are removed * - variable names are replaced by hdata name */ path_returned = malloc (strlen (path) * 2); if (!path_returned) goto end; ptr_hdata = ptr_hdata_head; strcpy (path_returned, hdata_head); hdata_name = hdata_head; for (i = 1; i < num_path; i++) { pos = strchr (list_path[i], '('); if (pos) pos[0] = '\0'; hdata_name = weechat_hdata_get_var_hdata (ptr_hdata, list_path[i]); if (!hdata_name) goto end; ptr_hdata = weechat_hdata_get (hdata_name); if (!ptr_hdata) goto end; strcat (path_returned, "/"); strcat (path_returned, hdata_name); if (pos) pos[0] = '('; } /* split keys */ if (!keys) keys = weechat_hdata_get_string (ptr_hdata, "var_keys"); list_keys = weechat_string_split (keys, ",", 0, 0, &num_keys); if (!list_keys) goto end; /* build string with list of keys with types: "key1:type1,key2:type2,..." */ keys_types = malloc (strlen (keys) + (num_keys * 8) + 1); if (!keys_types) goto end; keys_types[0] = '\0'; for (i = 0; i < num_keys; i++) { type = weechat_hdata_get_var_type (ptr_hdata, list_keys[i]); if ((type >= 0) && (type != WEECHAT_HDATA_OTHER)) { if (keys_types[0]) strcat (keys_types, ","); strcat (keys_types, list_keys[i]); strcat (keys_types, ":"); array_size = weechat_hdata_get_var_array_size_string (ptr_hdata, NULL, list_keys[i]); if (array_size) strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_ARRAY); else { switch (type) { case WEECHAT_HDATA_CHAR: strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_CHAR); break; case WEECHAT_HDATA_INTEGER: strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_INT); break; case WEECHAT_HDATA_LONG: strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_LONG); break; case WEECHAT_HDATA_STRING: strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_STRING); break; case WEECHAT_HDATA_POINTER: strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_POINTER); break; case WEECHAT_HDATA_TIME: strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_TIME); break; case WEECHAT_HDATA_HASHTABLE: strcat (keys_types, RELAY_WEECHAT_MSG_OBJ_HASHTABLE); break; } } } } if (!keys_types[0]) goto end; /* start hdata in message */ relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_HDATA); relay_weechat_msg_add_string (msg, path_returned); relay_weechat_msg_add_string (msg, keys_types); /* "count" will be set later, with number of objects in hdata */ pos_count = msg->data_size; count = 0; relay_weechat_msg_add_int (msg, 0); path_pointers = malloc (sizeof (*path_pointers) * num_path); if (path_pointers) { count = relay_weechat_msg_add_hdata_path (msg, list_path, 0, path_pointers, ptr_hdata_head, pointer, list_keys); free (path_pointers); } count32 = htonl ((uint32_t)count); relay_weechat_msg_set_bytes (msg, pos_count, &count32, 4); end: if (list_keys) weechat_string_free_split (list_keys); if (keys_types) free (keys_types); if (list_path) weechat_string_free_split (list_path); if (path_returned) free (path_returned); if (hdata_head) free (hdata_head); }
int trigger_regex_split (const char *str_regex, int *regex_count, struct t_trigger_regex **regex) { const char *ptr_regex, *pos, *pos_replace, *pos_replace_end; const char *pos_next_regex; char *delimiter, *str_regex_escaped; int rc, index, length_delimiter; struct t_trigger_regex *new_regex; rc = 0; delimiter = NULL; str_regex_escaped = NULL; if (!regex_count || !regex) goto end; /* remove any existing regex */ trigger_regex_free (regex_count, regex); if (!str_regex || !str_regex[0]) goto end; /* min 3 chars, for example: "/a/" */ if (strlen (str_regex) < 3) goto format_error; /* parse regular expressions in the option */ ptr_regex = str_regex; while (ptr_regex && ptr_regex[0]) { if (delimiter) { free (delimiter); delimiter = NULL; } /* search the delimiter (which can be more than one char) */ pos = weechat_utf8_next_char (ptr_regex); while (pos[0] && (weechat_utf8_charcmp (ptr_regex, pos) == 0)) { pos = weechat_utf8_next_char (pos); } if (!pos[0]) goto format_error; delimiter = weechat_strndup (ptr_regex, pos - ptr_regex); if (!delimiter) goto memory_error; length_delimiter = strlen (delimiter); ptr_regex = pos; if (!ptr_regex[0]) goto format_error; /* search the start of replacement string */ pos_replace = strstr (ptr_regex, delimiter); if (!pos_replace) goto format_error; /* search the end of replacement string */ pos_replace_end = strstr (pos_replace + length_delimiter, delimiter); new_regex = realloc (*regex, (*regex_count + 1) * sizeof ((*regex)[0])); if (!new_regex) goto memory_error; *regex = new_regex; (*regex_count)++; index = *regex_count - 1; /* initialize new regex */ (*regex)[index].variable = NULL; (*regex)[index].str_regex = NULL; (*regex)[index].regex = NULL; (*regex)[index].replace = NULL; (*regex)[index].replace_escaped = NULL; /* set string with regex */ (*regex)[index].str_regex = weechat_strndup (ptr_regex, pos_replace - ptr_regex); if (!(*regex)[index].str_regex) goto memory_error; str_regex_escaped = weechat_string_convert_escaped_chars ((*regex)[index].str_regex); if (!str_regex_escaped) goto memory_error; /* set regex */ (*regex)[index].regex = malloc (sizeof (*(*regex)[index].regex)); if (!(*regex)[index].regex) goto memory_error; if (weechat_string_regcomp ((*regex)[index].regex, str_regex_escaped, REG_EXTENDED | REG_ICASE) != 0) { free ((*regex)[index].regex); (*regex)[index].regex = NULL; goto compile_error; } /* set replace and replace_eval */ (*regex)[index].replace = (pos_replace_end) ? weechat_strndup (pos_replace + length_delimiter, pos_replace_end - pos_replace - length_delimiter) : strdup (pos_replace + length_delimiter); if (!(*regex)[index].replace) goto memory_error; (*regex)[index].replace_escaped = weechat_string_convert_escaped_chars ((*regex)[index].replace); if (!(*regex)[index].replace_escaped) goto memory_error; if (!pos_replace_end) break; /* set variable (optional) */ ptr_regex = pos_replace_end + length_delimiter; if (!ptr_regex[0]) break; if (ptr_regex[0] == ' ') pos_next_regex = ptr_regex; else { pos_next_regex = strchr (ptr_regex, ' '); (*regex)[index].variable = (pos_next_regex) ? weechat_strndup (ptr_regex, pos_next_regex - ptr_regex) : strdup (ptr_regex); if (!(*regex)[index].variable) goto memory_error; } if (!pos_next_regex) break; /* skip spaces before next regex */ ptr_regex = pos_next_regex + 1; while (ptr_regex[0] == ' ') { ptr_regex++; } } goto end; format_error: rc = -1; goto end; compile_error: rc = -2; goto end; memory_error: rc = -3; goto end; end: if (delimiter) free (delimiter); if (str_regex_escaped) free (str_regex_escaped); if (rc < 0) trigger_regex_free (regex_count, regex); return rc; }
void irc_message_parse (struct t_irc_server *server, const char *message, char **tags, char **message_without_tags, char **nick, char **host, char **command, char **channel, char **arguments, char **text, int *pos_command, int *pos_arguments, int *pos_channel, int *pos_text) { const char *ptr_message, *pos, *pos2, *pos3, *pos4; if (tags) *tags = NULL; if (message_without_tags) *message_without_tags = NULL; if (nick) *nick = NULL; if (host) *host = NULL; if (command) *command = NULL; if (channel) *channel = NULL; if (arguments) *arguments = NULL; if (text) *text = NULL; if (pos_command) *pos_command = -1; if (pos_arguments) *pos_arguments = -1; if (pos_channel) *pos_channel = -1; if (pos_text) *pos_text = -1; if (!message) return; ptr_message = message; /* * we will use this message as example: * * @time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello! */ if (ptr_message[0] == '@') { /* * read tags (they are optional and enabled only if client enabled * a server capability, see: * http://ircv3.atheme.org/specification/message-tags-3.2) */ pos = strchr (ptr_message, ' '); if (pos) { if (tags) { *tags = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); } ptr_message = pos + 1; while (ptr_message[0] == ' ') { ptr_message++; } } } if (message_without_tags) *message_without_tags = strdup (ptr_message); /* now we have: ptr_message --> ":nick!user@host PRIVMSG #weechat :hello!" */ if (ptr_message[0] == ':') { /* read host/nick */ pos3 = strchr (ptr_message, '@'); pos2 = strchr (ptr_message, '!'); pos = strchr (ptr_message, ' '); /* if the prefix doesn't contain a '!', split the nick at '@' */ if (!pos2 || (pos && pos2 > pos)) pos2 = pos3; if (pos2 && (!pos || pos > pos2)) { if (nick) *nick = weechat_strndup (ptr_message + 1, pos2 - (ptr_message + 1)); } else if (pos) { if (nick) *nick = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); } if (pos) { if (host) *host = weechat_strndup (ptr_message + 1, pos - (ptr_message + 1)); ptr_message = pos + 1; while (ptr_message[0] == ' ') { ptr_message++; } } else { if (host) *host = strdup (ptr_message + 1); ptr_message += strlen (ptr_message); } } /* now we have: ptr_message --> "PRIVMSG #weechat :hello!" */ if (ptr_message[0]) { pos = strchr (ptr_message, ' '); if (pos) { if (command) *command = weechat_strndup (ptr_message, pos - ptr_message); if (pos_command) *pos_command = ptr_message - message; pos++; while (pos[0] == ' ') { pos++; } /* now we have: pos --> "#weechat :hello!" */ if (arguments) *arguments = strdup (pos); if (pos_arguments) *pos_arguments = pos - message; if ((pos[0] == ':') && ((strncmp (ptr_message, "JOIN ", 5) == 0) || (strncmp (ptr_message, "PART ", 5) == 0))) { pos++; } if (pos[0] == ':') { if (text) *text = strdup (pos + 1); if (pos_text) *pos_text = pos - message + 1; } else { if (irc_channel_is_channel (server, pos)) { pos2 = strchr (pos, ' '); if (channel) { if (pos2) *channel = weechat_strndup (pos, pos2 - pos); else *channel = strdup (pos); } if (pos_channel) *pos_channel = pos - message; if (pos2) { while (pos2[0] == ' ') { pos2++; } if (pos2[0] == ':') pos2++; if (text) *text = strdup (pos2); if (pos_text) *pos_text = pos2 - message; } } else { pos2 = strchr (pos, ' '); if (nick && !*nick) { if (pos2) *nick = weechat_strndup (pos, pos2 - pos); else *nick = strdup (pos); } if (pos2) { pos3 = pos2; pos2++; while (pos2[0] == ' ') { pos2++; } if (irc_channel_is_channel (server, pos2)) { pos4 = strchr (pos2, ' '); if (channel) { if (pos4) *channel = weechat_strndup (pos2, pos4 - pos2); else *channel = strdup (pos2); } if (pos_channel) *pos_channel = pos2 - message; if (pos4) { while (pos4[0] == ' ') { pos4++; } if (pos4[0] == ':') pos4++; if (text) *text = strdup (pos4); if (pos_text) *pos_text = pos4 - message; } } else if ((channel && !*channel) || (pos_channel && (*pos_channel < 0))) { if (channel) *channel = weechat_strndup (pos, pos3 - pos); if (pos_channel) *pos_channel = pos - message; } } } } } else { if (command) *command = strdup (ptr_message); if (pos_command) *pos_command = ptr_message - message; } } }
int relay_weechat_msg_add_hdata_path (struct t_relay_weechat_msg *msg, char **list_path, int index_path, void **path_pointers, struct t_hdata *hdata, void *pointer, char **list_keys) { int num_added, i, j, count, count_all, var_type, array_size, max_array_size; int length; char *pos, *pos2, *str_count, *error, *name; void *sub_pointer; struct t_hdata *sub_hdata; const char *sub_hdata_name; num_added = 0; count_all = 0; count = 0; pos = strchr (list_path[index_path], '('); if (pos) { pos2 = strchr (pos + 1, ')'); if (pos2 && (pos2 > pos + 1)) { str_count = weechat_strndup (pos + 1, pos2 - (pos + 1)); if (str_count) { if (strcmp (str_count, "*") == 0) count_all = 1; else { error = NULL; count = (int)strtol (str_count, &error, 10); if (error && !error[0]) { if (count > 0) count--; else if (count < 0) count++; } else count = 0; } free (str_count); } } } while (pointer) { path_pointers[index_path] = pointer; if (list_path[index_path + 1]) { /* recursive call with next path */ pos = strchr (list_path[index_path + 1], '('); if (pos) pos[0] = '\0'; sub_pointer = weechat_hdata_pointer (hdata, pointer, list_path[index_path + 1]); sub_hdata_name = weechat_hdata_get_var_hdata (hdata, list_path[index_path + 1]); if (pos) pos[0] = '('; if (sub_pointer && sub_hdata_name) { sub_hdata = weechat_hdata_get (sub_hdata_name); if (sub_hdata) { num_added += relay_weechat_msg_add_hdata_path (msg, list_path, index_path + 1, path_pointers, sub_hdata, sub_pointer, list_keys); } } } else { /* last path? then get pointer + values and fill message with them */ for (i = 0; list_path[i]; i++) { relay_weechat_msg_add_pointer (msg, path_pointers[i]); } for (i = 0; list_keys[i]; i++) { var_type = weechat_hdata_get_var_type (hdata, list_keys[i]); if ((var_type >= 0) && (var_type != WEECHAT_HDATA_OTHER)) { max_array_size = 1; array_size = weechat_hdata_get_var_array_size (hdata, pointer, list_keys[i]); if (array_size >= 0) { switch (var_type) { case WEECHAT_HDATA_CHAR: relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_CHAR); break; case WEECHAT_HDATA_INTEGER: relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_INT); break; case WEECHAT_HDATA_LONG: relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_LONG); break; case WEECHAT_HDATA_STRING: relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_STRING); break; case WEECHAT_HDATA_POINTER: relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_POINTER); break; case WEECHAT_HDATA_TIME: relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_TIME); break; case WEECHAT_HDATA_HASHTABLE: relay_weechat_msg_add_type (msg, RELAY_WEECHAT_MSG_OBJ_HASHTABLE); break; } relay_weechat_msg_add_int (msg, array_size); max_array_size = array_size; } length = 16 + strlen (list_keys[i]) + 1; name = malloc (length); if (name) { for (j = 0; j < max_array_size; j++) { snprintf (name, length, "%d|%s", j, list_keys[i]); switch (var_type) { case WEECHAT_HDATA_CHAR: relay_weechat_msg_add_char (msg, weechat_hdata_char (hdata, pointer, name)); break; case WEECHAT_HDATA_INTEGER: relay_weechat_msg_add_int (msg, weechat_hdata_integer (hdata, pointer, name)); break; case WEECHAT_HDATA_LONG: relay_weechat_msg_add_long (msg, weechat_hdata_long (hdata, pointer, name)); break; case WEECHAT_HDATA_STRING: relay_weechat_msg_add_string (msg, weechat_hdata_string (hdata, pointer, name)); break; case WEECHAT_HDATA_POINTER: relay_weechat_msg_add_pointer (msg, weechat_hdata_pointer (hdata, pointer, name)); break; case WEECHAT_HDATA_TIME: relay_weechat_msg_add_time (msg, weechat_hdata_time (hdata, pointer, name)); break; case WEECHAT_HDATA_HASHTABLE: relay_weechat_msg_add_hashtable (msg, weechat_hdata_hashtable (hdata, pointer, name)); break; } } free (name); } } } num_added++; } if (count_all) { pointer = weechat_hdata_move (hdata, pointer, 1); } else if (count == 0) pointer = NULL; else if (count > 0) { pointer = weechat_hdata_move (hdata, pointer, 1); count--; } else { pointer = weechat_hdata_move (hdata, pointer, -1); count++; } if (!pointer) break; } return num_added; }
int irc_upgrade_read_cb (void *data, struct t_upgrade_file *upgrade_file, int object_id, struct t_infolist *infolist) { int flags, sock, size, i, index, nicks_count, num_items; long number; time_t join_time; char *buf, option_name[64], **nicks, *nick_join, *pos, *error; char **items; const char *buffer_name, *str, *nick; struct t_irc_nick *ptr_nick; struct t_irc_redirect *ptr_redirect; struct t_irc_notify *ptr_notify; struct t_gui_buffer *ptr_buffer; /* make C compiler happy */ (void) data; (void) upgrade_file; weechat_infolist_reset_item_cursor (infolist); while (weechat_infolist_next (infolist)) { switch (object_id) { case IRC_UPGRADE_TYPE_SERVER: irc_upgrade_current_server = irc_server_search (weechat_infolist_string (infolist, "name")); if (irc_upgrade_current_server) { irc_upgrade_current_server->temp_server = weechat_infolist_integer (infolist, "temp_server"); irc_upgrade_current_server->buffer = NULL; buffer_name = weechat_infolist_string (infolist, "buffer_name"); if (buffer_name && buffer_name[0]) { ptr_buffer = weechat_buffer_search (IRC_PLUGIN_NAME, buffer_name); if (ptr_buffer) irc_upgrade_current_server->buffer = ptr_buffer; } irc_upgrade_current_server->index_current_address = weechat_infolist_integer (infolist, "index_current_address"); str = weechat_infolist_string (infolist, "current_address"); if (str) { irc_upgrade_current_server->current_address = strdup (str); irc_upgrade_current_server->current_port = weechat_infolist_integer (infolist, "current_port"); } else { if (irc_upgrade_current_server->index_current_address < irc_upgrade_current_server->addresses_count) { irc_upgrade_current_server->current_address = strdup (irc_upgrade_current_server->addresses_array[irc_upgrade_current_server->index_current_address]); irc_upgrade_current_server->current_port = irc_upgrade_current_server->ports_array[irc_upgrade_current_server->index_current_address]; } } str = weechat_infolist_string (infolist, "current_ip"); if (str) irc_upgrade_current_server->current_ip = strdup (str); sock = weechat_infolist_integer (infolist, "sock"); if (sock >= 0) { irc_upgrade_current_server->sock = sock; irc_upgrade_current_server->hook_fd = weechat_hook_fd (irc_upgrade_current_server->sock, 1, 0, 0, &irc_server_recv_cb, irc_upgrade_current_server); } irc_upgrade_current_server->is_connected = weechat_infolist_integer (infolist, "is_connected"); irc_upgrade_current_server->ssl_connected = weechat_infolist_integer (infolist, "ssl_connected"); irc_upgrade_current_server->disconnected = weechat_infolist_integer (infolist, "disconnected"); str = weechat_infolist_string (infolist, "unterminated_message"); if (str) irc_upgrade_current_server->unterminated_message = strdup (str); str = weechat_infolist_string (infolist, "nick"); if (str) irc_server_set_nick (irc_upgrade_current_server, str); str = weechat_infolist_string (infolist, "nick_modes"); if (str) irc_upgrade_current_server->nick_modes = strdup (str); str = weechat_infolist_string (infolist, "isupport"); if (str) irc_upgrade_current_server->isupport = strdup (str); /* * "prefix" is not any more in this infolist (since * WeeChat 0.3.4), but we read it to keep compatibility * with old WeeChat versions, on /upgrade) */ str = weechat_infolist_string (infolist, "prefix"); if (str) irc_server_set_prefix_modes_chars (irc_upgrade_current_server, str); /* "prefix_modes" is new in WeeChat 0.3.4 */ str = weechat_infolist_string (infolist, "prefix_modes"); if (str) { if (irc_upgrade_current_server->prefix_modes) free (irc_upgrade_current_server->prefix_modes); irc_upgrade_current_server->prefix_modes = strdup (str); } /* "prefix_chars" is new in WeeChat 0.3.4 */ str = weechat_infolist_string (infolist, "prefix_chars"); if (str) { if (irc_upgrade_current_server->prefix_chars) free (irc_upgrade_current_server->prefix_chars); irc_upgrade_current_server->prefix_chars = strdup (str); } irc_upgrade_current_server->nick_max_length = weechat_infolist_integer (infolist, "nick_max_length"); irc_upgrade_current_server->casemapping = weechat_infolist_integer (infolist, "casemapping"); str = weechat_infolist_string (infolist, "chantypes"); if (str) irc_upgrade_current_server->chantypes = strdup (str); str = weechat_infolist_string (infolist, "chanmodes"); if (str) irc_upgrade_current_server->chanmodes = strdup (str); else { str = irc_server_get_isupport_value (irc_upgrade_current_server, "CHANMODES"); if (str) irc_upgrade_current_server->chanmodes = strdup (str); } /* "monitor" is new in WeeChat 0.4.3 */ if (weechat_infolist_search_var (infolist, "monitor")) { irc_upgrade_current_server->monitor = weechat_infolist_integer (infolist, "monitor"); } else { /* WeeChat <= 0.4.2 */ str = irc_server_get_isupport_value (irc_upgrade_current_server, "MONITOR"); if (str) { error = NULL; number = strtol (str, &error, 10); if (error && !error[0]) irc_upgrade_current_server->monitor = (int)number; } } irc_upgrade_current_server->reconnect_delay = weechat_infolist_integer (infolist, "reconnect_delay"); irc_upgrade_current_server->reconnect_start = weechat_infolist_time (infolist, "reconnect_start"); irc_upgrade_current_server->command_time = weechat_infolist_time (infolist, "command_time"); irc_upgrade_current_server->reconnect_join = weechat_infolist_integer (infolist, "reconnect_join"); irc_upgrade_current_server->disable_autojoin = weechat_infolist_integer (infolist, "disable_autojoin"); irc_upgrade_current_server->is_away = weechat_infolist_integer (infolist, "is_away"); str = weechat_infolist_string (infolist, "away_message"); if (str) irc_upgrade_current_server->away_message = strdup (str); irc_upgrade_current_server->away_time = weechat_infolist_time (infolist, "away_time"); irc_upgrade_current_server->lag = weechat_infolist_integer (infolist, "lag"); buf = weechat_infolist_buffer (infolist, "lag_check_time", &size); if (buf) memcpy (&(irc_upgrade_current_server->lag_check_time), buf, size); irc_upgrade_current_server->lag_next_check = weechat_infolist_time (infolist, "lag_next_check"); irc_upgrade_current_server->lag_last_refresh = weechat_infolist_time (infolist, "lag_last_refresh"); irc_upgrade_current_server->last_user_message = weechat_infolist_time (infolist, "last_user_message"); irc_upgrade_current_server->last_away_check = weechat_infolist_time (infolist, "last_away_check"); irc_upgrade_current_server->last_data_purge = weechat_infolist_time (infolist, "last_data_purge"); } break; case IRC_UPGRADE_TYPE_CHANNEL: if (irc_upgrade_current_server) { irc_upgrade_current_channel = irc_channel_new (irc_upgrade_current_server, weechat_infolist_integer (infolist, "type"), weechat_infolist_string (infolist, "name"), 0, 0); if (irc_upgrade_current_channel) { str = weechat_infolist_string (infolist, "topic"); if (str) irc_channel_set_topic (irc_upgrade_current_channel, str); str = weechat_infolist_string (infolist, "modes"); if (str) irc_upgrade_current_channel->modes = strdup (str); irc_upgrade_current_channel->limit = weechat_infolist_integer (infolist, "limit"); str = weechat_infolist_string (infolist, "key"); if (str) irc_upgrade_current_channel->key = strdup (str); str = weechat_infolist_string (infolist, "join_msg_received"); if (str) { items = weechat_string_split (str, ",", 0, 0, &num_items); if (items) { for (i = 0; i < num_items; i++) { weechat_hashtable_set (irc_upgrade_current_channel->join_msg_received, items[i], "1"); } weechat_string_free_split (items); } } irc_upgrade_current_channel->checking_away = weechat_infolist_integer (infolist, "checking_away"); str = weechat_infolist_string (infolist, "away_message"); if (str) irc_upgrade_current_channel->away_message = strdup (str); irc_upgrade_current_channel->has_quit_server = weechat_infolist_integer (infolist, "has_quit_server"); irc_upgrade_current_channel->cycle = weechat_infolist_integer (infolist, "cycle"); irc_upgrade_current_channel->part = weechat_infolist_integer (infolist, "part"); irc_upgrade_current_channel->nick_completion_reset = weechat_infolist_integer (infolist, "nick_completion_reset"); for (i = 0; i < 2; i++) { index = 0; while (1) { snprintf (option_name, sizeof (option_name), "nick_speaking%d_%05d", i, index); nick = weechat_infolist_string (infolist, option_name); if (!nick) break; irc_channel_nick_speaking_add (irc_upgrade_current_channel, nick, i); index++; } } index = 0; while (1) { snprintf (option_name, sizeof (option_name), "nick_speaking_time_nick_%05d", index); nick = weechat_infolist_string (infolist, option_name); if (!nick) break; snprintf (option_name, sizeof (option_name), "nick_speaking_time_time_%05d", index); irc_channel_nick_speaking_time_add (irc_upgrade_current_server, irc_upgrade_current_channel, nick, weechat_infolist_time (infolist, option_name)); index++; } str = weechat_infolist_string (infolist, "join_smart_filtered"); if (str) { nicks = weechat_string_split (str, ",", 0, 0, &nicks_count); if (nicks) { for (i = 0; i < nicks_count; i++) { pos = strchr (nicks[i], ':'); if (pos) { nick_join = weechat_strndup (nicks[i], pos - nicks[i]); if (nick_join) { error = NULL; number = strtol (pos + 1, &error, 10); if (error && !error[0]) { join_time = (time_t)number; irc_channel_join_smart_filtered_add (irc_upgrade_current_channel, nick_join, join_time); } free (nick_join); } } } weechat_string_free_split (nicks); } } } } break; case IRC_UPGRADE_TYPE_NICK: if (irc_upgrade_current_server && irc_upgrade_current_channel) { ptr_nick = irc_nick_new (irc_upgrade_current_server, irc_upgrade_current_channel, weechat_infolist_string (infolist, "name"), weechat_infolist_string (infolist, "host"), weechat_infolist_string (infolist, "prefixes"), weechat_infolist_integer (infolist, "away")); if (ptr_nick) { /* * "flags" is not any more in this infolist (since * WeeChat 0.3.4), but we read it to keep compatibility * with old WeeChat versions, on /upgrade) * We try to restore prefixes with old flags, but * this is approximation, it's not sure we will * restore good prefixes here (a /names on channel * will fix problem if prefixes are wrong). * Flags were defined in irc-nick.h: * #define IRC_NICK_CHANOWNER 1 * #define IRC_NICK_CHANADMIN 2 * #define IRC_NICK_CHANADMIN2 4 * #define IRC_NICK_OP 8 * #define IRC_NICK_HALFOP 16 * #define IRC_NICK_VOICE 32 * #define IRC_NICK_AWAY 64 * #define IRC_NICK_CHANUSER 128 */ flags = weechat_infolist_integer (infolist, "flags"); if (flags > 0) { /* channel owner */ if (flags & 1) { irc_nick_set_mode (irc_upgrade_current_server, irc_upgrade_current_channel, ptr_nick, 1, 'q'); } /* channel admin */ if ((flags & 2) || (flags & 4)) { irc_nick_set_mode (irc_upgrade_current_server, irc_upgrade_current_channel, ptr_nick, 1, 'a'); } /* op */ if (flags & 8) { irc_nick_set_mode (irc_upgrade_current_server, irc_upgrade_current_channel, ptr_nick, 1, 'o'); } /* half-op */ if (flags & 16) { irc_nick_set_mode (irc_upgrade_current_server, irc_upgrade_current_channel, ptr_nick, 1, 'h'); } /* voice */ if (flags & 32) { irc_nick_set_mode (irc_upgrade_current_server, irc_upgrade_current_channel, ptr_nick, 1, 'v'); } /* away */ if (flags & 64) { irc_nick_set_away (irc_upgrade_current_server, irc_upgrade_current_channel, ptr_nick, 1); } /* channel user */ if (flags & 128) { irc_nick_set_mode (irc_upgrade_current_server, irc_upgrade_current_channel, ptr_nick, 1, 'u'); } } } } break; case IRC_UPGRADE_TYPE_REDIRECT: if (irc_upgrade_current_server) { ptr_redirect = irc_redirect_new_with_commands ( irc_upgrade_current_server, weechat_infolist_string (infolist, "pattern"), weechat_infolist_string (infolist, "signal"), weechat_infolist_integer (infolist, "count"), weechat_infolist_string (infolist, "string"), weechat_infolist_integer (infolist, "timeout"), weechat_infolist_string (infolist, "cmd_start"), weechat_infolist_string (infolist, "cmd_stop"), weechat_infolist_string (infolist, "cmd_extra"), weechat_infolist_string (infolist, "cmd_filter")); if (ptr_redirect) { ptr_redirect->current_count = weechat_infolist_integer (infolist, "current_count"); str = weechat_infolist_string (infolist, "command"); if (str) ptr_redirect->command = strdup (str); ptr_redirect->assigned_to_command = weechat_infolist_integer (infolist, "assigned_to_command"); ptr_redirect->start_time = weechat_infolist_time (infolist, "start_time"); ptr_redirect->cmd_start_received = weechat_infolist_integer (infolist, "cmd_start_received"); ptr_redirect->cmd_stop_received = weechat_infolist_integer (infolist, "cmd_stop_received"); str = weechat_infolist_string (infolist, "output"); if (str) ptr_redirect->output = strdup (str); ptr_redirect->output_size = weechat_infolist_integer (infolist, "output_size"); } } break; case IRC_UPGRADE_TYPE_REDIRECT_PATTERN: irc_redirect_pattern_new ( weechat_infolist_string (infolist, "name"), weechat_infolist_integer (infolist, "temp_pattern"), weechat_infolist_integer (infolist, "timeout"), weechat_infolist_string (infolist, "cmd_start"), weechat_infolist_string (infolist, "cmd_stop"), weechat_infolist_string (infolist, "cmd_extra")); break; case IRC_UPGRADE_TYPE_NOTIFY: if (irc_upgrade_current_server) { ptr_notify = irc_notify_search (irc_upgrade_current_server, weechat_infolist_string (infolist, "nick")); if (ptr_notify) { ptr_notify->is_on_server = weechat_infolist_integer (infolist, "is_on_server"); str = weechat_infolist_string (infolist, "away_message"); if (str) ptr_notify->away_message = strdup (str); } } break; case IRC_UPGRADE_TYPE_RAW_MESSAGE: irc_raw_message_add_to_list (weechat_infolist_time (infolist, "date"), weechat_infolist_string (infolist, "prefix"), weechat_infolist_string (infolist, "message")); break; } } return WEECHAT_RC_OK; }
struct t_hashtable * irc_message_split (struct t_irc_server *server, const char *message) { struct t_hashtable *hashtable; char **argv, **argv_eol, *tags, *host, *command, *arguments, target[512]; char *pos, monitor_action[3]; int split_ok, argc, index_args, max_length_nick, max_length_host; split_ok = 0; tags = NULL; host = NULL; command = NULL; arguments = NULL; index_args = 0; argv = NULL; argv_eol = NULL; /* debug message */ if (weechat_irc_plugin->debug >= 2) weechat_printf (NULL, "irc_message_split: message='%s'", message); hashtable = weechat_hashtable_new (32, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL); if (!hashtable) return NULL; if (!message || !message[0]) goto end; if (message[0] == '@') { pos = strchr (message, ' '); if (pos) { tags = weechat_strndup (message, pos - message + 1); message = pos + 1; } } argv = weechat_string_split (message, " ", 0, 0, &argc); argv_eol = weechat_string_split (message, " ", 2, 0, NULL); if (argc < 2) goto end; if (argv[0][0] == ':') { if (argc < 3) goto end; host = argv[0]; command = argv[1]; arguments = argv_eol[2]; index_args = 2; } else { command = argv[0]; arguments = argv_eol[1]; index_args = 1; } max_length_nick = (server && (server->nick_max_length > 0)) ? server->nick_max_length : 16; max_length_host = 1 + /* ":" */ max_length_nick + /* nick */ 1 + /* "!" */ 63 + /* host */ 1; /* " " */ if ((weechat_strcasecmp (command, "ison") == 0) || (weechat_strcasecmp (command, "wallops") == 0)) { /* * ISON :nick1 nick2 nick3 * WALLOPS :some text here */ split_ok = irc_message_split_string ( hashtable, tags, host, command, NULL, ":", (argv_eol[index_args][0] == ':') ? argv_eol[index_args] + 1 : argv_eol[index_args], NULL, ' ', max_length_host); } else if (weechat_strcasecmp (command, "monitor") == 0) { /* * MONITOR + nick1,nick2,nick3 * MONITOR - nick1,nick2,nick3 */ if (((argv_eol[index_args][0] == '+') || (argv_eol[index_args][0] == '-')) && (argv_eol[index_args][1] == ' ')) { snprintf (monitor_action, sizeof (monitor_action), "%c ", argv_eol[index_args][0]); split_ok = irc_message_split_string ( hashtable, tags, host, command, NULL, monitor_action, argv_eol[index_args] + 2, NULL, ',', max_length_host); } else { split_ok = irc_message_split_string ( hashtable, tags, host, command, NULL, ":", (argv_eol[index_args][0] == ':') ? argv_eol[index_args] + 1 : argv_eol[index_args], NULL, ',', max_length_host); } } else if (weechat_strcasecmp (command, "join") == 0) { /* JOIN #channel1,#channel2,#channel3 key1,key2 */ if (strlen (message) > 510) { /* split join if it's more than 510 bytes */ split_ok = irc_message_split_join (hashtable, tags, host, arguments); } } else if ((weechat_strcasecmp (command, "privmsg") == 0) || (weechat_strcasecmp (command, "notice") == 0)) { /* * PRIVMSG target :some text here * NOTICE target :some text here */ if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_privmsg_notice ( hashtable, tags, host, command, argv[index_args], (argv_eol[index_args + 1][0] == ':') ? argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1], max_length_host); } } else if (weechat_strcasecmp (command, "005") == 0) { /* :server 005 nick MODES=4 CHANLIMIT=#:20 NICKLEN=16 USERLEN=10 ... */ if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_005 ( hashtable, tags, host, command, argv[index_args], (argv_eol[index_args + 1][0] == ':') ? argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1]); } } else if (weechat_strcasecmp (command, "353") == 0) { /* * list of users on channel: * :server 353 mynick = #channel :mynick nick1 @nick2 +nick3 */ if (index_args + 2 <= argc - 1) { if (irc_channel_is_channel (server, argv[index_args + 1])) { snprintf (target, sizeof (target), "%s %s", argv[index_args], argv[index_args + 1]); split_ok = irc_message_split_string ( hashtable, tags, host, command, target, ":", (argv_eol[index_args + 2][0] == ':') ? argv_eol[index_args + 2] + 1 : argv_eol[index_args + 2], NULL, ' ', -1); } else { if (index_args + 3 <= argc - 1) { snprintf (target, sizeof (target), "%s %s %s", argv[index_args], argv[index_args + 1], argv[index_args + 2]); split_ok = irc_message_split_string ( hashtable, tags, host, command, target, ":", (argv_eol[index_args + 3][0] == ':') ? argv_eol[index_args + 3] + 1 : argv_eol[index_args + 3], NULL, ' ', -1); } } } } end: if (!split_ok || (weechat_hashtable_get_integer (hashtable, "items_count") == 0)) { irc_message_split_add (hashtable, 1, tags, message, arguments); } if (tags) free (tags); if (argv) weechat_string_free_split (argv); if (argv_eol) weechat_string_free_split (argv_eol); return hashtable; }
void exec_concat_output (struct t_exec_cmd *exec_cmd, struct t_gui_buffer *buffer, int out, const char *text) { int length, new_size; const char *ptr_text; char *new_output, *pos, *line; ptr_text = text; /* if output is not sent as hsignal, display lines (ending with '\n') */ if (!exec_cmd->hsignal) { ptr_text = text; while (ptr_text[0]) { pos = strchr (ptr_text, '\n'); if (!pos) break; if (exec_cmd->output_size[out] > 0) { length = exec_cmd->output_size[out] + (pos - ptr_text) + 1; line = malloc (length); if (line) { memcpy (line, exec_cmd->output[out], exec_cmd->output_size[out]); memcpy (line + exec_cmd->output_size[out], ptr_text, pos - ptr_text); line[length - 1] = '\0'; } } else line = weechat_strndup (ptr_text, pos - ptr_text); if (!line) break; if (exec_cmd->output[out]) { free (exec_cmd->output[out]); exec_cmd->output[out] = NULL; } exec_cmd->output_size[out] = 0; exec_display_line (exec_cmd, buffer, out, line); free (line); ptr_text = pos + 1; } } /* concatenate ptr_text to output buffer */ length = strlen (ptr_text); if (length > 0) { new_size = exec_cmd->output_size[out] + length; new_output = realloc (exec_cmd->output[out], new_size + 1); if (!new_output) return; exec_cmd->output[out] = new_output; memcpy (exec_cmd->output[out] + exec_cmd->output_size[out], ptr_text, length + 1); exec_cmd->output_size[out] = new_size; } }
int irc_input_send_cb (void *data, const char *signal, const char *type_data, void *signal_data) { const char *ptr_string, *ptr_message; char *pos_semicol1, *pos_semicol2, *pos_semicol3, *pos_semicol4, *error; char *server, *channel, *flags, *tags; long flags_value; char *data_with_colors; struct t_irc_server *ptr_server; struct t_irc_channel *ptr_channel; struct t_gui_buffer *ptr_buffer; /* make C compiler happy */ (void) data; (void) signal; (void) type_data; ptr_string = (const char *)signal_data; server = NULL; channel = NULL; flags = NULL; tags = NULL; ptr_message = NULL; ptr_server = NULL; ptr_channel = NULL; pos_semicol1 = strchr (ptr_string, ';'); if (pos_semicol1) { if (pos_semicol1 > ptr_string + 1) { server = weechat_strndup (ptr_string, pos_semicol1 - ptr_string); } pos_semicol2 = strchr (pos_semicol1 + 1, ';'); if (pos_semicol2) { if (pos_semicol2 > pos_semicol1 + 1) { channel = weechat_strndup (pos_semicol1 + 1, pos_semicol2 - pos_semicol1 - 1); } pos_semicol3 = strchr (pos_semicol2 + 1, ';'); if (pos_semicol3) { if (pos_semicol3 > pos_semicol2 + 1) { flags = weechat_strndup (pos_semicol2 + 1, pos_semicol3 - pos_semicol2 - 1); } pos_semicol4 = strchr (pos_semicol3 + 1, ';'); if (pos_semicol4) { if (pos_semicol4 > pos_semicol3 + 1) { tags = weechat_strndup (pos_semicol3 + 1, pos_semicol4 - pos_semicol3 - 1); } ptr_message = pos_semicol4 + 1; } } } } flags_value = IRC_SERVER_SEND_OUTQ_PRIO_HIGH; if (flags) { error = NULL; flags_value = strtol (flags, &error, 10); if (flags_value < 0) flags_value = IRC_SERVER_SEND_OUTQ_PRIO_HIGH; } if (server && ptr_message) { ptr_server = irc_server_search (server); if (ptr_server) { ptr_buffer = ptr_server->buffer; if (channel) { ptr_channel = irc_channel_search (ptr_server, channel); if (ptr_channel) ptr_buffer = ptr_channel->buffer; } /* set tags to use by default */ irc_server_set_send_default_tags (tags); /* send text to buffer, or execute command */ if (weechat_string_input_for_buffer (ptr_message)) { /* text as input */ irc_input_data (ptr_buffer, ptr_message, flags_value); } else { /* command */ data_with_colors = irc_color_encode (ptr_message, weechat_config_boolean (irc_config_network_colors_send)); weechat_command (ptr_buffer, (data_with_colors) ? data_with_colors : ptr_message); if (data_with_colors) free (data_with_colors); } /* reset tags to use by default */ irc_server_set_send_default_tags (NULL); } } if (server) free (server); if (channel) free (channel); if (flags) free (flags); if (tags) free (tags); return WEECHAT_RC_OK; }
int irc_input_send_cb (const void *pointer, void *data, const char *signal, const char *type_data, void *signal_data) { const char *ptr_string, *ptr_message; char *pos_semicol1, *pos_semicol2, *pos_semicol3, *pos_semicol4; char *server, *channel, *options, *tags, *data_with_colors, **list_options; int i, num_options, flags, force_user_message; struct t_irc_server *ptr_server; struct t_irc_channel *ptr_channel; struct t_gui_buffer *ptr_buffer; /* make C compiler happy */ (void) pointer; (void) data; (void) signal; (void) type_data; ptr_string = (const char *)signal_data; server = NULL; channel = NULL; options = NULL; flags = IRC_SERVER_SEND_OUTQ_PRIO_HIGH; force_user_message = 0; tags = NULL; ptr_message = NULL; ptr_server = NULL; ptr_channel = NULL; pos_semicol1 = strchr (ptr_string, ';'); if (pos_semicol1) { if (pos_semicol1 > ptr_string + 1) { server = weechat_strndup (ptr_string, pos_semicol1 - ptr_string); } pos_semicol2 = strchr (pos_semicol1 + 1, ';'); if (pos_semicol2) { if (pos_semicol2 > pos_semicol1 + 1) { channel = weechat_strndup (pos_semicol1 + 1, pos_semicol2 - pos_semicol1 - 1); } pos_semicol3 = strchr (pos_semicol2 + 1, ';'); if (pos_semicol3) { if (pos_semicol3 > pos_semicol2 + 1) { options = weechat_strndup (pos_semicol2 + 1, pos_semicol3 - pos_semicol2 - 1); } pos_semicol4 = strchr (pos_semicol3 + 1, ';'); if (pos_semicol4) { if (pos_semicol4 > pos_semicol3 + 1) { tags = weechat_strndup (pos_semicol3 + 1, pos_semicol4 - pos_semicol3 - 1); } ptr_message = pos_semicol4 + 1; } } } } if (options && options[0]) { list_options = weechat_string_split (options, ",", 0, 0, &num_options); if (list_options) { for (i = 0; i < num_options; i++) { if (strcmp (list_options[i], "priority_high") == 0) flags = IRC_SERVER_SEND_OUTQ_PRIO_HIGH; else if (strcmp (list_options[i], "priority_low") == 0) flags = IRC_SERVER_SEND_OUTQ_PRIO_LOW; else if (strcmp (list_options[i], "user_message") == 0) force_user_message = 1; } weechat_string_free_split (list_options); } } if (server && ptr_message) { ptr_server = irc_server_search (server); if (ptr_server) { ptr_buffer = ptr_server->buffer; if (channel) { ptr_channel = irc_channel_search (ptr_server, channel); if (ptr_channel) ptr_buffer = ptr_channel->buffer; } /* set tags to use by default */ irc_server_set_send_default_tags (tags); /* send text to buffer, or execute command */ if (force_user_message || weechat_string_input_for_buffer (ptr_message)) { /* text as input */ irc_input_data (ptr_buffer, ptr_message, flags, 1); } else { /* command */ data_with_colors = irc_color_encode ( ptr_message, weechat_config_boolean (irc_config_network_colors_send)); weechat_command ( ptr_buffer, (data_with_colors) ? data_with_colors : ptr_message); if (data_with_colors) free (data_with_colors); } /* reset tags to use by default */ irc_server_set_send_default_tags (NULL); } } if (server) free (server); if (channel) free (channel); if (options) free (options); if (tags) free (tags); return WEECHAT_RC_OK; }
void irc_mode_channel_update (struct t_irc_server *server, struct t_irc_channel *channel, char set_flag, char chanmode, const char *argument) { char *pos_args, *str_modes, **argv, *pos, *ptr_arg; char *new_modes, *new_args, str_mode[2], *str_temp; int argc, current_arg, chanmode_found, length; if (!channel->modes) channel->modes = strdup ("+"); if (!channel->modes) return; argc = 0; argv = NULL; pos_args = strchr (channel->modes, ' '); if (pos_args) { str_modes = weechat_strndup (channel->modes, pos_args - channel->modes); if (!str_modes) return; pos_args++; while (pos_args[0] == ' ') pos_args++; argv = weechat_string_split (pos_args, " ", WEECHAT_STRING_SPLIT_STRIP_LEFT | WEECHAT_STRING_SPLIT_STRIP_RIGHT | WEECHAT_STRING_SPLIT_COLLAPSE_SEPS, 0, &argc); } else { str_modes = strdup (channel->modes); if (!str_modes) return; } new_modes = malloc (strlen (channel->modes) + 1 + 1); new_args = malloc (((pos_args) ? strlen (pos_args) : 0) + ((argument) ? 1 + strlen (argument) : 0) + 1); if (new_modes && new_args) { new_modes[0] = '\0'; new_args[0] = '\0'; /* loop on current modes and build "new_modes" + "new_args" */ current_arg = 0; chanmode_found = 0; pos = str_modes; while (pos && pos[0]) { if ((pos[0] == '+') || (pos[0] == '-')) { str_mode[0] = pos[0]; str_mode[1] = '\0'; strcat (new_modes, str_mode); } else { ptr_arg = NULL; switch (irc_mode_get_chanmode_type (server, pos[0])) { case 'A': /* always argument */ case 'B': /* always argument */ case 'C': /* argument if set */ ptr_arg = (current_arg < argc) ? argv[current_arg] : NULL; break; case 'D': /* no argument */ break; } if (ptr_arg) current_arg++; if (pos[0] == chanmode) { chanmode_found = 1; if (set_flag == '+') { str_mode[0] = pos[0]; str_mode[1] = '\0'; strcat (new_modes, str_mode); if (argument) { if (new_args[0]) strcat (new_args, " "); strcat (new_args, argument); } } } else { str_mode[0] = pos[0]; str_mode[1] = '\0'; strcat (new_modes, str_mode); if (ptr_arg) { if (new_args[0]) strcat (new_args, " "); strcat (new_args, ptr_arg); } } } pos++; } if (!chanmode_found) { /* * chanmode was not in channel modes: if set_flag is '+', add * it to channel modes */ if (set_flag == '+') { if (argument) { /* add mode with argument at the end of modes */ str_mode[0] = chanmode; str_mode[1] = '\0'; strcat (new_modes, str_mode); if (new_args[0]) strcat (new_args, " "); strcat (new_args, argument); } else { /* add mode without argument at the beginning of modes */ pos = new_modes; while (pos[0] == '+') pos++; memmove (pos + 1, pos, strlen (pos) + 1); pos[0] = chanmode; } } } if (new_args[0]) { length = strlen (new_modes) + 1 + strlen (new_args) + 1; str_temp = malloc (length); if (str_temp) { snprintf (str_temp, length, "%s %s", new_modes, new_args); if (channel->modes) free (channel->modes); channel->modes = str_temp; } } else { if (channel->modes) free (channel->modes); channel->modes = strdup (new_modes); } } if (new_modes) free (new_modes); if (new_args) free (new_args); if (str_modes) free (str_modes); if (argv) weechat_string_free_split (argv); }
struct t_hashtable * irc_message_split (struct t_irc_server *server, const char *message) { struct t_hashtable *hashtable; char **argv, **argv_eol, *tags, *host, *command, *arguments, target[512]; char *pos; int split_ok, argc, index_args, max_length_nick, max_length_host; split_ok = 0; tags = NULL; host = NULL; command = NULL; arguments = NULL; index_args = 0; argv = NULL; argv_eol = NULL; /* debug message */ if (weechat_irc_plugin->debug >= 2) weechat_printf (NULL, "irc_message_split: message='%s'", message); hashtable = weechat_hashtable_new (32, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL); if (!hashtable) return NULL; if (!message || !message[0]) goto end; if (message[0] == '@') { pos = strchr (message, ' '); if (pos) { tags = weechat_strndup (message, pos - message + 1); message = pos + 1; } } argv = weechat_string_split (message, " ", 0, 0, &argc); argv_eol = weechat_string_split (message, " ", 2, 0, NULL); if (argc < 2) goto end; if (argv[0][0] == ':') { if (argc < 3) goto end; host = argv[0]; command = argv[1]; arguments = argv_eol[2]; index_args = 2; } else { command = argv[0]; arguments = argv_eol[1]; index_args = 1; } max_length_nick = (server && (server->nick_max_length > 0)) ? server->nick_max_length : 16; max_length_host = 1 + /* ":" */ max_length_nick + /* nick */ 1 + /* "!" */ 63 + /* host */ 1; /* " " */ if ((weechat_strcasecmp (command, "ison") == 0) || (weechat_strcasecmp (command, "wallops") == 0)) { split_ok = irc_message_split_string (hashtable, tags, host, command, NULL, ":", (argv_eol[index_args][0] == ':') ? argv_eol[index_args] + 1 : argv_eol[index_args], NULL, ' ', max_length_host); } else if (weechat_strcasecmp (command, "join") == 0) { /* split join (if it's more than 510 bytes) */ if (strlen (message) > 510) { split_ok = irc_message_split_join (hashtable, tags, host, arguments); } } else if ((weechat_strcasecmp (command, "privmsg") == 0) || (weechat_strcasecmp (command, "notice") == 0)) { /* split privmsg/notice */ if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_privmsg_notice (hashtable, tags, host, command, argv[index_args], (argv_eol[index_args + 1][0] == ':') ? argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1], max_length_host); } } else if (weechat_strcasecmp (command, "005") == 0) { /* split 005 (isupport) */ if (index_args + 1 <= argc - 1) { split_ok = irc_message_split_005 (hashtable, tags, host, command, argv[index_args], (argv_eol[index_args + 1][0] == ':') ? argv_eol[index_args + 1] + 1 : argv_eol[index_args + 1]); } } else if (weechat_strcasecmp (command, "353") == 0) { /* * split 353 (list of users on channel): * :server 353 mynick = #channel :mynick nick1 @nick2 +nick3 */ if (index_args + 2 <= argc - 1) { if (irc_channel_is_channel (server, argv[index_args + 1])) { snprintf (target, sizeof (target), "%s %s", argv[index_args], argv[index_args + 1]); split_ok = irc_message_split_string (hashtable, tags, host, command, target, ":", (argv_eol[index_args + 2][0] == ':') ? argv_eol[index_args + 2] + 1 : argv_eol[index_args + 2], NULL, ' ', -1); } else { if (index_args + 3 <= argc - 1) { snprintf (target, sizeof (target), "%s %s %s", argv[index_args], argv[index_args + 1], argv[index_args + 2]); split_ok = irc_message_split_string (hashtable, tags, host, command, target, ":", (argv_eol[index_args + 3][0] == ':') ? argv_eol[index_args + 3] + 1 : argv_eol[index_args + 3], NULL, ' ', -1); } } } } end: if (!split_ok || (weechat_hashtable_get_integer (hashtable, "items_count") == 0)) { irc_message_split_add (hashtable, 1, tags, message, arguments); } if (tags) free (tags); if (argv) weechat_string_free_split (argv); if (argv_eol) weechat_string_free_split (argv_eol); return hashtable; }
int irc_message_split_string (struct t_hashtable *hashtable, const char *tags, const char *host, const char *command, const char *target, const char *prefix, const char *arguments, const char *suffix, const char delimiter, int max_length_host) { const char *pos, *pos_max, *pos_next, *pos_last_delim; char message[1024], *dup_arguments; int max_length, number; max_length = 510; if (max_length_host >= 0) max_length -= max_length_host; else max_length -= (host) ? strlen (host) + 1 : 0; max_length -= strlen (command) + 1; if (target) max_length -= strlen (target); if (prefix) max_length -= strlen (prefix); if (suffix) max_length -= strlen (suffix); if (max_length < 2) return 0; /* debug message */ if (weechat_irc_plugin->debug >= 2) { weechat_printf (NULL, "irc_message_split_string: tags='%s', host='%s', " "command='%s', target='%s', prefix='%s', " "arguments='%s', suffix='%s', max_length=%d", tags, host, command, target, prefix, arguments, suffix, max_length); } number = 1; if (!arguments || !arguments[0]) { snprintf (message, sizeof (message), "%s%s%s %s%s%s%s", (host) ? host : "", (host) ? " " : "", command, (target) ? target : "", (target && target[0]) ? " " : "", (prefix) ? prefix : "", (suffix) ? suffix : ""); irc_message_split_add (hashtable, 1, tags, message, ""); return 1; } while (arguments && arguments[0]) { pos = arguments; pos_max = pos + max_length; pos_last_delim = NULL; while (pos && pos[0]) { if (pos[0] == delimiter) pos_last_delim = pos; pos_next = weechat_utf8_next_char (pos); if (pos_next > pos_max) break; pos = pos_next; } if (pos[0] && pos_last_delim) pos = pos_last_delim; dup_arguments = weechat_strndup (arguments, pos - arguments); if (dup_arguments) { snprintf (message, sizeof (message), "%s%s%s %s%s%s%s%s", (host) ? host : "", (host) ? " " : "", command, (target) ? target : "", (target && target[0]) ? " " : "", (prefix) ? prefix : "", dup_arguments, (suffix) ? suffix : ""); irc_message_split_add (hashtable, number, tags, message, dup_arguments); number++; free (dup_arguments); } arguments = (pos == pos_last_delim) ? pos + 1 : pos; } return 1; }
void weechat_aspell_command_speller_list_dicts () { #ifndef USE_ENCHANT char *country, *lang, *pos, *iso; char str_dict[256], str_country[128]; struct AspellConfig *config; AspellDictInfoList *list; AspellDictInfoEnumeration *elements; const AspellDictInfo *dict; #endif weechat_printf (NULL, ""); weechat_printf (NULL, /* TRANSLATORS: "%s" is "aspell" */ _( "%s dictionaries list:"), ASPELL_PLUGIN_NAME); #ifdef USE_ENCHANT enchant_broker_list_dicts (broker, weechat_aspell_enchant_dict_describe_cb, NULL); #else config = new_aspell_config(); list = get_aspell_dict_info_list (config); elements = aspell_dict_info_list_elements (list); while ((dict = aspell_dict_info_enumeration_next (elements)) != NULL) { lang = NULL; country = NULL; pos = strchr (dict->code, '_'); if (pos) { iso = weechat_strndup (dict->code, pos - dict->code); if (iso) { lang = weechat_aspell_command_iso_to_lang (iso); country = weechat_aspell_command_iso_to_country (pos + 1); free (iso); } } else lang = weechat_aspell_command_iso_to_lang ((char*)dict->code); str_country[0] = '\0'; if (country || dict->jargon[0]) { snprintf (str_country, sizeof (str_country), " (%s%s%s)", (country) ? country : dict->jargon, (country && dict->jargon[0]) ? " - " : "", (country && dict->jargon[0]) ? ((dict->jargon[0]) ? dict->jargon : country) : ""); } snprintf (str_dict, sizeof (str_dict), "%-22s %s%s", dict->name, lang, str_country); weechat_printf (NULL, " %s", str_dict); if (lang) free (lang); if (country) free (country); } delete_aspell_dict_info_enumeration (elements); delete_aspell_config (config); #endif }
int irc_mode_channel_set (struct t_irc_server *server, struct t_irc_channel *channel, const char *modes) { char *pos_args, *str_modes, set_flag, **argv, *pos, *ptr_arg, chanmode_type; int argc, current_arg, update_channel_modes, channel_modes_updated; int smart_filter; struct t_irc_nick *ptr_nick; if (!server || !channel || !modes) return 0; channel_modes_updated = 0; argc = 0; argv = NULL; pos_args = strchr (modes, ' '); if (pos_args) { str_modes = weechat_strndup (modes, pos_args - modes); if (!str_modes) return 0; pos_args++; while (pos_args[0] == ' ') pos_args++; argv = weechat_string_split (pos_args, " ", 0, 0, &argc); } else { str_modes = strdup (modes); if (!str_modes) return 0; } current_arg = 0; smart_filter = (weechat_config_boolean (irc_config_look_smart_filter) && weechat_config_string (irc_config_look_smart_filter_mode) && weechat_config_string (irc_config_look_smart_filter_mode)[0]) ? 1 : 0; if (str_modes && str_modes[0]) { set_flag = '+'; pos = str_modes; while (pos && pos[0]) { switch (pos[0]) { case ':': case ' ': break; case '+': set_flag = '+'; break; case '-': set_flag = '-'; break; default: update_channel_modes = 1; chanmode_type = irc_mode_get_chanmode_type (server, pos[0]); ptr_arg = NULL; switch (chanmode_type) { case 'A': /* always argument */ update_channel_modes = 0; ptr_arg = (current_arg < argc) ? argv[current_arg] : NULL; break; case 'B': /* always argument */ ptr_arg = (current_arg < argc) ? argv[current_arg] : NULL; break; case 'C': /* argument if set */ ptr_arg = ((set_flag == '+') && (current_arg < argc)) ? argv[current_arg] : NULL; break; case 'D': /* no argument */ break; } if (ptr_arg) current_arg++; if (smart_filter && !irc_mode_smart_filtered (server, pos[0])) { smart_filter = 0; } if (pos[0] == 'k') { /* channel key */ if (set_flag == '-') { if (channel->key) { free (channel->key); channel->key = NULL; } } else if ((set_flag == '+') && ptr_arg && (strcmp (ptr_arg, "*") != 0)) { /* replace key for +k, but ignore "*" as new key */ if (channel->key) free (channel->key); channel->key = strdup (ptr_arg); } } else if (pos[0] == 'l') { /* channel limit */ if (set_flag == '-') channel->limit = 0; if ((set_flag == '+') && ptr_arg) { channel->limit = atoi (ptr_arg); } } else if ((chanmode_type != 'A') && (irc_server_get_prefix_mode_index (server, pos[0]) >= 0)) { /* mode for nick */ update_channel_modes = 0; if (ptr_arg) { ptr_nick = irc_nick_search (server, channel, ptr_arg); if (ptr_nick) { irc_nick_set_mode (server, channel, ptr_nick, (set_flag == '+'), pos[0]); if (smart_filter && irc_channel_nick_speaking_time_search (server, channel, ptr_nick->name, 1)) { smart_filter = 0; } } } } if (update_channel_modes) { irc_mode_channel_update (server, channel, set_flag, pos[0], ptr_arg); channel_modes_updated = 1; } break; } pos++; } } if (str_modes) free (str_modes); if (argv) weechat_string_free_split (argv); if (channel_modes_updated) weechat_bar_item_update ("buffer_modes"); return smart_filter; }
void irc_input_user_message_display (struct t_gui_buffer *buffer, int action, const char *text) { struct t_irc_nick *ptr_nick; char *pos, *text2, *text_decoded, str_tags[256], *str_color; const char *ptr_text; /* if message is an action, force "action" to 1 and extract message */ if (strncmp (text, "\01ACTION ", 8) == 0) { action = 1; pos = strrchr (text + 8, '\01'); if (pos) text2 = weechat_strndup (text + 8, pos - text - 8); else text2 = strdup (text + 8); } else text2 = strdup (text); text_decoded = irc_color_decode ( (text2) ? text2 : text, weechat_config_boolean (irc_config_network_colors_send)); IRC_BUFFER_GET_SERVER_CHANNEL(buffer); if (ptr_channel) { ptr_nick = NULL; if (ptr_channel->type == IRC_CHANNEL_TYPE_CHANNEL) { ptr_nick = irc_nick_search (ptr_server, ptr_channel, ptr_server->nick); } if (action) { snprintf (str_tags, sizeof (str_tags), "irc_action,self_msg,notify_none,no_highlight"); } else { str_color = irc_color_for_tags ( weechat_config_color ( weechat_config_get ("weechat.color.chat_nick_self"))); snprintf (str_tags, sizeof (str_tags), "notify_none,self_msg,no_highlight,prefix_nick_%s", (str_color) ? str_color : "default"); if (str_color) free (str_color); } ptr_text = (text_decoded) ? text_decoded : ((text2) ? text2 : text); if (action) { weechat_printf_date_tags ( buffer, 0, irc_protocol_tags ( "privmsg", str_tags, (ptr_nick) ? ptr_nick->name : ptr_server->nick, NULL), "%s%s%s%s%s %s", weechat_prefix ("action"), irc_nick_mode_for_display (ptr_server, ptr_nick, 0), IRC_COLOR_CHAT_NICK_SELF, ptr_server->nick, IRC_COLOR_RESET, ptr_text); } else { weechat_printf_date_tags ( buffer, 0, irc_protocol_tags ( "privmsg", str_tags, (ptr_nick) ? ptr_nick->name : ptr_server->nick, NULL), "%s%s", irc_nick_as_prefix ( ptr_server, (ptr_nick) ? ptr_nick : NULL, (ptr_nick) ? NULL : ptr_server->nick, IRC_COLOR_CHAT_NICK_SELF), ptr_text); } } if (text2) free (text2); if (text_decoded) free (text_decoded); }
int irc_message_split_join (struct t_hashtable *hashtable, const char *tags, const char *host, const char *arguments) { int number, channels_count, keys_count, length, length_no_channel; int length_to_add, index_channel; char **channels, **keys, *pos, *str; char msg_to_send[2048], keys_to_add[2048]; number = 1; channels = NULL; channels_count = 0; keys = NULL; keys_count = 0; pos = strchr (arguments, ' '); if (pos) { str = weechat_strndup (arguments, pos - arguments); if (!str) return 0; channels = weechat_string_split (str, ",", 0, 0, &channels_count); free (str); while (pos[0] == ' ') { pos++; } if (pos[0]) keys = weechat_string_split (pos, ",", 0, 0, &keys_count); } else { channels = weechat_string_split (arguments, ",", 0, 0, &channels_count); } snprintf (msg_to_send, sizeof (msg_to_send), "%s%sJOIN", (host) ? host : "", (host) ? " " : ""); length = strlen (msg_to_send); length_no_channel = length; keys_to_add[0] = '\0'; index_channel = 0; while (index_channel < channels_count) { length_to_add = 1 + strlen (channels[index_channel]); if (index_channel < keys_count) length_to_add += 1 + strlen (keys[index_channel]); if ((length + length_to_add < 510) || (length == length_no_channel)) { if (length + length_to_add < (int)sizeof (msg_to_send)) { strcat (msg_to_send, (length == length_no_channel) ? " " : ","); strcat (msg_to_send, channels[index_channel]); } if (index_channel < keys_count) { if (strlen (keys_to_add) + 1 + strlen (keys[index_channel]) < (int)sizeof (keys_to_add)) { strcat (keys_to_add, (keys_to_add[0]) ? "," : " "); strcat (keys_to_add, keys[index_channel]); } } length += length_to_add; index_channel++; } else { strcat (msg_to_send, keys_to_add); irc_message_split_add (hashtable, number, tags, msg_to_send, msg_to_send + length_no_channel + 1); number++; snprintf (msg_to_send, sizeof (msg_to_send), "%s%sJOIN", (host) ? host : "", (host) ? " " : ""); length = strlen (msg_to_send); keys_to_add[0] = '\0'; } } if (length > length_no_channel) { strcat (msg_to_send, keys_to_add); irc_message_split_add (hashtable, number, tags, msg_to_send, msg_to_send + length_no_channel + 1); } if (channels) weechat_string_free_split (channels); if (keys) weechat_string_free_split (keys); return 1; }
int trigger_callback_signal_cb (void *data, const char *signal, const char *type_data, void *signal_data) { const char *ptr_signal_data; char str_data[128], *irc_server; const char *pos, *ptr_irc_message; TRIGGER_CALLBACK_CB_INIT(WEECHAT_RC_OK); /* split IRC message (if signal_data is an IRC message) */ irc_server = NULL; ptr_irc_message = NULL; if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) { if (strstr (signal, ",irc_in_") || strstr (signal, ",irc_in2_") || strstr (signal, ",irc_raw_in_") || strstr (signal, ",irc_raw_in2_") || strstr (signal, ",irc_out1_") || strstr (signal, ",irc_out_")) { pos = strchr (signal, ','); if (pos) { irc_server = weechat_strndup (signal, pos - signal); ptr_irc_message = (const char *)signal_data; } } else { pos = strstr (signal, ",irc_outtags_"); if (pos) { irc_server = weechat_strndup (signal, pos - signal); pos = strchr ((const char *)signal_data, ';'); if (pos) ptr_irc_message = pos + 1; } } } if (irc_server && ptr_irc_message) { extra_vars = trigger_callback_irc_message_parse (ptr_irc_message, irc_server); if (extra_vars) weechat_hashtable_set (extra_vars, "server", irc_server); } if (irc_server) free (irc_server); /* create hashtable (if not already created) */ if (!extra_vars) { TRIGGER_CALLBACK_CB_NEW_EXTRA_VARS; } /* add data in hashtable used for conditions/replace/command */ ptr_signal_data = NULL; weechat_hashtable_set (extra_vars, "tg_signal", signal); if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_STRING) == 0) { ptr_signal_data = (const char *)signal_data; } else if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_INT) == 0) { str_data[0] = '\0'; if (signal_data) { snprintf (str_data, sizeof (str_data), "%d", *((int *)signal_data)); } ptr_signal_data = str_data; } else if (strcmp (type_data, WEECHAT_HOOK_SIGNAL_POINTER) == 0) { str_data[0] = '\0'; if (signal_data) { snprintf (str_data, sizeof (str_data), "0x%lx", (long unsigned int)signal_data); } ptr_signal_data = str_data; } weechat_hashtable_set (extra_vars, "tg_signal_data", ptr_signal_data); /* execute the trigger (conditions, regex, command) */ trigger_callback_execute (trigger, NULL, pointers, extra_vars); end: TRIGGER_CALLBACK_CB_END(trigger_rc); }
void relay_weechat_protocol_recv (struct t_relay_client *client, const char *data) { char *pos, *id, *command, **argv, **argv_eol; int i, argc, return_code; struct t_relay_weechat_protocol_cb protocol_cb[] = { { "init", &relay_weechat_protocol_cb_init }, { "hdata", &relay_weechat_protocol_cb_hdata }, { "info", &relay_weechat_protocol_cb_info }, { "infolist", &relay_weechat_protocol_cb_infolist }, { "nicklist", &relay_weechat_protocol_cb_nicklist }, { "input", &relay_weechat_protocol_cb_input }, { "sync", &relay_weechat_protocol_cb_sync }, { "desync", &relay_weechat_protocol_cb_desync }, { "test", &relay_weechat_protocol_cb_test }, { "ping", &relay_weechat_protocol_cb_ping }, { "quit", &relay_weechat_protocol_cb_quit }, { NULL, NULL } }; if (!data || !data[0] || RELAY_CLIENT_HAS_ENDED(client)) return; /* display debug message */ if (weechat_relay_plugin->debug >= 2) { weechat_printf (NULL, "%s: recv from client %s%s%s: \"%s\"", RELAY_PLUGIN_NAME, RELAY_COLOR_CHAT_CLIENT, client->desc, RELAY_COLOR_CHAT, data); } /* extract id */ id = NULL; if (data[0] == '(') { pos = strchr (data, ')'); if (pos) { id = weechat_strndup (data + 1, pos - data - 1); data = pos + 1; while (data[0] == ' ') { data++; } } } /* search end of data */ pos = strchr (data, ' '); if (pos) command = weechat_strndup (data, pos - data); else command = strdup (data); if (!command) { if (id) free (id); return; } argc = 0; argv = NULL; argv_eol = NULL; if (pos) { while (pos[0] == ' ') { pos++; } argv = weechat_string_split (pos, " ", 0, 0, &argc); argv_eol = weechat_string_split (pos, " ", 2, 0, NULL); } for (i = 0; protocol_cb[i].name; i++) { if (strcmp (protocol_cb[i].name, command) == 0) { if ((strcmp (protocol_cb[i].name, "init") != 0) && (!RELAY_WEECHAT_DATA(client, password_ok))) { /* * command is not "init" and password is not set? * then close connection! */ relay_client_set_status (client, RELAY_STATUS_AUTH_FAILED); } else { return_code = (int) (protocol_cb[i].cmd_function) (client, id, protocol_cb[i].name, argc, argv, argv_eol); if ((weechat_relay_plugin->debug >= 1) && (return_code == WEECHAT_RC_ERROR)) { weechat_printf (NULL, _("%s%s: failed to execute command \"%s\" " "for client %s%s%s"), weechat_prefix ("error"), RELAY_PLUGIN_NAME, command, RELAY_COLOR_CHAT_CLIENT, client->desc, RELAY_COLOR_CHAT); } } break; } } if (id) free (id); free (command); if (argv) weechat_string_free_split (argv); if (argv_eol) weechat_string_free_split (argv_eol); }
char * trigger_callback_modifier_cb (void *data, const char *modifier, const char *modifier_data, const char *string) { struct t_gui_buffer *buffer; const char *ptr_string; char *string_modified, *pos, *pos2, *plugin_name, *buffer_name; char *buffer_full_name, *str_tags, **tags, *prefix, *string_no_color; int length, num_tags; TRIGGER_CALLBACK_CB_INIT(NULL); buffer = NULL; tags = NULL; num_tags = 0; string_no_color = NULL; /* split IRC message (if string is an IRC message) */ if ((strncmp (modifier, "irc_in_", 7) == 0) || (strncmp (modifier, "irc_in2_", 8) == 0) || (strncmp (modifier, "irc_out1_", 9) == 0) || (strncmp (modifier, "irc_out_", 8) == 0)) { extra_vars = trigger_callback_irc_message_parse (string, modifier_data); if (extra_vars) weechat_hashtable_set (extra_vars, "server", modifier_data); } TRIGGER_CALLBACK_CB_NEW_POINTERS; if (!extra_vars) { TRIGGER_CALLBACK_CB_NEW_EXTRA_VARS; } /* add data in hashtable used for conditions/replace/command */ weechat_hashtable_set (extra_vars, "tg_modifier", modifier); weechat_hashtable_set (extra_vars, "tg_modifier_data", modifier_data); weechat_hashtable_set (extra_vars, "tg_string", string); string_no_color = weechat_string_remove_color (string, NULL); if (string_no_color) { weechat_hashtable_set (extra_vars, "tg_string_nocolor", string_no_color); } /* add special variables for a WeeChat message */ if (strcmp (modifier, "weechat_print") == 0) { /* set "tg_prefix" and "tg_message" */ pos = strchr (string, '\t'); if (pos) { if (pos > string) { prefix = weechat_strndup (string, pos - string); if (prefix) { weechat_hashtable_set (extra_vars, "tg_prefix", prefix); free (prefix); } } pos++; if (pos[0] == '\t') pos++; weechat_hashtable_set (extra_vars, "tg_message", pos); } else weechat_hashtable_set (extra_vars, "tg_message", string); /* set "tg_prefix_nocolor" and "tg_message_nocolor" */ if (string_no_color) { pos = strchr (string_no_color, '\t'); if (pos) { if (pos > string_no_color) { prefix = weechat_strndup (string_no_color, pos - string_no_color); if (prefix) { weechat_hashtable_set (extra_vars, "tg_prefix_nocolor", prefix); free (prefix); } } pos++; if (pos[0] == '\t') pos++; weechat_hashtable_set (extra_vars, "tg_message_nocolor", pos); } else { weechat_hashtable_set (extra_vars, "tg_message_nocolor", string_no_color); } } /* * extract buffer/tags from modifier data * (format: "plugin;buffer_name;tags") */ pos = strchr (modifier_data, ';'); if (pos) { plugin_name = weechat_strndup (modifier_data, pos - modifier_data); if (plugin_name) { weechat_hashtable_set (extra_vars, "tg_plugin", plugin_name); pos++; pos2 = strchr (pos, ';'); if (pos2) { buffer_name = weechat_strndup (pos, pos2 - pos); if (buffer_name) { buffer = weechat_buffer_search (plugin_name, buffer_name); length = strlen (plugin_name) + 1 + strlen (buffer_name) + 1; buffer_full_name = malloc (length); if (buffer_full_name) { snprintf (buffer_full_name, length, "%s.%s", plugin_name, buffer_name); weechat_hashtable_set (extra_vars, "tg_buffer", buffer_full_name); free (buffer_full_name); } free (buffer_name); } pos2++; if (pos2[0]) { tags = weechat_string_split (pos2, ",", 0, 0, &num_tags); length = 1 + strlen (pos2) + 1 + 1; str_tags = malloc (length); if (str_tags) { snprintf (str_tags, length, ",%s,", pos2); weechat_hashtable_set (extra_vars, "tg_tags", str_tags); free (str_tags); } } } free (plugin_name); } } weechat_hashtable_set (pointers, "buffer", buffer); } if (tags) { if (!trigger_callback_set_tags (buffer, (const char **)tags, num_tags, extra_vars)) { goto end; } } /* execute the trigger (conditions, regex, command) */ trigger_callback_execute (trigger, buffer, pointers, extra_vars); end: ptr_string = weechat_hashtable_get (extra_vars, "tg_string"); string_modified = (ptr_string && (strcmp (ptr_string, string) != 0)) ? strdup (ptr_string) : NULL; if (tags) weechat_string_free_split (tags); if (string_no_color) free (string_no_color); TRIGGER_CALLBACK_CB_END(string_modified); }