static void sig_server_add_fill(SERVER_SETUP_REC *rec, GHashTable *optlist) { char *value; value = g_hash_table_lookup(optlist, "icqnet"); if (value != NULL) { g_free_and_null(rec->chatnet); if (*value != '\0') rec->chatnet = g_strdup(value); } }
int key_pressed(KEYBOARD_REC *keyboard, const char *key) { KEY_REC *rec; char *combo; int first_key, consumed; g_return_val_if_fail(keyboard != NULL, FALSE); g_return_val_if_fail(key != NULL && *key != '\0', FALSE); if (keyboard->timer_tag > 0) { g_source_remove(keyboard->timer_tag); keyboard->timer_tag = 0; } if (keyboard->key_state == NULL && key[1] == '\0' && !used_keys[(int) (unsigned char) key[0]]) { /* fast check - key not used */ return -1; } first_key = keyboard->key_state == NULL; combo = keyboard->key_state == NULL ? g_strdup(key) : g_strconcat(keyboard->key_state, "-", key, NULL); g_free_and_null(keyboard->key_state); rec = g_tree_search(key_states, (GCompareFunc) key_states_search, combo); if (rec == NULL) { /* unknown key combo, eat the invalid key unless it was the first key pressed */ g_free(combo); return first_key ? -1 : 1; } if (g_tree_lookup(key_states, combo) != rec) { /* key combo continues.. */ keyboard->key_state = combo; /* respect the timeout if specified by the user */ if (key_timeout > 0) { keyboard->timer_tag = g_timeout_add(key_timeout, (GSourceFunc) key_timeout_expired, keyboard); } return 0; } /* finished key combo, execute */ g_free(combo); consumed = key_emit_signal(keyboard, rec); /* never consume non-control characters */ return consumed ? 1 : -1; }
static void get_source_host_ip(void) { const char *hostname; IPADDR ip4, ip6; if (source_host_ok) return; /* FIXME: This will block! */ hostname = settings_get_str("hostname"); source_host_ok = *hostname != '\0' && net_gethostbyname(hostname, &ip4, &ip6) == 0; if (source_host_ok) save_ips(&ip4, &ip6, &source_host_ip4, &source_host_ip6); else { g_free_and_null(source_host_ip4); g_free_and_null(source_host_ip6); } }
/* SYNTAX: WINDOW SERVER [-sticky | -unsticky] <tag> */ static void cmd_window_server(const char *data) { GHashTable *optlist; SERVER_REC *server; char *tag; void *free_arg; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS, "window server", &optlist, &tag)) return; if (*tag == '\0' && active_win->active_server != NULL && (g_hash_table_lookup(optlist, "sticky") != NULL || g_hash_table_lookup(optlist, "unsticky") != NULL)) { tag = active_win->active_server->tag; } if (*tag == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); server = server_find_tag(tag); if (server == NULL) server = server_find_lookup_tag(tag); if (g_hash_table_lookup(optlist, "unsticky") != NULL && active_win->servertag != NULL) { g_free_and_null(active_win->servertag); printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_UNSET_SERVER_STICKY); } if (active_win->servertag != NULL && g_hash_table_lookup(optlist, "sticky") == NULL) { printformat_window(active_win, MSGLEVEL_CLIENTERROR, TXT_ERROR_SERVER_STICKY); } else if (server == NULL) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_UNKNOWN_SERVER_TAG, tag); } else if (active_win->active == NULL) { window_change_server(active_win, server); if (g_hash_table_lookup(optlist, "sticky") != NULL) { g_free_not_null(active_win->servertag); active_win->servertag = g_strdup(server->tag); printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_SET_SERVER_STICKY, server->tag); } printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_SERVER_CHANGED, server->tag, server->connrec->address, server->connrec->chatnet == NULL ? "" : server->connrec->chatnet); } cmd_params_free(free_arg); }
/* Don't send window activity if window is already visible in another mainwindow */ static void sig_activity(WINDOW_REC *window) { GSList *tmp; if (!is_window_visible(window) || window->data_level == 0) return; if (!settings_get_bool("activity_hide_visible")) return; window->data_level = 0; g_free_and_null(window->hilight_color); for (tmp = window->items; tmp != NULL; tmp = tmp->next) { WI_ITEM_REC *item = tmp->data; item->data_level = 0; g_free_and_null(item->hilight_color); } signal_stop(); }
/* Update own IPv4 and IPv6 records */ void server_connect_own_ip_save(SERVER_CONNECT_REC *conn, IPADDR *ip4, IPADDR *ip6) { if (ip4 == NULL || ip4->family == 0) g_free_and_null(conn->own_ip4); if (ip6 == NULL || ip6->family == 0) g_free_and_null(conn->own_ip6); if (ip4 != NULL && ip4->family != 0) { /* IPv4 address was found */ if (conn->own_ip4 == NULL) conn->own_ip4 = g_new0(IPADDR, 1); memcpy(conn->own_ip4, ip4, sizeof(IPADDR)); } if (ip6 != NULL && ip6->family != 0) { /* IPv6 address was found */ if (conn->own_ip6 == NULL) conn->own_ip6 = g_new0(IPADDR, 1); memcpy(conn->own_ip6, ip6, sizeof(IPADDR)); } }
void hilight_update_text_dest(TEXT_DEST_REC *dest, HILIGHT_REC *rec) { dest->level |= MSGLEVEL_HILIGHT; if (rec->priority > 0) dest->hilight_priority = rec->priority; g_free_and_null(dest->hilight_color); if (rec->act_color != NULL && strcmp(rec->act_color, "%n") == 0) dest->level |= MSGLEVEL_NO_ACT; else dest->hilight_color = hilight_get_act_color(rec); }
static void server_send_away(IRC_SERVER_REC *server, const char *reason) { if (!IS_IRC_SERVER(server)) return; if (*reason != '\0' || server->usermode_away) { g_free_and_null(server->away_reason); if (*reason != '\0') server->away_reason = g_strdup(reason); irc_send_cmdv(server, "AWAY :%s", reason); } }
static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl) { #ifdef SSL_get_server_tmp_key /* Show ephemeral key information. */ EVP_PKEY *ephemeral_key = NULL; /* OPENSSL_NO_EC is for solaris 11.3 (2016), github ticket #598 */ #ifndef OPENSSL_NO_EC EC_KEY *ec_key = NULL; #endif char *ephemeral_key_algorithm = NULL; char *cname = NULL; int nid; g_return_if_fail(tls != NULL); g_return_if_fail(ssl != NULL); if (SSL_get_server_tmp_key(ssl, &ephemeral_key)) { switch (EVP_PKEY_id(ephemeral_key)) { case EVP_PKEY_DH: tls_rec_set_ephemeral_key_algorithm(tls, "DH"); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); break; #ifndef OPENSSL_NO_EC case EVP_PKEY_EC: ec_key = EVP_PKEY_get1_EC_KEY(ephemeral_key); nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); EC_KEY_free(ec_key); cname = (char *)OBJ_nid2sn(nid); ephemeral_key_algorithm = g_strdup_printf("ECDH: %s", cname); tls_rec_set_ephemeral_key_algorithm(tls, ephemeral_key_algorithm); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); g_free_and_null(ephemeral_key_algorithm); break; #endif default: tls_rec_set_ephemeral_key_algorithm(tls, "Unknown"); tls_rec_set_ephemeral_key_size(tls, EVP_PKEY_bits(ephemeral_key)); break; } EVP_PKEY_free(ephemeral_key); } #endif /* SSL_get_server_tmp_key. */ }
static void handle_entry_redirect(const char *line) { ENTRY_REDIRECT_ENTRY_FUNC func; void *data; func = (ENTRY_REDIRECT_ENTRY_FUNC) redir->func; data = redir->data; g_free_and_null(redir); if (func != NULL) func(line, data, active_win->active_server, active_win->active); gui_entry_remove_perm_prompt(); window_update_prompt(active_win); }
static void handle_key_redirect(int key) { ENTRY_REDIRECT_KEY_FUNC func; void *data; func = (ENTRY_REDIRECT_KEY_FUNC) redir->func; data = redir->data; g_free_and_null(redir); if (func != NULL) func(key, data, active_win->active_server, active_win->active); gui_entry_remove_perm_prompt(); window_update_prompt(); }
/* SYNTAX: CHANNEL ADD [-auto | -noauto] [-bots <masks>] [-botcmd <command>] <channel> <chatnet> [<password>] */ static void cmd_channel_add(const char *data) { GHashTable *optlist; CHANNEL_SETUP_REC *rec; char *botarg, *botcmdarg, *chatnet, *channel, *password; void *free_arg; if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS, "channel add", &optlist, &channel, &chatnet, &password)) return; botarg = g_hash_table_lookup(optlist, "bots"); botcmdarg = g_hash_table_lookup(optlist, "botcmd"); if (*chatnet == '\0' || *channel == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); rec = channels_setup_find(channel, chatnet); if (rec == NULL) { rec = g_new0(CHANNEL_SETUP_REC, 1); rec->name = g_strdup(channel); rec->chatnet = g_strdup(chatnet); } else { if (g_hash_table_lookup(optlist, "bots")) g_free_and_null(rec->botmasks); if (g_hash_table_lookup(optlist, "botcmd")) g_free_and_null(rec->autosendcmd); if (*password != '\0') g_free_and_null(rec->password); } if (g_hash_table_lookup(optlist, "auto")) rec->autojoin = TRUE; if (g_hash_table_lookup(optlist, "noauto")) rec->autojoin = FALSE; if (botarg != NULL && *botarg != '\0') rec->botmasks = g_strdup(botarg); if (botcmdarg != NULL && *botcmdarg != '\0') rec->autosendcmd = g_strdup(botcmdarg); if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password); channels_setup_create(rec); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_CHANSETUP_ADDED, channel, chatnet); cmd_params_free(free_arg); }
void tls_rec_free(TLS_REC *tls_rec) { if (tls_rec == NULL) return; g_free_and_null(tls_rec->protocol_version); g_free_and_null(tls_rec->cipher); g_free_and_null(tls_rec->public_key_algorithm); g_free_and_null(tls_rec->public_key_fingerprint); g_free_and_null(tls_rec->public_key_fingerprint_algorithm); g_free_and_null(tls_rec->certificate_fingerprint); g_free_and_null(tls_rec->certificate_fingerprint_algorithm); g_free_and_null(tls_rec->not_after); g_free_and_null(tls_rec->not_before); g_free_and_null(tls_rec->ephemeral_key_algorithm); if (tls_rec->certs != NULL) { g_slist_foreach(tls_rec->certs, (GFunc)tls_cert_rec_free, NULL); g_slist_free(tls_rec->certs); tls_rec->certs = NULL; } g_free(tls_rec); }
static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, GHashTable *optlist) { char *value; value = g_hash_table_lookup(optlist, "ircnet"); if (value != NULL) { g_free_and_null(rec->chatnet); if (*value != '\0') rec->chatnet = g_strdup(value); } value = g_hash_table_lookup(optlist, "cmdspeed"); if (value != NULL && *value != '\0') rec->cmd_queue_speed = atoi(value); value = g_hash_table_lookup(optlist, "cmdmax"); if (value != NULL && *value != '\0') rec->max_cmds_at_once = atoi(value); }
/* Mode that needs parameter for both setting and removing (eg: +k) */ void modes_type_b(IRC_CHANNEL_REC *channel, const char *setby, char type, char mode, char *arg, GString *newmode) { if (mode == 'k') { if (*arg == '\0' && type == '+') arg = channel->key != NULL ? channel->key : "???"; if (arg != channel->key) { g_free_and_null(channel->key); if (type == '+') channel->key = g_strdup(arg); } } mode_set_arg(channel->server, newmode, type, mode, arg, FALSE); }
/* Transmit all data from buffer - return TRUE if the whole buffer was sent */ static int buffer_send(NET_SENDBUF_REC *rec) { int ret; ret = net_transmit(rec->handle, rec->buffer, rec->bufpos); if (ret < 0 || rec->bufpos == ret) { /* error/all sent - don't try to send it anymore */ g_free_and_null(rec->buffer); return TRUE; } if (ret > 0) { rec->bufpos -= ret; g_memmove(rec->buffer, rec->buffer+ret, rec->bufpos); } return FALSE; }
/* Returns TRUE if key press was consumed. Control characters should be sent as "^@" .. "^_" instead of #0..#31 chars, #127 should be sent as ^? */ int key_pressed(KEYBOARD_REC *keyboard, const char *key) { KEY_REC *rec; char *combo; int first_key, consumed; g_return_val_if_fail(keyboard != NULL, FALSE); g_return_val_if_fail(key != NULL && *key != '\0', FALSE); if (keyboard->key_state == NULL && key[1] == '\0' && !used_keys[(int) (unsigned char) key[0]]) { /* fast check - key not used */ return FALSE; } first_key = keyboard->key_state == NULL; combo = keyboard->key_state == NULL ? g_strdup(key) : g_strconcat(keyboard->key_state, "-", key, NULL); g_free_and_null(keyboard->key_state); #if GLIB_MAJOR_VERSION == 2 # define GSearchFunc GCompareFunc #endif rec = g_tree_search(key_states, (GSearchFunc) key_states_search, combo); if (rec == NULL) { /* unknown key combo, eat the invalid key unless it was the first key pressed */ g_free(combo); return !first_key; } if (g_tree_lookup(key_states, combo) != rec) { /* key combo continues.. */ keyboard->key_state = combo; return TRUE; } /* finished key combo, execute */ g_free(combo); consumed = key_emit_signal(keyboard, rec); /* never consume non-control characters */ return consumed; }
static gboolean key_timeout_expired(KEYBOARD_REC *keyboard) { KEY_REC *rec; keyboard->timer_tag = 0; /* So, the timeout has expired with the input queue full, let's see if * what we've got is bound to some action. */ rec = g_tree_lookup(key_states, keyboard->key_state); /* Drain the queue anyway. */ g_free_and_null(keyboard->key_state); if (rec != NULL) { (void)key_emit_signal(keyboard, rec); } return FALSE; }
void irc_server_send_away(IRC_SERVER_REC *server, const char *reason) { char *recoded = NULL; if (!IS_IRC_SERVER(server)) return; if (*reason != '\0' || server->usermode_away) { g_free_and_null(server->away_reason); if (*reason != '\0') { server->away_reason = g_strdup(reason); reason = recoded = recode_out(SERVER(server), reason, NULL); } irc_send_cmdv(server, "AWAY :%s", reason); } g_free(recoded); }
/* SYNTAX: WINDOW THEME [-delete] [<name>] */ static void cmd_window_theme(const char *data) { THEME_REC *theme; GHashTable *optlist; char *name; void *free_arg; if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS, "window theme", &optlist, &name)) return; if (g_hash_table_lookup(optlist, "delete") != NULL) { g_free_and_null(active_win->theme_name); printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_THEME_REMOVED); } else if (*name == '\0') { if (active_win->theme == NULL) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_THEME_DEFAULT); } else { theme = active_win->theme; printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_THEME, theme->name, theme->path); } } else { g_free_not_null(active_win->theme_name); active_win->theme_name = g_strdup(data); active_win->theme = theme = theme_load(data); if (theme != NULL) { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_WINDOW_THEME_CHANGED, theme->name, theme->path); } else { printformat_window(active_win, MSGLEVEL_CLIENTNOTICE, TXT_THEME_NOT_FOUND, data); } } cmd_params_free(free_arg); }
static int channel_rejoin(IRC_SERVER_REC *server, const char *channel) { IRC_CHANNEL_REC *chanrec; REJOIN_REC *rec; g_return_val_if_fail(IS_IRC_SERVER(server), 0); g_return_val_if_fail(channel != NULL, 0); chanrec = irc_channel_find(server, channel); if (chanrec == NULL || chanrec->joined) return 0; if (!settings_get_bool("channels_rejoin_unavailable")) { chanrec->left = TRUE; channel_destroy(CHANNEL(chanrec)); return 0; } rec = rejoin_find(server, channel); if (rec != NULL) { /* already exists */ rec->joining = FALSE; /* update channel key */ g_free_and_null(rec->key); if (channel_have_key(chanrec)) rec->key = g_strdup(chanrec->key); } else { /* new rejoin */ rec = g_new0(REJOIN_REC, 1); rec->channel = g_strdup(channel); if (channel_have_key(chanrec)) rec->key = g_strdup(chanrec->key); server->rejoin_channels = g_slist_append(server->rejoin_channels, rec); signal_emit("channel rejoin new", 2, server, rec); } chanrec->left = TRUE; channel_destroy(CHANNEL(chanrec)); return 1; }
static void print_line(TEXT_DEST_REC *dest, const char *text) { THEME_REC *theme; char *str, *tmp, *stripped; g_return_if_fail(dest != NULL); g_return_if_fail(text != NULL); theme = window_get_theme(dest->window); tmp = format_get_level_tag(theme, dest); str = !theme->info_eol ? format_add_linestart(text, tmp) : format_add_lineend(text, tmp); g_free_not_null(tmp); /* send both the formatted + stripped (for logging etc.) */ stripped = strip_codes(str); signal_emit_id(signal_print_text, 3, dest, str, stripped); g_free_and_null(dest->hilight_color); g_free(str); g_free(stripped); }
/* SYNTAX: SERVER ADD [-4 | -6] [-ssl] [-ssl_cert <cert>] [-ssl_pkey <pkey>] [-ssl_verify] [-ssl_cafile <cafile>] [-ssl_capath <capath>] [-auto | -noauto] [-ircnet <ircnet>] [-host <hostname>] [-cmdspeed <ms>] [-cmdmax <count>] [-port <port>] <address> [<port> [<password>]] */ static void sig_server_add_fill(IRC_SERVER_SETUP_REC *rec, GHashTable *optlist) { IRC_CHATNET_REC *ircnet; char *value; value = g_hash_table_lookup(optlist, "ircnet"); if (value != NULL) { g_free_and_null(rec->chatnet); if (*value != '\0') { ircnet = ircnet_find(value); rec->chatnet = ircnet != NULL ? g_strdup(ircnet->name) : g_strdup(value); } } value = g_hash_table_lookup(optlist, "cmdspeed"); if (value != NULL && *value != '\0') rec->cmd_queue_speed = atoi(value); value = g_hash_table_lookup(optlist, "cmdmax"); if (value != NULL && *value != '\0') rec->max_cmds_at_once = atoi(value); value = g_hash_table_lookup(optlist, "querychans"); if (value != NULL && *value != '\0') rec->max_query_chans = atoi(value); }
void session_set_binary(const char *path) { const char *envpath; char **paths, **tmp; char *str; g_free_and_null(irssi_binary); if (g_path_is_absolute(path)) { /* full path - easy */ irssi_binary = g_strdup(path); return; } if (strchr(path, G_DIR_SEPARATOR) != NULL) { /* relative path */ str = g_get_current_dir(); irssi_binary = g_strconcat(str, G_DIR_SEPARATOR_S, path, NULL); g_free(str); return; } /* we'll need to find it from path. */ envpath = g_getenv("PATH"); if (envpath == NULL) return; paths = g_strsplit(envpath, ":", -1); for (tmp = paths; *tmp != NULL; tmp++) { str = g_strconcat(*tmp, G_DIR_SEPARATOR_S, path, NULL); if (access(str, X_OK) == 0) { irssi_binary = str; break; } g_free(str); } g_strfreev(paths); }
static void event_whois(IRC_SERVER_REC *server, const char *data) { char *params, *nick, *user, *host, *realname; NOTIFY_NICK_REC *nickrec; NOTIFYLIST_REC *notify; g_return_if_fail(data != NULL); g_return_if_fail(server != NULL); params = event_get_params(data, 6, NULL, &nick, &user, &host, NULL, &realname); notify = notifylist_find(nick, server->connrec->chatnet); if (notify != NULL && !mask_match(SERVER(server), notify->mask, nick, user, host)) { /* user or host didn't match */ g_free(params); return; } nickrec = notify_nick_find(server, nick); if (nickrec != NULL) { g_free_not_null(last_notify_nick); last_notify_nick = g_strdup(nick); g_free_not_null(nickrec->user); g_free_not_null(nickrec->host); g_free_not_null(nickrec->realname); g_free_and_null(nickrec->awaymsg); nickrec->user = g_strdup(user); nickrec->host = g_strdup(host); nickrec->realname = g_strdup(realname); nickrec->away = FALSE; nickrec->host_ok = TRUE; nickrec->idle_ok = TRUE; } g_free(params); }
/* NOTE: -network replaces the old -ircnet flag. */ static void cmd_ignore(const char *data) { GHashTable *optlist; IGNORE_REC *rec; char *patternarg, *chanarg, *mask, *levels, *timestr, *servertag; char **channels; void *free_arg; int new_ignore, msecs, level, flags; if (*data == '\0') { cmd_ignore_show(); return; } if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST | PARAM_FLAG_STRIP_TRAILING_WS, "ignore", &optlist, &mask, &levels)) return; patternarg = g_hash_table_lookup(optlist, "pattern"); chanarg = g_hash_table_lookup(optlist, "channels"); servertag = g_hash_table_lookup(optlist, "network"); /* Allow -ircnet for backwards compatibility */ if (!servertag) servertag = g_hash_table_lookup(optlist, "ircnet"); if (*mask == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (*levels == '\0') levels = "ALL"; level = level2bits(levels, NULL); msecs = 0; timestr = g_hash_table_lookup(optlist, "time"); if (timestr != NULL) { if (!parse_time_interval(timestr, &msecs)) cmd_param_error(CMDERR_INVALID_TIME); } if (active_win->active_server != NULL && server_ischannel(active_win->active_server, mask)) { chanarg = mask; mask = NULL; } channels = (chanarg == NULL || *chanarg == '\0') ? NULL : g_strsplit(chanarg, ",", -1); flags = IGNORE_FIND_PATTERN; if (level & MSGLEVEL_NO_ACT) flags |= IGNORE_FIND_NOACT; if (level & MSGLEVEL_HIDDEN) flags |= IGNORE_FIND_HIDDEN; rec = ignore_find_full(servertag, mask, patternarg, channels, flags); new_ignore = rec == NULL; if (rec == NULL) { rec = g_new0(IGNORE_REC, 1); rec->mask = mask == NULL || *mask == '\0' || g_strcmp0(mask, "*") == 0 ? NULL : g_strdup(mask); rec->channels = channels; } else { g_free_and_null(rec->pattern); g_strfreev(channels); } rec->level = combine_level(rec->level, levels); if (rec->level == MSGLEVEL_NO_ACT) { /* If only NO_ACT was specified add all levels; it makes no * sense on its own. */ rec->level |= MSGLEVEL_ALL; } if (rec->level == MSGLEVEL_HIDDEN) { /* If only HIDDEN was specified add all levels; it makes no * sense on its own. */ rec->level |= MSGLEVEL_ALL; } if (new_ignore && rec->level == 0) { /* tried to unignore levels from nonexisting ignore */ printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_IGNORE_NOT_FOUND, rec->mask); g_free(rec->mask); g_strfreev(rec->channels); g_free(rec); cmd_params_free(free_arg); return; } rec->servertag = (servertag == NULL || *servertag == '\0') ? NULL : g_strdup(servertag); rec->pattern = (patternarg == NULL || *patternarg == '\0') ? NULL : g_strdup(patternarg); rec->exception = g_hash_table_lookup(optlist, "except") != NULL; rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL; rec->fullword = g_hash_table_lookup(optlist, "full") != NULL; rec->replies = g_hash_table_lookup(optlist, "replies") != NULL; if (msecs != 0) rec->unignore_time = time(NULL)+msecs/1000; if (new_ignore) ignore_add_rec(rec); else ignore_update_rec(rec); cmd_params_free(free_arg); }
/* Parse channel mode string */ void parse_channel_modes(IRC_CHANNEL_REC *channel, const char *setby, const char *mode) { GString *newmode; char *dup, *modestr, *arg, *curmode, type; g_return_if_fail(IS_IRC_CHANNEL(channel)); g_return_if_fail(mode != NULL); type = '+'; newmode = g_string_new(channel->mode); dup = modestr = g_strdup(mode); curmode = cmd_get_param(&modestr); while (*curmode != '\0') { if (HAS_MODE_ARG(type, *curmode)) { /* get the argument for the mode. since we're expecting argument, ignore the mode if there's no argument (shouldn't happen). */ arg = cmd_get_param(&modestr); if (*arg == '\0') { curmode++; continue; } } else { arg = NULL; } switch (*curmode) { case '+': case '-': type = *curmode; break; case 'b': if (type == '+') banlist_add(channel, arg, setby, time(NULL)); else banlist_remove(channel, arg); break; case 'e': if (type == '+') banlist_exception_add(channel, arg, setby, time(NULL)); else banlist_exception_remove(channel, arg); break; case 'I': if (type == '+') invitelist_add(channel, arg); else invitelist_remove(channel, arg); break; case 'o': if (g_strcasecmp(channel->server->nick, arg) == 0) channel->chanop = type == '+'; nick_mode_change(channel, arg, '@', type); break; case 'h': nick_mode_change(channel, arg, '%', type); break; case 'v': nick_mode_change(channel, arg, '+', type); break; case 'l': mode_set_arg(newmode, type, 'l', arg); channel->limit = type == '-' ? 0 : atoi(arg); break; case 'k': mode_set_arg(newmode, type, 'k', arg); g_free_and_null(channel->key); if (type == '+') channel->key = g_strdup(arg); break; default: mode_set(newmode, type, *curmode); break; } curmode++; } g_free(dup); if (strchr(channel->mode, 'k') == NULL && channel->key != NULL) { /* join was used with key but there's no key set in channel modes.. */ g_free(channel->key); channel->key = NULL; } if (strcmp(newmode->str, channel->mode) != 0) { g_free(channel->mode); channel->mode = g_strdup(newmode->str); signal_emit("channel mode changed", 1, channel); } g_string_free(newmode, TRUE); }
static void cmd_server_add(const char *data) { GHashTable *optlist; SERVER_SETUP_REC *rec; char *addr, *portstr, *password, *value, *chatnet; void *free_arg; int port; if (!cmd_get_params(data, &free_arg, 3 | PARAM_FLAG_OPTIONS, "server add", &optlist, &addr, &portstr, &password)) return; if (*addr == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); port = *portstr == '\0' ? DEFAULT_SERVER_ADD_PORT : atoi(portstr); chatnet = g_hash_table_lookup(optlist, "network"); rec = server_setup_find(addr, port, chatnet); if (rec == NULL) { rec = create_server_setup(optlist); if (rec == NULL) { cmd_params_free(free_arg); return; } rec->address = g_strdup(addr); rec->port = port; } else { value = g_hash_table_lookup(optlist, "port"); if (value != NULL && *value != '\0') rec->port = atoi(value); if (*password != '\0') g_free_and_null(rec->password); if (g_hash_table_lookup(optlist, "host")) { g_free_and_null(rec->own_host); rec->own_ip4 = rec->own_ip6 = NULL; } } if (g_hash_table_lookup(optlist, "6")) rec->family = AF_INET6; else if (g_hash_table_lookup(optlist, "4")) rec->family = AF_INET; if (g_hash_table_lookup(optlist, "ssl")) rec->use_ssl = TRUE; value = g_hash_table_lookup(optlist, "ssl_cert"); if (value != NULL && *value != '\0') rec->ssl_cert = g_strdup(value); value = g_hash_table_lookup(optlist, "ssl_pkey"); if (value != NULL && *value != '\0') rec->ssl_pkey = g_strdup(value); if (g_hash_table_lookup(optlist, "ssl_verify")) rec->ssl_verify = TRUE; value = g_hash_table_lookup(optlist, "ssl_cafile"); if (value != NULL && *value != '\0') rec->ssl_cafile = g_strdup(value); value = g_hash_table_lookup(optlist, "ssl_capath"); if (value != NULL && *value != '\0') rec->ssl_capath = g_strdup(value); if ((rec->ssl_cafile != NULL && rec->ssl_cafile[0] != '\0') || (rec->ssl_capath != NULL && rec->ssl_capath[0] != '\0')) rec->ssl_verify = TRUE; if ((rec->ssl_cert != NULL && rec->ssl_cert[0] != '\0') || rec->ssl_verify == TRUE) rec->use_ssl = TRUE; if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE; if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE; if (g_hash_table_lookup(optlist, "proxy")) rec->no_proxy = FALSE; if (g_hash_table_lookup(optlist, "noproxy")) rec->no_proxy = TRUE; if (*password != '\0' && strcmp(password, "-") != 0) rec->password = g_strdup(password); value = g_hash_table_lookup(optlist, "host"); if (value != NULL && *value != '\0') { rec->own_host = g_strdup(value); rec->own_ip4 = rec->own_ip6 = NULL; } signal_emit("server add fill", 2, rec, optlist); server_setup_add(rec); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_SETUPSERVER_ADDED, addr, port); cmd_params_free(free_arg); }
static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr, char **rawlog_file) { CHAT_PROTOCOL_REC *proto; SERVER_CONNECT_REC *conn; GHashTable *optlist; char *addr, *portstr, *password, *nick, *chatnet, *host, *tmp; void *free_arg; g_return_val_if_fail(data != NULL, NULL); if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_OPTIONS, "connect", &optlist, &addr, &portstr, &password, &nick)) return NULL; if (plus_addr != NULL) *plus_addr = *addr == '+'; if (*addr == '+') addr++; if (*addr == '\0') { signal_emit("error command", 1, GINT_TO_POINTER(CMDERR_NOT_ENOUGH_PARAMS)); cmd_params_free(free_arg); return NULL; } if (strcmp(password, "-") == 0) *password = '******'; /* check if -<chatnet> option is used to specify chat protocol */ proto = chat_protocol_find_net(optlist); /* connect to server */ chatnet = proto == NULL ? NULL : g_hash_table_lookup(optlist, proto->chatnet); if (chatnet == NULL) chatnet = g_hash_table_lookup(optlist, "network"); conn = server_create_conn(proto != NULL ? proto->id : -1, addr, atoi(portstr), chatnet, password, nick); if (proto == NULL) proto = chat_protocol_find_id(conn->chat_type); if (proto->not_initialized) { /* trying to use protocol that isn't yet initialized */ signal_emit("chat protocol unknown", 1, proto->name); server_connect_unref(conn); cmd_params_free(free_arg); return NULL; } if (strchr(addr, '/') != NULL) conn->unix_socket = TRUE; if (g_hash_table_lookup(optlist, "6") != NULL) conn->family = AF_INET6; else if (g_hash_table_lookup(optlist, "4") != NULL) conn->family = AF_INET; if (g_hash_table_lookup(optlist, "ssl") != NULL) conn->use_ssl = TRUE; if ((tmp = g_hash_table_lookup(optlist, "ssl_cert")) != NULL) conn->ssl_cert = g_strdup(tmp); if ((tmp = g_hash_table_lookup(optlist, "ssl_pkey")) != NULL) conn->ssl_pkey = g_strdup(tmp); if ((tmp = g_hash_table_lookup(optlist, "ssl_pass")) != NULL) conn->ssl_pass = g_strdup(tmp); if (g_hash_table_lookup(optlist, "ssl_verify") != NULL) conn->ssl_verify = TRUE; if ((tmp = g_hash_table_lookup(optlist, "ssl_cafile")) != NULL) conn->ssl_cafile = g_strdup(tmp); if ((tmp = g_hash_table_lookup(optlist, "ssl_capath")) != NULL) conn->ssl_capath = g_strdup(tmp); if ((conn->ssl_capath != NULL && conn->ssl_capath[0] != '\0') || (conn->ssl_cafile != NULL && conn->ssl_cafile[0] != '\0')) conn->ssl_verify = TRUE; if ((conn->ssl_cert != NULL && conn->ssl_cert[0] != '\0') || conn->ssl_verify) conn->use_ssl = TRUE; if (g_hash_table_lookup(optlist, "!") != NULL) conn->no_autojoin_channels = TRUE; if (g_hash_table_lookup(optlist, "noautosendcmd") != NULL) conn->no_autosendcmd = TRUE; if (g_hash_table_lookup(optlist, "noproxy") != NULL) g_free_and_null(conn->proxy); *rawlog_file = g_strdup(g_hash_table_lookup(optlist, "rawlog")); host = g_hash_table_lookup(optlist, "host"); if (host != NULL && *host != '\0') { IPADDR ip4, ip6; if (net_gethostbyname(host, &ip4, &ip6) == 0) server_connect_own_ip_save(conn, &ip4, &ip6); } cmd_params_free(free_arg); return conn; }
static void cmd_ignore(const char *data) { /* /IGNORE [-regexp | -word] [-pattern <pattern>] [-except] [-replies] [-channels <channel>] <mask> <levels> OR /IGNORE [-regexp | -word] [-pattern <pattern>] [-except] [-replies] <channels> <levels> */ GHashTable *optlist; IGNORE_REC *rec; char *patternarg, *chanarg, *mask, *levels, *key; char **channels; void *free_arg; int new_ignore; if (*data == '\0') { cmd_ignore_show(); return; } if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS | PARAM_FLAG_GETREST, "ignore", &optlist, &mask, &levels)) return; patternarg = g_hash_table_lookup(optlist, "pattern"); chanarg = g_hash_table_lookup(optlist, "channels"); if (*levels == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); if (ischannel(*mask)) { chanarg = mask; mask = ""; } channels = (chanarg == NULL || *chanarg == '\0') ? NULL : g_strsplit(replace_chars(chanarg, ',', ' '), " ", -1); rec = ignore_find(NULL, mask, channels); new_ignore = rec == NULL; if (rec == NULL) { rec = g_new0(IGNORE_REC, 1); rec->mask = *mask == '\0' ? NULL : g_strdup(mask); rec->channels = channels; } else { g_free_and_null(rec->pattern); g_strfreev(channels); } if (g_hash_table_lookup(optlist, "except") != NULL) { rec->except_level = combine_level(rec->except_level, levels); } else { ignore_split_levels(levels, &rec->level, &rec->except_level); } rec->pattern = (patternarg == NULL || *patternarg == '\0') ? NULL : g_strdup(patternarg); rec->regexp = g_hash_table_lookup(optlist, "regexp") != NULL; rec->fullword = g_hash_table_lookup(optlist, "word") != NULL; rec->replies = g_hash_table_lookup(optlist, "replies") != NULL; if (rec->level == 0 && rec->except_level == 0) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_UNIGNORED, rec->mask == NULL ? "" : rec->mask); } else { key = ignore_get_key(rec); levels = ignore_get_levels(rec->level, rec->except_level); printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, IRCTXT_IGNORED, key, levels); g_free(key); g_free(levels); } if (new_ignore) ignore_add_rec(rec); else ignore_update_rec(rec); cmd_params_free(free_arg); }