예제 #1
0
/* received msg to all ops in channel */
static void sig_message_irc_op_public(SERVER_REC *server, const char *msg,
				      const char *nick, const char *address,
				      const char *target)
{
	char *nickmode, *optarget, *prefix;
	const char *cleantarget;

	/* only skip here so the difference can be stored in prefix */
	cleantarget = fe_channel_skip_prefix(IRC_SERVER(server), target);
	prefix = g_strndup(target, cleantarget - target);

	/* and clean the rest here */
	cleantarget = get_visible_target(IRC_SERVER(server), cleantarget);

	nickmode = channel_get_nickmode(channel_find(server, cleantarget),
					nick);

	optarget = g_strconcat(prefix, cleantarget, NULL);

	printformat_module("fe-common/core", server, cleantarget,
			   MSGLEVEL_PUBLIC,
			   TXT_PUBMSG_CHANNEL,
			   nick, optarget, msg, nickmode);
	g_free(nickmode);
	g_free(optarget);
	g_free(prefix);
}
예제 #2
0
파일: irc-channels.c 프로젝트: Liaf/irssi
/* function for finding IRC channels - adds support for !channels */
static CHANNEL_REC *irc_channel_find_server(SERVER_REC *server,
					    const char *channel)
{
	GSList *tmp;
	char *fmt_channel;

	/* if 'channel' has no leading # this lookup is going to fail, add a
	 * octothorpe in front of it to handle this case. */
	fmt_channel = server_ischannel(SERVER(server), channel) ?
	    g_strdup(channel) :
	    g_strdup_printf("#%s", channel);

	for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
		CHANNEL_REC *rec = tmp->data;

		if (rec->chat_type != server->chat_type)
                        continue;

		/* check both !ABCDEchannel and !channel */
		if (IRC_SERVER(server)->nick_comp_func(fmt_channel, rec->name) == 0) {
			g_free(fmt_channel);
			return rec;
		}

		if (IRC_SERVER(server)->nick_comp_func(fmt_channel, rec->visible_name) == 0) {
			g_free(fmt_channel);
			return rec;
		}
	}

	g_free(fmt_channel);

	return NULL;
}
예제 #3
0
파일: irc-servers.c 프로젝트: dgl/irssi
static void send_message(SERVER_REC *server, const char *target,
			 const char *msg, int target_type)
{
	IRC_SERVER_REC *ircserver;
	CHANNEL_REC *channel;
	char *str;
	char *recoded;

        ircserver = IRC_SERVER(server);
	g_return_if_fail(ircserver != NULL);
	g_return_if_fail(target != NULL);
	g_return_if_fail(msg != NULL);

	if (*target == '!') {
		/* !chan -> !12345chan */
		channel = channel_find(server, target);
		if (channel != NULL &&
		    g_ascii_strcasecmp(channel->name, target) != 0)
			target = channel->name;
	}

	recoded = recode_out(SERVER(server), msg, target);
	str = g_strdup_printf("PRIVMSG %s :%s", target, recoded);
	irc_send_cmd_split(ircserver, str, 2, ircserver->max_msgs_in_cmd);
	g_free(str);
	g_free(recoded);
}
예제 #4
0
/* SYNTAX: WAIT [-<server tag>] <milliseconds> */
static void cmd_wait(const char *data, IRC_SERVER_REC *server)
{
	GHashTable *optlist;
	char *msecs;
	void *free_arg;
	int n;

        CMD_IRC_SERVER(server);

	if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST,
			    NULL, &optlist, &msecs))
		return;

	if (*msecs == '\0')
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	/* -<server tag> */
	server = IRC_SERVER(cmd_options_get_server(NULL, optlist,
						   SERVER(server)));

	n = atoi(msecs);
	if (server != NULL && n > 0) {
		g_get_current_time(&server->wait_cmd);
		server->wait_cmd.tv_sec += n/1000;
		server->wait_cmd.tv_usec += n%1000;
		if (server->wait_cmd.tv_usec >= 1000) {
			server->wait_cmd.tv_sec++;
			server->wait_cmd.tv_usec -= 1000;
		}
	}
	cmd_params_free(free_arg);
}
예제 #5
0
static void sig_message_own_public(SERVER_REC *server, const char *msg,
				   const char *target, const char *origtarget)
{
	const char *oldtarget;
	char *nickmode;

	if (!IS_IRC_SERVER(server))
		return;
	oldtarget = target;
	target = fe_channel_skip_prefix(IRC_SERVER(server), target);
	if (target != oldtarget) {
		/* Hybrid 6 / Bahamut feature, send msg to all
		   ops / ops+voices in channel */
		nickmode = channel_get_nickmode(channel_find(server, target),
						server->nick);

		printformat_module("fe-common/core", server, target,
				   MSGLEVEL_PUBLIC | MSGLEVEL_NOHILIGHT |
				   MSGLEVEL_NO_ACT,
				   TXT_OWN_MSG_CHANNEL,
				   server->nick, oldtarget, msg, nickmode);
		g_free(nickmode);
                signal_stop();
	}

}
예제 #6
0
/* SYNTAX: ACTION [-<server tag>] <target> <message> */
static void cmd_action(const char *data, IRC_SERVER_REC *server)
{
	GHashTable *optlist;
	const char *target, *text;
	char *subtext;
	char **splittexts;
	int n = 0;
	void *free_arg;

        CMD_IRC_SERVER(server);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST,
			    "action", &optlist, &target, &text))
		return;
	if (*target == '\0' || *text == '\0')
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	server = IRC_SERVER(cmd_options_get_server("action", optlist, SERVER(server)));
	if (server == NULL || !server->connected)
		cmd_param_error(CMDERR_NOT_CONNECTED);

	splittexts = irc_server_split_action(server, target, text);
	while ((subtext = splittexts[n++])) {
		irc_server_send_action(server, target, subtext);
		signal_emit("message irc own_action", 3, server, subtext,
			    target);
	}

	g_strfreev(splittexts);
	cmd_params_free(free_arg);
}
예제 #7
0
/* SYNTAX: ACTION [-<server tag>] <target> <message> */
static void cmd_action(const char *data, IRC_SERVER_REC *server)
{
	GHashTable *optlist;
	const char *target, *text;
	char *recoded;
	void *free_arg;

        CMD_IRC_SERVER(server);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_GETREST,
			    "action", &optlist, &target, &text))
		return;
	if (*target == '\0' || *text == '\0')
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	server = IRC_SERVER(cmd_options_get_server("action", optlist, SERVER(server)));
	if (server == NULL || !server->connected)
		cmd_param_error(CMDERR_NOT_CONNECTED);

	recoded = recode_out(SERVER(server), text, target);
	irc_send_cmdv(server, "PRIVMSG %s :\001ACTION %s\001", target, recoded);

	signal_emit("message irc own_action", 3, server, recoded, target);

	g_free(recoded);
	cmd_params_free(free_arg);
}
예제 #8
0
파일: dcc-send.c 프로젝트: svn2github/irssi
static void dcc_queue_send_next(int queue)
{
	IRC_SERVER_REC *server;
        DCC_QUEUE_REC *qrec;
	int send_started = FALSE;

	while ((qrec = dcc_queue_get_next(queue)) != NULL && !send_started) {
		server = qrec->servertag == NULL ? NULL :
			IRC_SERVER(server_find_tag(qrec->servertag));

		if (server == NULL && qrec->chat == NULL) {
			/* no way to send this request */
			signal_emit("dcc error send no route", 2,
				    qrec->nick, qrec->file);
		} else {
			send_started = dcc_send_one_file(queue, qrec->nick,
							 qrec->file, server,
							 qrec->chat);
		}
                dcc_queue_remove_head(queue);
	}

	if (!send_started) {
		/* no files in queue anymore, remove it */
		dcc_queue_free(queue);
	}
}
예제 #9
0
static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg,
				   const char *nick, const char *address,
				   const char *target)
{
	void *item;
	const char *oldtarget;
        char *freemsg = NULL;
	int level;
	int own = FALSE;

	oldtarget = target;
	target = fe_channel_skip_prefix(IRC_SERVER(server), target);

	level = MSGLEVEL_ACTIONS |
		(server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS);

	if (ignore_check_plus(SERVER(server), nick, address, target, msg, &level, TRUE))
		return;

	if (server_ischannel(SERVER(server), target)) {
		item = irc_channel_find(server, target);
	} else {
		own = (!g_strcmp0(nick, server->nick));
		item = privmsg_get_query(SERVER(server), own ? target : nick, FALSE, level);
	}

	if (settings_get_bool("emphasis"))
		msg = freemsg = expand_emphasis(item, msg);

	if (server_ischannel(SERVER(server), target)) {
		/* channel action */
		if (window_item_is_active(item) && target == oldtarget) {
			/* message to active channel in window */
			printformat(server, target, level,
				    IRCTXT_ACTION_PUBLIC, nick, msg);
		} else {
			/* message to not existing/active channel, or to @/+ */
			printformat(server, target, level,
				    IRCTXT_ACTION_PUBLIC_CHANNEL,
				    nick, oldtarget, msg);
		}
	} else {
		if (own) {
			/* own action bounced */
			printformat(server, target,
				    MSGLEVEL_ACTIONS | MSGLEVEL_MSGS,
				    item != NULL && oldtarget == target ? IRCTXT_OWN_ACTION : IRCTXT_OWN_ACTION_TARGET,
				    server->nick, msg, oldtarget);
		} else {
			/* private action */
			printformat(server, nick, MSGLEVEL_ACTIONS | MSGLEVEL_MSGS,
				    item == NULL ? IRCTXT_ACTION_PRIVATE :
				    IRCTXT_ACTION_PRIVATE_QUERY,
				    nick, address == NULL ? "" : address, msg);
		}
	}

	g_free_not_null(freemsg);
}
예제 #10
0
파일: listen.c 프로젝트: Manishearth/irssi
static void sig_listen(LISTEN_REC *listen)
{
	CLIENT_REC *rec;
	IPADDR ip;
	NET_SENDBUF_REC *sendbuf;
        GIOChannel *handle;
	char host[MAX_IP_LEN];
	int port;

	g_return_if_fail(listen != NULL);

	/* accept connection */
	handle = net_accept(listen->handle, &ip, &port);
	if (handle == NULL)
		return;
	net_ip2host(&ip, host);
	sendbuf = net_sendbuffer_create(handle, 0);
	rec = g_new0(CLIENT_REC, 1);
	rec->listen = listen;
	rec->handle = sendbuf;
        rec->host = g_strdup(host);
	rec->port = port;
	if (g_strcmp0(listen->ircnet, "*") == 0) {
		rec->proxy_address = g_strdup("irc.proxy");
		rec->server = servers == NULL ? NULL : IRC_SERVER(servers->data);
	} else {
		rec->proxy_address = g_strdup_printf("%s.proxy", listen->ircnet);
		rec->server = servers == NULL ? NULL :
			IRC_SERVER(server_find_chatnet(listen->ircnet));
	}
	rec->recv_tag = g_input_add(handle, G_INPUT_READ,
			       (GInputFunction) sig_listen_client, rec);

	proxy_clients = g_slist_prepend(proxy_clients, rec);
	rec->listen->clients = g_slist_prepend(rec->listen->clients, rec);

	signal_emit("proxy client connecting", 1, rec);
	printtext(rec->server, NULL, MSGLEVEL_CLIENTNOTICE,
		  "Proxy: New client %s:%d on port %d (%s)",
		  rec->host, rec->port, listen->port, listen->ircnet);
}
예제 #11
0
/* function for finding IRC channels - adds support for !channels */
static CHANNEL_REC *irc_channel_find_server(SERVER_REC *server,
					    const char *channel)
{
	GSList *tmp;

	for (tmp = server->channels; tmp != NULL; tmp = tmp->next) {
		CHANNEL_REC *rec = tmp->data;

		if (rec->chat_type != server->chat_type)
                        continue;

		/* check both !ABCDEchannel and !channel */
		if (IRC_SERVER(server)->nick_comp_func(channel, rec->name) == 0)
			return rec;

		if (IRC_SERVER(server)->nick_comp_func(channel, rec->visible_name) == 0)
			return rec;
	}

	return NULL;
}
예제 #12
0
static void sig_message_irc_action(IRC_SERVER_REC *server, const char *msg,
				   const char *nick, const char *address,
				   const char *target)
{
	void *item;
	const char *oldtarget;
        char *freemsg = NULL;
	int level;

	oldtarget = target;
	target = skip_target(IRC_SERVER(server), target);

	level = MSGLEVEL_ACTIONS |
		(ischannel(*target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS);

	if (ignore_check(SERVER(server), nick, address, target, msg, level))
		return;

	if (ignore_check(SERVER(server), nick, address, target, msg,
			 level | MSGLEVEL_NO_ACT))
		level |= MSGLEVEL_NO_ACT;

	if (ischannel(*target))
		item = irc_channel_find(server, target);
        else
		item = privmsg_get_query(SERVER(server), nick, FALSE, level);

	if (settings_get_bool("emphasis"))
		msg = freemsg = expand_emphasis(item, msg);

	if (ischannel(*target)) {
		/* channel action */
		if (window_item_is_active(item) && target == oldtarget) {
			/* message to active channel in window */
			printformat(server, target, level,
				    IRCTXT_ACTION_PUBLIC, nick, msg);
		} else {
			/* message to not existing/active channel, or to @/+ */
			printformat(server, target, level,
				    IRCTXT_ACTION_PUBLIC_CHANNEL,
				    nick, oldtarget, msg);
		}
	} else {
		/* private action */
		printformat(server, nick, MSGLEVEL_ACTIONS | MSGLEVEL_MSGS,
			    item == NULL ? IRCTXT_ACTION_PRIVATE :
			    IRCTXT_ACTION_PRIVATE_QUERY,
			    nick, address == NULL ? "" : address, msg);
	}
	
	g_free_not_null(freemsg);
}
예제 #13
0
파일: test-796.c 프로젝트: dequis/irssi
static void test_server_destroy_flood(ServerDestroyFloodData *fixture, const void *data)
{
	SERVER_REC *server; /* = g_new0(IRC_SERVER_REC, 1); */
	CHAT_PROTOCOL_REC *proto;
	SERVER_CONNECT_REC *conn;
	GLogLevelFlags loglev;

	g_test_bug("796");

	/* for the purpose of this exercise, we are ignoring the
	   errors of g_hash_table_lookup failure */
	loglev = g_log_set_always_fatal(G_LOG_FATAL_MASK);

	proto = chat_protocol_find("IRC");
	conn = server_create_conn(proto->id, "localhost", 0, "", "", "user");
	server = proto->server_init_connect(conn);
	server->session_reconnect = TRUE;
	server->tag = g_strdup("testserver");

	g_test_message("created server: %p", server);

	/* we skip some initialisations that would try to send data */
	/* irc_servers_deinit(); */
	irc_session_deinit();
	irc_irc_deinit();


	server_connect_finished(server);

	/* make up for the skipped session init */
	irc_server_init_bare_minimum(IRC_SERVER(server));

	irc_irc_init();
	irc_session_init();
	/* irc_servers_init(); */

	/* simulate failing irc_server_send_data() */
	server->connection_lost = TRUE;

	/*
	chat_completion_deinit();
	fe_messages_deinit();
	irc_notifylist_deinit();
	*/

	server_ref(server);
	signal_emit("event privmsg", 4, server, "#someroom :test message", "nick", "user@host");
	server_unref(server);

	g_log_set_always_fatal(loglev);
}
예제 #14
0
static void sig_message_irc_notice(SERVER_REC *server, const char *msg,
				   const char *nick, const char *address,
				   const char *target)
{
	const char *oldtarget;
	int level = MSGLEVEL_NOTICES;

	oldtarget = target;
	target = fe_channel_skip_prefix(IRC_SERVER(server), target);

	if (address == NULL || *address == '\0') {
		level = MSGLEVEL_SNOTES;
		/* notice from server */
		if (!ignore_check_plus(server, nick, "",
				       target, msg, &level, TRUE)) {
			printformat(server, target, level,
				    IRCTXT_NOTICE_SERVER, nick, msg);
		}
                return;
	}

	if (ignore_check_plus(server, nick, address,
			 server_ischannel(SERVER(server), target) ? target : NULL,
			      msg, &level, TRUE))
		return;

	if (server_ischannel(SERVER(server), target)) {
		/* notice in some channel */
		printformat(server, target, level,
			    IRCTXT_NOTICE_PUBLIC, nick, oldtarget, msg);
	} else {
		char *channel;
		/* check if this is a cnotice */
		channel = notice_channel_context(server, msg);

		if (channel == NULL) {
			/* private notice */
			privmsg_get_query(SERVER(server), nick, FALSE, MSGLEVEL_NOTICES);
		}
		printformat(server, channel == NULL ? nick : channel, level, IRCTXT_NOTICE_PRIVATE,
		            nick, address, msg);

		g_free(channel);
	}
}
예제 #15
0
static void sig_message_irc_notice(SERVER_REC *server, const char *msg,
				   const char *nick, const char *address,
				   const char *target)
{
	const char *oldtarget;
	int level = MSGLEVEL_NOTICES;
	
	oldtarget = target;
	target = skip_target(IRC_SERVER(server), target);

	if (address == NULL || *address == '\0') {
		/* notice from server */
		if (!ignore_check(server, nick, "",
				  target, msg, MSGLEVEL_SNOTES)) {
			printformat(server, target, MSGLEVEL_SNOTES,
				    IRCTXT_NOTICE_SERVER, nick, msg);
		}
                return;
	}

	if (ignore_check(server, nick, address,
			 ischannel(*target) ? target : NULL,
			 msg, level))
		return;

	if (ignore_check(server, nick, address,
			 ischannel(*target) ? target : NULL,
			 msg, level | MSGLEVEL_NO_ACT))
		level |= MSGLEVEL_NO_ACT;

        if (ischannel(*target)) {
		/* notice in some channel */
		printformat(server, target, level,
			    IRCTXT_NOTICE_PUBLIC, nick, oldtarget, msg);
	} else {
		/* private notice */
		privmsg_get_query(SERVER(server), nick, FALSE,
				  MSGLEVEL_NOTICES);
		printformat(server, nick, level,
			    IRCTXT_NOTICE_PRIVATE, nick, address, msg);
	}
}
예제 #16
0
파일: fe-netjoin.c 프로젝트: mmuman/irssi
/* something is going to be printed to screen, print our current netsplit
   message before it. */
static void sig_print_starting(TEXT_DEST_REC *dest)
{
	NETJOIN_SERVER_REC *rec;

	if (printing_joins)
		return;

	if (!IS_IRC_SERVER(dest->server))
		return;

	if (!(dest->level & MSGLEVEL_PUBLIC))
		return;

	if (!server_ischannel(dest->server, dest->target))
		return;

	rec = netjoin_find_server(IRC_SERVER(dest->server));
	if (rec != NULL && rec->netjoins != NULL)
		print_netjoins(rec, dest->target);
}
예제 #17
0
/* your /userhost $N address (user@host) */
static char *expando_userhost(SERVER_REC *server, void *item, int *free_ret)
{
	IRC_SERVER_REC *ircserver;
	const char *username;
	char hostname[100];

	ircserver = IRC_SERVER(server);

	/* prefer the _real_ /userhost reply */
	if (ircserver != NULL && ircserver->userhost != NULL)
		return ircserver->userhost;

	/* haven't received userhost reply yet. guess something */
	*free_ret = TRUE;
	if (ircserver == NULL)
		username = settings_get_str("user_name");
	else
		username = ircserver->connrec->username;

	if (gethostname(hostname, sizeof(hostname)) != 0 || *hostname == '\0')
		strcpy(hostname, "??");
	return g_strconcat(username, "@", hostname, NULL);;
}
예제 #18
0
파일: dcc-chat.c 프로젝트: irssi/irssi
/* DCC CLOSE CHAT <nick> - check only from chat_ids in open DCC chats,
   the default handler will check from DCC chat requests */
static void cmd_dcc_close(char *data, SERVER_REC *server)
{
	GSList *tmp, *next;
	char *nick;
	void *free_arg;
	int found;

	g_return_if_fail(data != NULL);

	if (g_ascii_strncasecmp(data, "CHAT ", 5) != 0 ||
	    !cmd_get_params(data, &free_arg, 2, NULL, &nick))
		return;

	if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	found = FALSE;
	for (tmp = dcc_conns; tmp != NULL; tmp = next) {
		CHAT_DCC_REC *dcc = tmp->data;

		next = tmp->next;
		if (IS_DCC_CHAT(dcc) && dcc->id != NULL &&
		    g_ascii_strcasecmp(dcc->id, nick) == 0) {
			found = TRUE;
			if (!dcc_is_connected(dcc) && IS_IRC_SERVER(server))
				dcc_reject(DCC(dcc), IRC_SERVER(server));
			else {
				/* don't send DCC REJECT after DCC chat
				   is already open */
				dcc_close(DCC(dcc));
			}
		}
	}

	if (found) signal_stop();

	cmd_params_free(free_arg);
}
예제 #19
0
static void sig_message_own_action(IRC_SERVER_REC *server, const char *msg,
                                   const char *target)
{
	void *item;
	const char *oldtarget;
        char *freemsg = NULL;

	oldtarget = target;
	target = fe_channel_skip_prefix(IRC_SERVER(server), target);
	if (server_ischannel(SERVER(server), target))
		item = irc_channel_find(server, target);
	else
		item = irc_query_find(server, target);

	if (settings_get_bool("emphasis"))
		msg = freemsg = expand_emphasis(item, msg);

	printformat(server, target,
		    MSGLEVEL_ACTIONS | MSGLEVEL_NOHILIGHT | MSGLEVEL_NO_ACT |
		    (server_ischannel(SERVER(server), target) ? MSGLEVEL_PUBLIC : MSGLEVEL_MSGS),
		    item != NULL && oldtarget == target ? IRCTXT_OWN_ACTION : IRCTXT_OWN_ACTION_TARGET,
		    server->nick, msg, oldtarget);
        g_free_not_null(freemsg);
}
예제 #20
0
/* your hostname address (host) */
static char *expando_hostname(SERVER_REC *server, void *item, int *free_ret)
{
	IRC_SERVER_REC *ircserver;
	char hostname[HOST_NAME_MAX];
	char **list;
	char *hostname_split;

	ircserver = IRC_SERVER(server);

	*free_ret = TRUE;

	/* prefer the _real_ /userhost reply */
	if (ircserver != NULL && ircserver->userhost != NULL) {
		list = g_strsplit(ircserver->userhost, "@", -1);
		hostname_split = g_strdup(list[1]);
		g_strfreev(list);
		return hostname_split;
	}

	/* haven't received userhost reply yet. guess something */
	if (gethostname(hostname, sizeof(hostname)) != 0 || *hostname == '\0')
		strcpy(hostname, "(none)");
	return g_strdup(hostname);
}
예제 #21
0
/* current server name */
static char *expando_servername(SERVER_REC *server, void *item, int *free_ret)
{
	IRC_SERVER_REC *ircserver = IRC_SERVER(server);

	return ircserver == NULL ? "" : ircserver->real_address;
}
예제 #22
0
/* SYNTAX: SERVER [-ircnet <ircnet>] [-host <hostname>]
                  [+]<address>|<ircnet> [<port> [<password> [<nick>]]] */
static void cmd_server(const char *data, IRC_SERVER_REC *server,
		       void *item)
{
	GHashTable *optlist;
	IRC_SERVER_CONNECT_REC *conn;
	char *addr, *port, *channels, *away_reason, *usermode, *ircnet;
	void *free_arg;
	int no_old_server;

	g_return_if_fail(data != NULL);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS,
			    "connect", &optlist, &addr, &port))
		return;

	if (*addr == '\0' || strcmp(addr, "+") == 0)
		cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	conn = server == NULL ? NULL : server->connrec;
	if (*addr != '+' && conn == NULL) {
		/* check if there's a server waiting for removal in
		   reconnection queue.. */
		RECONNECT_REC *rec;

		rec = find_reconnect_server(addr, atoi(port));
		if (rec != NULL) {
			/* remove the reconnection.. */
                        conn = (IRC_SERVER_CONNECT_REC *) rec->conn;
			server_reconnect_destroy(rec, FALSE);
		}
	}

	no_old_server = server == NULL;
	ircnet = conn == NULL ? NULL : g_strdup(conn->chatnet);
	if (*addr == '+' || conn == NULL) {
		channels = away_reason = usermode = NULL;
	} else if (server != NULL) {
		channels = irc_server_get_channels((IRC_SERVER_REC *) server);
		if (*channels == '\0')
			g_free_and_null(channels);
		away_reason = !server->usermode_away ? NULL :
			g_strdup(server->away_reason);
		usermode = g_strdup(server->usermode);
		signal_emit("command disconnect", 3,
			    "* Changing server", server, item);
	} else {
		channels = g_strdup(conn->channels);
		away_reason = g_strdup(conn->away_reason);
		usermode = g_strdup(conn->usermode);
	}

	server = IRC_SERVER(irc_connect_server(data));
	if (*addr == '+' || server == NULL ||
	    (ircnet != NULL && server->connrec->chatnet != NULL &&
	     g_strcasecmp(ircnet, server->connrec->chatnet) != 0)) {
		g_free_not_null(channels);
		g_free_not_null(usermode);
		g_free_not_null(away_reason);
	} else if (server != NULL && conn != NULL) {
		server->connrec->reconnection = TRUE;
		server->connrec->channels = channels;
		server->connrec->usermode = usermode;
		server->connrec->away_reason = away_reason;
		if (no_old_server)
			server_connect_free(SERVER_CONNECT(conn));
	}
	g_free_not_null(ircnet);
	cmd_params_free(free_arg);
}
예제 #23
0
/* SYNTAX: WHOIS [-<server tag>] [<server>] [<nicks>] */
static void cmd_whois(const char *data, IRC_SERVER_REC *server,
		      WI_ITEM_REC *item)
{
	GHashTable *optlist;
	char *qserver, *query, *event_402, *str;
	void *free_arg;
	int free_nick;

        CMD_IRC_SERVER(server);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTIONS |
			    PARAM_FLAG_UNKNOWN_OPTIONS,
			    "whois", &optlist, &qserver, &query))
		return;

	/* -<server tag> */
	server = IRC_SERVER(cmd_options_get_server("whois", optlist,
						   SERVER(server)));
	if (server == NULL) {
		cmd_params_free(free_arg);
		return;
	}

	if (*query == '\0') {
		query = qserver;
		qserver = "";
	}
	if (*query == '\0') {
		QUERY_REC *queryitem = QUERY(item);
		if (queryitem == NULL)
			query = server->nick;
		else
			query = qserver = queryitem->name;
	}

	if (strcmp(query, "*") == 0 &&
	    g_hash_table_lookup(optlist, "yes") == NULL)
		cmd_param_error(CMDERR_NOT_GOOD_IDEA);

	event_402 = "event 402";
	if (*qserver == '\0')
		g_string_sprintf(tmpstr, "WHOIS %s", query);
	else {
		g_string_sprintf(tmpstr, "WHOIS %s %s", qserver, query);
		if (g_strcasecmp(qserver, query) == 0)
			event_402 = "whois event not found";
	}

	query = get_redirect_nicklist(query, &free_nick);

	str = g_strconcat(qserver, " ", query, NULL);
	server_redirect_event(server, "whois", 1, str, TRUE,
		      NULL,
		      "event 318", "whois end",
		      "event 402", event_402,
		      "event 301", "whois away", /* 301 can come as a reply to /MSG, /WHOIS or /WHOWAS */
		      "event 313", "whois oper",
		      "event 401", (settings_get_bool("auto_whowas") ? "whois try whowas" : "whois event not found"),
		      "event 311", "whois event",
		      "", "whois default event", NULL);
        g_free(str);

	server->whois_found = FALSE;
	irc_send_cmd_split(server, tmpstr->str, 2, server->max_whois_in_cmd);

	if (free_nick) g_free(query);
	cmd_params_free(free_arg);
}
예제 #24
0
static void irc_channels_join(IRC_SERVER_REC *server, const char *data,
			      int automatic)
{
	CHANNEL_SETUP_REC *schannel;
	IRC_CHANNEL_REC *chanrec;
	GString *outchans, *outkeys;
	char *channels, *keys, *key;
	char **chanlist, **keylist, **tmp, **tmpkey, *channel, *channame;
	void *free_arg;
	int use_keys;

	g_return_if_fail(data != NULL);
	g_return_if_fail(IS_IRC_SERVER(server) && server->connected);
	if (*data == '\0') return;

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
			    &channels, &keys))
		return;

        chanlist = g_strsplit(channels, ",", -1);
	keylist = g_strsplit(keys, ",", -1);

	outchans = g_string_new(NULL);
	outkeys = g_string_new(NULL);

	use_keys = *keys != '\0';
	tmpkey = keylist;
	for (tmp = chanlist; *tmp != NULL; tmp++) {
		channel = ischannel(**tmp) ? g_strdup(*tmp) :
			g_strdup_printf("#%s", *tmp);

		chanrec = irc_channel_find(server, channel);
		if (chanrec == NULL) {
			schannel = channel_setup_find(channel, server->connrec->chatnet);

                        g_string_sprintfa(outchans, "%s,", channel);
                        if (*tmpkey != NULL && **tmpkey != '\0')
                        	key = *tmpkey;
                        else if (schannel != NULL && schannel->password != NULL) {
				/* get password from setup record */
                                use_keys = TRUE;
				key = schannel->password;
			} else key = NULL;

			g_string_sprintfa(outkeys, "%s,", get_join_key(key));
			channame = channel + (channel[0] == '!' &&
					      channel[1] == '!');
			chanrec = irc_channel_create(server, channame,
						     automatic);
			if (key != NULL) chanrec->key = g_strdup(key);
		}
		g_free(channel);

		if (*tmpkey != NULL)
                        tmpkey++;
	}

	if (outchans->len > 0) {
		g_string_truncate(outchans, outchans->len-1);
		g_string_truncate(outkeys, outkeys->len-1);
		irc_send_cmdv(IRC_SERVER(server),
			      use_keys ? "JOIN %s %s" : "JOIN %s",
			      outchans->str, outkeys->str);
	}

	g_string_free(outchans, TRUE);
	g_string_free(outkeys, TRUE);

	g_strfreev(chanlist);
	g_strfreev(keylist);

	cmd_params_free(free_arg);
}
예제 #25
0
/* redraw nick */
static void statusbar_nick(SBAR_ITEM_REC *item, int ypos)
{
	CHANNEL_REC *channel;
	SERVER_REC *server;
	IRC_SERVER_REC *ircserver;
	NICK_REC *nickrec;
	int size_needed;
	int umode_size;
	char nick[10];

	server = active_win == NULL ? NULL : active_win->active_server;
	ircserver = IRC_SERVER(server);

	umode_size = ircserver == NULL || ircserver->usermode == NULL ||
		ircserver->usermode[0] == '\0' ? 0 :
		strlen(ircserver->usermode)+3;

	/* nick */
	if (server == NULL || server->nick == NULL) {
		nick[0] = '\0';
		nickrec = NULL;
	} else {
		strncpy(nick, server->nick, 9);
		nick[9] = '\0';

		channel = CHANNEL(active_win->active);
		nickrec = channel == NULL ? NULL :
			nicklist_find(channel, server->nick);
	}

	size_needed = 2 + strlen(nick) + umode_size +
		(server != NULL && server->usermode_away ? 7 : 0) +
		(nickrec != NULL && (nickrec->op || nickrec->voice) ? 1 : 0); /* @ + */

	if (item->size != size_needed) {
		/* we need more (or less..) space! */
		statusbar_item_resize(item, size_needed);
		return;
	}

	/* size ok, draw the nick */
	move(ypos, item->xpos);

	set_color(stdscr, sbar_color_dim); addch('[');
	if (nickrec != NULL && (nickrec->op || nickrec->voice)) {
		set_color(stdscr, sbar_color_bold);
		addch(nickrec->op ? '@' : '+');
	}
	set_color(stdscr, sbar_color_normal); addstr(nick);
	if (umode_size) {
		set_color(stdscr, sbar_color_bold); addch('(');
		set_color(stdscr, sbar_color_dim); addch('+');
		set_color(stdscr, sbar_color_normal); addstr(ircserver->usermode);
		set_color(stdscr, sbar_color_bold); addch(')');
	}
	if (server != NULL && server->usermode_away) {
		set_color(stdscr, sbar_color_normal); addstr(" (");
		set_color(stdscr, sbar_color_away); addstr("zZzZ");
		set_color(stdscr, sbar_color_normal); addch(')');
	}
	set_color(stdscr, sbar_color_dim); addch(']');
	screen_refresh(NULL);
}
예제 #26
0
/* user mode in active server */
static char *expando_usermode(SERVER_REC *server, void *item, int *free_ret)
{
	return IS_IRC_SERVER(server) ? IRC_SERVER(server)->usermode : "";
}
예제 #27
0
static void irc_channels_join(IRC_SERVER_REC *server, const char *data,
			      int automatic)
{
	CHANNEL_SETUP_REC *schannel;
	IRC_CHANNEL_REC *chanrec;
	GString *outchans, *outkeys;
	char *channels, *keys, *key, *space;
	char **chanlist, **keylist, **tmp, **tmpkey, **tmpstr, *channel, *channame;
	void *free_arg;
	int use_keys, cmdlen;

	g_return_if_fail(data != NULL);
	g_return_if_fail(IS_IRC_SERVER(server) && server->connected);
	if (*data == '\0') return;

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST,
			    &channels, &keys))
		return;

	/* keys shouldn't contain space */
	space = strchr(keys, ' ');
	if (space != NULL) {
		*space = '\0';
	}

        chanlist = g_strsplit(channels, ",", -1);
	keylist = g_strsplit(keys, ",", -1);

	outchans = g_string_new(NULL);
	outkeys = g_string_new(NULL);

	use_keys = *keys != '\0';
	tmpkey = keylist;
	tmp = chanlist;
	for (;; tmp++) {
		if (*tmp !=  NULL) {
			channel = ischannel(**tmp) ? g_strdup(*tmp) :
			g_strdup_printf("#%s", *tmp);

			chanrec = irc_channel_find(server, channel);
			if (chanrec == NULL) {
				schannel = channel_setup_find(channel, server->connrec->chatnet);

				g_string_sprintfa(outchans, "%s,", channel);
				if (*tmpkey != NULL && **tmpkey != '\0')
                        		key = *tmpkey;
	                        else if (schannel != NULL && schannel->password != NULL) {
					/* get password from setup record */
                	                use_keys = TRUE;
					key = schannel->password;
				} else key = NULL;
				
				g_string_sprintfa(outkeys, "%s,", get_join_key(key));
				channame = channel + (channel[0] == '!' &&
						      channel[1] == '!');
				chanrec = irc_channel_create(server, channame, NULL,
							     automatic);
				if (key != NULL) chanrec->key = g_strdup(key);
			}
			g_free(channel);

			if (*tmpkey != NULL)
                	        tmpkey++;
	
			tmpstr = tmp;
			tmpstr++;
			cmdlen = outchans->len-1;
			
			if (use_keys)
				cmdlen += outkeys->len;
			if (*tmpstr != NULL)
				cmdlen += ischannel(**tmpstr) ? strlen(*tmpstr) :
					  strlen(*tmpstr)+1;
			if (*tmpkey != NULL)
				cmdlen += strlen(*tmpkey);
				
			/* don't try to send too long lines 
			   make sure it's not longer than 510
			   so 510 - strlen("JOIN ") = 505 */
			if (cmdlen < 505)
				continue;
		}
		if (outchans->len > 0) {
			g_string_truncate(outchans, outchans->len-1);
			g_string_truncate(outkeys, outkeys->len-1);
			irc_send_cmdv(IRC_SERVER(server),
				      use_keys ? "JOIN %s %s" : "JOIN %s",
				      outchans->str, outkeys->str);
		}
		cmdlen = 0;
		g_string_truncate(outchans,0);
		g_string_truncate(outkeys,0);
		if (*tmp == NULL || tmp[1] == NULL)
			break;
	}
	g_string_free(outchans, TRUE);
	g_string_free(outkeys, TRUE);

	g_strfreev(chanlist);
	g_strfreev(keylist);

	cmd_params_free(free_arg);
}