Пример #1
0
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);
	}
}
Пример #2
0
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;
}
Пример #3
0
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);
	}
}
Пример #4
0
/* 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);
}
Пример #5
0
/* 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();
}
Пример #6
0
/* 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));
	}
}
Пример #7
0
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);
}
Пример #8
0
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);
	}
}
Пример #9
0
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. */
}
Пример #10
0
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);
}
Пример #11
0
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();
}
Пример #12
0
/* 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);
}
Пример #13
0
Файл: tls.c Проект: irssi/irssi
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);
}
Пример #14
0
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);
}
Пример #15
0
/* 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);
}
Пример #16
0
/* 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;
}
Пример #17
0
/* 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;
}
Пример #18
0
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;
}
Пример #19
0
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);
}
Пример #20
0
/* 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);
}
Пример #21
0
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;
}
Пример #22
0
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);
}
Пример #23
0
/* 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);
}
Пример #24
0
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);
}
Пример #25
0
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);
}
Пример #26
0
/* 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);
}
Пример #27
0
/* 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);
}
Пример #28
0
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);
}
Пример #29
0
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;
}
Пример #30
0
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);
}