Exemple #1
0
/* in response to a TOPIC message from the server */
static void p_topic(char *from, char **ArgList)
{
    struct channel *tmp;

    if (!ArgList[1]) {
	fake();
	return;
    }
    tmp = lookup_channel(ArgList[0], from_server, CHAN_NOUNLINK);
    malloc_strcpy(&tmp->topic, ArgList[1]);
    if (check_ignore(from, FromUserHost, tmp->channel, IGNORE_TOPICS | IGNORE_CRAP, NULL) != IGNORED) {
	message_from(ArgList[0], LOG_CRAP);
	if (do_hook(TOPIC_LIST, "%s %s %s", from, ArgList[0], ArgList[1])) {
	    if (ArgList[1] && *ArgList[1]) {
		if (get_format(FORMAT_TOPIC_CHANGE_HEADER_FSET))
		    put_it("%s",
			   convert_output_format(get_format(FORMAT_TOPIC_CHANGE_HEADER_FSET), "%s %s %s %s", update_clock(GET_TIME),
						 from, ArgList[0], ArgList[1]));
		put_it("%s",
		       convert_output_format(get_format(FORMAT_TOPIC_CHANGE_FSET), "%s %s %s %s", update_clock(GET_TIME), from,
					     ArgList[0], ArgList[1]));
	    } else
		put_it("%s",
		       convert_output_format(get_format(FORMAT_TOPIC_UNSET_FSET), "%s %s %s", update_clock(GET_TIME), from,
					     ArgList[0]));
	}

	message_from(NULL, LOG_CRAP);
    }
    update_all_status(curr_scr_win, NULL, 0);
}
Exemple #2
0
void funny_mode(char *from, char **ArgList)
{
	char	*mode, *channel;
	ChannelList *chan = NULL;
		
	if (!ArgList[0]) return;

	channel = ArgList[0];
	mode = ArgList[1];
	PasteArgs(ArgList, 1);

	if((channel && in_join_list(channel, from_server)) || get_chan_from_join_list(from_server))
	{
		if (!channel)
			channel = get_chan_from_join_list(from_server);
		update_channel_mode(from, channel, from_server, mode, chan);
		update_all_status(current_window, NULL, 0);
		got_info(channel, from_server, GOTMODE);
	}
	else
	{
		if (channel)
		{
			set_display_target(channel, LOG_CRAP);
			if (do_hook(current_numeric, "%s %s %s", from, channel, mode))
				put_it("%s", convert_output_format(fget_string_var(FORMAT_MODE_CHANNEL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, *FromUserHost ? FromUserHost:"ÿ", channel, mode));
			reset_display_target();
		}
		else
		{
			if (do_hook(current_numeric, "%s %s", from, mode))
				put_it("%s", convert_output_format(fget_string_var(FORMAT_MODE_CHANNEL_FSET), "%s %s %s %s", update_clock(GET_TIME), from, *FromUserHost ? FromUserHost:"ÿ", mode));
		}
	}
}
Exemple #3
0
static void set_clock_format (Window *win, char *value, int unused)
{
	extern char *time_format; /* XXXX bogus XXXX */
	malloc_strcpy(&time_format, value);
	update_clock(RESET_TIME);
	update_all_status(current_window, NULL, 0);
}
Exemple #4
0
static void p_part(char *from, char **ArgList)
{
    char *channel;

    if (!from || !*from)
	return;
    channel = ArgList[0];

    PasteArgs(ArgList, 1);
    message_from(channel, LOG_CRAP);
    in_on_who = 1;

    if ((check_ignore(from, FromUserHost, channel, IGNORE_PARTS | IGNORE_CRAP, NULL) != IGNORED) &&
	do_hook(LEAVE_LIST, "%s %s %s %s", from, channel, FromUserHost, ArgList[1] ? ArgList[1] : empty_str))
	put_it("%s",
	       convert_output_format(get_format(FORMAT_LEAVE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, FromUserHost,
				     channel, ArgList[1] ? ArgList[1] : empty_str));
    if (!my_stricmp(from, get_server_nickname(from_server))) {
	remove_channel(channel, from_server);
	remove_from_mode_list(channel, from_server);
	remove_from_join_list(channel, from_server);
	set_input_prompt(curr_scr_win, get_string_var(INPUT_PROMPT_VAR), 0);
    } else {
	remove_from_channel(channel, from, from_server, 0, NULL);
    }
    update_all_status(curr_scr_win, NULL, 0);
    update_input(UPDATE_ALL);
    message_from(NULL, LOG_CRAP);
    in_on_who = 0;
}
Exemple #5
0
static	void parse_server_notice(char *from, char *line)
{
	int	flag = 0;
	int	up_status = 0;
const	char	*f;	
				
	f = from;
	if (!f || !*f)
		if (!(f = get_server_itsname(from_server)))
			f = get_server_name(from_server);
			
	if (*line != '*'  && *line != '#' && strncmp(line, "MOTD ", 4))
		flag = 1;
	else
		flag = 0;

	if (do_hook(SERVER_NOTICE_LIST, flag?"%s *** %s":"%s %s", f, line))
	{
#ifdef WANT_OPERVIEW
		if (handle_oper_vision(f, line, &up_status))
			reset_display_target();
		else 
#endif
		if (strstr(line, "***"))
		{
			set_display_target(NULL, LOG_SNOTE);
#ifdef WANT_OPERVIEW
			if (get_int_var(OV_VAR) && !(get_server_ircop_flags(from_server) & SERVER_CRAP))
				goto done1;
#endif
			if (do_hook(SERVER_NOTICE_LIST, flag ? "%s *** %s" : "%s %s", f, line))
			{
				char *for_;
				for_ = next_arg(line,&line);
				serversay(1, from_server, "%s", 
				convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FSET), "%s %s %s", update_clock(GET_TIME), 
				f, stripansicodes(line)));
				add_last_type(&last_servermsg[0], MAX_LAST_MSG, NULL, NULL, NULL, line);
			}
		}
		else
		{
			set_display_target(NULL, LOG_SNOTE);
#ifdef WANT_OPERVIEW
			if (get_int_var(OV_VAR) && !(get_server_ircop_flags(from_server) & SERVER_CRAP))
				goto done1;
#endif
			if (do_hook(SERVER_NOTICE_LIST, flag ? "%s *** %s" : "%s %s", f, line))
				serversay(1, from_server, "%s", 
				convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FSET), "%s %s %s", update_clock(GET_TIME), 
				f, stripansicodes(line)));
			add_last_type(&last_servermsg[0], MAX_LAST_MSG, NULL, NULL, NULL, line);
		}
	}
	if (up_status)
		update_all_status(current_window, NULL, 0);
done1:
	reset_display_target();
}
Exemple #6
0
static void reinit_screen(Window *win, char *unused, int value)
{
	set_input_prompt(current_window, NULL, 0);
	set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 0);
	update_all_windows();
	update_all_status(current_window, NULL, 0);
	update_input(UPDATE_ALL);
}
Exemple #7
0
void	reset_clock (const void *stuff)
{
	if (x_debug & DEBUG_BROKEN_CLOCK)
		reset_broken_clock();
	else if (get_int_var(METRIC_TIME_VAR))
		reset_metric_clock();
	else
		reset_standard_clock();

	update_all_status();
	cursor_to_input();
}
Exemple #8
0
void got_initial_version_28 (char **ArgList)
{
	char *server, *sversion, *user_modes, *channel_modes;

	server = ArgList[0];
	sversion = ArgList[1];
	user_modes = ArgList[2];
	channel_modes = ArgList[3];
		
	if (sversion)
	{
		if (!strncmp(sversion, "2.8", 3))
		{
			if (strstr(sversion, "mu") || strstr(sversion, "me"))
				set_server_version(from_server, Server_u2_8);
			else if (strstr(sversion, "hybrid-6"))
				set_server_version(from_server, Server2_8hybrid6);
			else if (strstr(sversion, "hybrid"))
				set_server_version(from_server, Server2_8hybrid);
			else if (strstr(sversion, "comstud"))
				set_server_version(from_server, Server2_8comstud);
			else if (strstr(channel_modes, "che"))
				set_server_version(from_server, Server2_8ts4); 
			else
				set_server_version(from_server, Server2_8);
		}
		else if (!strncmp(sversion, "2.9", 3))
		        set_server_version(from_server, Server2_9);
		else if (!strncmp(sversion, "2.10", 4))
	        	set_server_version(from_server, Server2_10);
		else if (!strncmp(sversion, "u2.9", 4))
			set_server_version(from_server, Server_u2_9);
		else if (!strncmp(sversion, "u2.10", 4))
			set_server_version(from_server, Server_u2_10);
		else if (!strncmp(sversion, "u3.0", 4))
			set_server_version(from_server, Server_u3_0);
		else
			set_server_version(from_server, Server2_8);
	} else
		set_server_version(from_server, Server2_8);

	set_server_version_string(from_server, sversion ? sversion : "2.8");
	set_server_itsname(from_server, server);
	reconnect_all_channels(from_server);

	reset_display_target();
	reinstate_user_modes();
	if (use_nat_address == 1)
		userhostbase(get_server_nickname(from_server), get_nat_address, 1, "%s", get_server_nickname(from_server));
	update_all_status(current_window, NULL, 0);
	do_hook(CONNECT_LIST, "%s %d %s", get_server_name(from_server), get_server_port(from_server), get_server_itsname(from_server));
}
Exemple #9
0
/*
 * This function causes every status bar, both global and per-window to be
 * rebuilt, and marks every window as needing its status bar redrawn.
 * This function can be quite expensive.
 *
 * This function should be called whenever you change the global status format
 * (/SET STATUS_FORMAT*) or one of the sub-components (/SET STATUS_*)
 * 
 * This function is a /SET callback, so it must always take a (char *) as an
 * argument even though we don't care about it.
 */
void	build_status	(const void *stuff)
{
	Window 	*w = NULL;

	if (!main_status_init)
		init_status();

	rebuild_a_status(w);
	while (traverse_all_windows(&w))
		rebuild_a_status(w);

	update_all_status();
}
Exemple #10
0
void	reset_clock (void *stuff)
{
	char *	sclock;

	if (x_debug & DEBUG_BROKEN_CLOCK)
		reset_broken_clock();
	else if (get_int_var(METRIC_TIME_VAR))
		reset_metric_clock();
	else
		reset_standard_clock();

	sclock = get_string_var(STATUS_CLOCK_VAR);
	if (sclock && *sclock)
		update_all_status();
}
Exemple #11
0
static	void
nickname_sendline(u_char *data, u_char *nick)
{
	int	new_server, server;

	new_server = my_atoi(data);
	server = parsing_server();
	set_from_server(new_server);
	if (nick && *nick)
	{
		send_to_server("NICK %s", nick);
		if (new_server == get_primary_server())
			set_nickname(nick);
		server_set_nickname(new_server, nick);
	}
	set_from_server(server);
	already_doing_reset_nickname = 0;
	update_all_status();
}
Exemple #12
0
static void p_quit(char *from, char **ArgList)
{
    int one_prints = 0;
    char *chan = NULL;
    char *Reason;
    int netsplit = 0;
    int ignore;

    PasteArgs(ArgList, 0);
    if (ArgList[0]) {
	Reason = ArgList[0];
	netsplit = check_split(from, Reason, chan);
    } else
	Reason = "?";

    ignore = check_ignore(from, FromUserHost, NULL, (netsplit ? IGNORE_SPLITS : IGNORE_QUITS) | IGNORE_ALL, NULL);
    for (chan = walk_channels(from, 1, from_server); chan; chan = walk_channels(from, 0, -1)) {
	if (ignore != IGNORED) {
	    message_from(chan, LOG_CRAP);
	    if (do_hook(CHANNEL_SIGNOFF_LIST, "%s %s %s", chan, from, Reason))
		one_prints = 1;
	    message_from(NULL, LOG_CURRENT);
	}
    }
    if (one_prints) {
	chan = what_channel(from, from_server);

	ignore = check_ignore(from, FromUserHost, chan, (netsplit ? IGNORE_SPLITS : IGNORE_QUITS) | IGNORE_ALL, NULL);

	message_from(chan, LOG_CRAP);
	if ((ignore != IGNORED) && do_hook(SIGNOFF_LIST, "%s %s", from, Reason) && !netsplit)
	    put_it("%s",
		   convert_output_format(get_format(FORMAT_CHANNEL_SIGNOFF_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from,
					 FromUserHost, chan, Reason));
	message_from(NULL, LOG_CURRENT);
    }
    if (!netsplit)
	check_orig_nick(from);
    notify_mark(from, NULL, NULL, 0);
    remove_from_channel(NULL, from, from_server, netsplit, Reason);
    message_from(NULL, LOG_CRAP);
    update_all_status(curr_scr_win, NULL, 0);
}
Exemple #13
0
/*
 * reset_nickname: when the server reports that the selected nickname is not
 * a good one, it gets reset here. 
 */
static	void
reset_nickname(u_char *from)
{
	u_char	server_num[10];
	const	int	from_server = get_from_server();

	if (already_doing_reset_nickname ||
	    is_server_connected(from_server) ||
	    !server_get_attempting_to_connect(from_server))
		return;

	say("You have specified an illegal nickname");
	if (!term_basic() && !get_int_var(NO_ASK_NICKNAME_VAR))
	{
		already_doing_reset_nickname = 1;
		say("Please enter your nickname");
		snprintf(CP(server_num), sizeof server_num, "%d", parsing_server());
		add_wait_prompt(UP("Nickname: "), nickname_sendline, server_num,
			WAIT_PROMPT_LINE);
	}
	update_all_status();
}
Exemple #14
0
void	set_mail (const void *stuff)
{
	int	value = *(const int *)stuff;

	if (value < 0 || value > 3)
	{
		say("/SET MAIL must be 0, 1, 2, or 3");
		set_int_var(MAIL_VAR, 0);
		return;
	}
	else if (value == 0)
		checkmail->deinit();
	else
	{
		if (!checkmail->init())
			return;
	}

	update_system_timer(mail_timeref);
	update_all_status();
	cursor_to_input();
}
Exemple #15
0
static void p_kill(char *from, char **ArgList)
{
    char sc[20];
    int port;
    int local = 0;

    port = get_server_port(from_server);
    if (ArgList[1] && strstr(ArgList[1], get_server_name(from_server)))
	if (!strchr(from, '.'))
	    local = 1;
    snprintf(sc, 19, "+%i %d", from_server, port);

    close_server(from_server, empty_str);
    clean_whois_queue();
    window_check_servers();
    set_input_prompt(curr_scr_win, get_string_var(INPUT_PROMPT_VAR), 0);

    if (strchr(from, '.')) {
	say("Server [%s] has rejected you (probably due to a nick collision)", from);
	t_parse_command("SERVER", NULL);
    } else {
	if (local && get_int_var(NEXT_SERVER_ON_LOCAL_KILL_VAR)) {
	    int i = from_server + 1;

	    if (i >= number_of_servers)
		i = 0;
	    snprintf(sc, 19, "+%i", i);
	    from_server = -1;
	}
	if (do_hook(DISCONNECT_LIST, "Killed by %s (%s)", from, ArgList[1] ? ArgList[1] : "(No Reason Given)"))
	    put_it("%s",
		   convert_output_format(get_format(FORMAT_KILL_FSET), "%s %s", update_clock(GET_TIME),
					 ArgList[1] ? ArgList[1] : "You have been Killed"));
	if (get_int_var(AUTO_RECONNECT_VAR))
	    t_parse_command("SERVER", NULL);
    }
    update_all_status(curr_scr_win, NULL, 0);
}
Exemple #16
0
void	mail_systimer (void)
{
	int	x;

	switch ((x = get_int_var(MAIL_VAR)))
	{
		case 1:
			checkmail->level1();
			break;
		case 2:
			checkmail->level2();
			break;
		case 3:
			checkmail->level3();
			break;
		default:
			panic("mail_systimer called with set mail %d", x);
	}

	update_all_status();
	cursor_to_input();
	return;
}
Exemple #17
0
void	set_clock (const void *stuff)
{
	update_system_timer(clock_timeref);
	update_all_status();
	cursor_to_input();
}
Exemple #18
0
void io (const char *what)
{
	static	int	first_time = 1;
		long	clock_timeout = 0, 
			timer_timeout = 0,
			real_timeout = 0; 
static	struct	timeval my_now,
			my_timer,
			*time_ptr = &my_timer;

	int		hold_over,
			rc;
	fd_set		rd, 
			wd;

	get_time(&my_now);
	now = my_now.tv_sec;
	
	/* CHECK FOR CPU SAVER MODE */
	if (!cpu_saver && get_int_var(CPU_SAVER_AFTER_VAR))
		if (now - idle_time > get_int_var(CPU_SAVER_AFTER_VAR) * 60)
			cpu_saver_on(0, NULL);

	rd = readables;
	wd = writables;
	FD_ZERO(&wd);
	FD_ZERO(&rd);

	set_screens(&rd, &wd);
	set_server_bits(&rd, &wd);
	set_process_bits(&rd);
	set_socket_read(&rd, &wd);
	icmp_sockets(&rd, &wd);
	
#if defined(WANT_THREAD)
#ifdef WANT_NSLOOKUP
	set_dns_output_fd(&rd);
#endif
#ifdef WANT_PTEST
	set_ptest_output_fd(&rd);
#endif
#ifdef WANT_MP3PLAYER
	set_mp3_output_fd(&rd);
#endif
	
# if defined(GTK)
	if (tgtk_okay())
		tgtk_set_output_fd(&rd);
# endif
#endif
	clock_timeout = (timeout_select - (my_now.tv_sec % timeout_select)) * 1000;
	if (cpu_saver && get_int_var(CPU_SAVER_EVERY_VAR))
		clock_timeout += (get_int_var(CPU_SAVER_EVERY_VAR) - 1) * 60000;

	timer_timeout = TimerTimeout();

	if ((hold_over = unhold_windows()))
		real_timeout = 0;
	else if (timer_timeout <= clock_timeout)
		real_timeout = timer_timeout;
	else
		real_timeout = clock_timeout;

	if (real_timeout == -1)
		time_ptr = NULL;
	else
	{
		time_ptr->tv_sec = real_timeout / 1000;
		time_ptr->tv_usec = ((real_timeout % 1000) * 1000);
	}
	
	/* GO AHEAD AND WAIT FOR SOME DATA TO COME IN */
	switch ((rc = new_select(&rd, &wd, time_ptr)))
	{
		case 0:
			break;
		case -1:
		{
			/* if we just got a sigint */
			first_time = 0;
			if (cntl_c_hit)
				edit_char('\003');
			else if (errno && errno != EINTR)
			{
				int ii = 0;
				fd_set rd1, wd1;
				char ii_buff_r[500];
				char ii_buff_w[500];
				int ii_r[FD_SETSIZE];
				int ii_w[FD_SETSIZE];
				yell("Select failed with [%d:%s]", errno, strerror(errno));
				/* Reseed fd_sets so we can dig further */
				yell("Packing fd_sets... Dump of fd's set in fd_set");
				ii_buff_r[0] = '\0';
				ii_buff_w[0] = '\0';
				for (ii = 0; ii < FD_SETSIZE; ii++) {
					ii_r[ii] = 0;
					ii_w[ii] = 0;
				}
				FD_ZERO(&wd1);
				FD_ZERO(&rd1);
				set_screens(&rd1, &wd1);
				set_server_bits(&rd1, &wd1);
				set_process_bits(&rd1);
				set_socket_read(&rd1, &wd1);
				icmp_sockets(&rd1, &wd1);
#if defined(WANT_THREAD)
#ifdef WANT_NSLOOKUP
				set_dns_output_fd(&rd1);
#endif
#ifdef WANT_PTEST
				set_ptest_output_fd(&rd1);
#endif
#ifdef WANT_MP3PLAYER
				set_mp3_output_fd(&rd1);
#endif
	
# if defined(GTK)
	if (tgtk_okay())
				tgtk_set_output_fd(&rd1);
# endif
#endif
				for (ii = 0; ii <= global_max_fd; ii++) {
					fd_set rblah, wblah;
					memcpy(&rblah, &rd1, sizeof(fd_set));
					FD_SET(ii, &rblah);
					if (memcmp(&rblah, &rd1, sizeof(fd_set)) == 0) {
						char blahblah[20];
						sprintf(blahblah, "%d ", ii);
						strcat(ii_buff_r, blahblah);
						ii_r[ii] = 1;
					}
					memcpy(&wblah, &wd1, sizeof(fd_set));
					FD_SET(ii, &wblah);
					if (memcmp(&wblah, &wd1, sizeof(fd_set)) == 0) {
						char blahblah[20];
						yell("blah");
						sprintf(blahblah, "%d ", ii);
						strcat(ii_buff_w, blahblah);
						ii_w[ii] = 1;
					}
				}
				yell("Read fd's in set: %s", (ii_buff_r[0] == '\0') ? "<NONE>" : ii_buff_r);
				for (ii = 0; ii <= global_max_fd; ii++) {
					if (ii_r[ii] == 1) {
						struct stat st;
						if (fstat(ii, &st) == -1) {
							yell("READ FD %d is causing the select failure!", ii);
						}
						else {
							if (S_ISSOCK(st.st_mode))
								yell("READ FD %d is a socket!", ii);
							else if (S_ISREG(st.st_mode))
								yell("READ FD %d is a regular file!", ii);
							else if (S_ISFIFO(st.st_mode))
								yell("READ FD %d is a FIFO!", ii);
							else ;
						}
					}
				}
				yell("Write fd's in set: %s", (ii_buff_w[0] == '\0') ? "<NONE>" : ii_buff_w);
				for (ii = 0; ii <= global_max_fd; ii++) {
					if (ii_w[ii] == 1) {
						struct stat st;
						if (fstat(ii, &st) == -1) {
							yell("WRITE FD %d is causing the select failure!", ii);
						}
						else {
							if (S_ISSOCK(st.st_mode))
								yell("WRITE FD %d is a socket!", ii);
							else if (S_ISREG(st.st_mode))
								yell("WRITE FD %d is a regular file!", ii);
							else if (S_ISFIFO(st.st_mode))
								yell("WRITE FD %d is a FIFO!", ii);
							else ;
						}
					}
				}
				sleep(10);
			}
			else 
			{
#if 0
				yell("errno 0 rc = -1, maybe it'll go away");
				sleep(10);
#endif
			}
			break;

		}

		/* we got something on one of the descriptors */
		default:
		{
			cntl_c_hit = 0;
			now = time(NULL);
			make_window_current(NULL);
			do_screens(&rd);
			check_icmpresult(&rd, &wd);
#if defined(WANT_THREAD)
#ifdef WANT_NSLOOKUP
			dns_check(&rd);
#endif
#ifdef WANT_PTEST
			ptest_check(&rd);
#endif
#ifdef WANT_MP3PLAYER
			mp3_check(&rd);
#endif
# if defined(GTK)
			if (tgtk_okay())
				tgtk_check(&rd);
# endif
#endif
			do_server(&rd, &wd);
			do_processes(&rd);
			scan_sockets(&rd, &wd);
			clean_sockets();
			break;
		} 
	}

	now = time(NULL);
	ExecuteTimers();

        get_child_exit(-1);
	if (update_refresh)
	{
		update_refresh = 0;
		refresh_screen(0, NULL);
	}
	if (!hold_over)
		cursor_to_input();


	if (update_clock(RESET_TIME))
	{
		if (get_int_var(CLOCK_VAR))
		{
			update_all_status(current_window, NULL, 0);
			cursor_to_input();
		}
		clean_queue(get_int_var(TRANSFER_TIMEOUT_VAR)); /* timeout if send time is greater than 5 minutes */
	}

	/* (set in term.c) -- we should redraw the screen here */
	if (need_redraw)
		refresh_screen(0, NULL);
#ifdef WANT_THREAD
	if (scan_done)
		scan_is_done();	
#endif
	alloca(0);
	return;
}
Exemple #19
0
void reset_clock(Window *win, char *unused, int unused1)
{
	update_clock(RESET_TIME);
	update_all_status(win, NULL, 0);
}
Exemple #20
0
void	my_set_clock (void *stuff)
{
	update_system_timer(clock_timeref);
	update_all_status();
}
Exemple #21
0
void reinit_status(Window *win, char *unused, int value)
{
	update_all_windows();
	update_all_status(current_window, NULL, 0);
	build_status(current_window, NULL, 0);
}
Exemple #22
0
/*
 * got_initial_version_28: this is called when ircii gets the serial
 * number 004 reply.  We do this becuase the 004 numeric gives us the
 * server name and version in an easy to use fashion, and doesnt
 * rely on the syntax or construction of the 002 numeric.
 *
 * Hacked as neccesary by jfn, May 1995
 */
void 	got_initial_version_28 (const char *server, const char *version, const char *umodes)
{
	/* Worthless 004 reply.  Hope for the best! */
	if (!server || !version || !umodes)
	{
		set_server_version(from_server, Server2_8);
		set_server_version_string(from_server, "<none provided>");
		set_server_itsname(from_server, get_server_name(from_server));
	}
	else
	{
		if (!strncmp(version, "2.8", 3))
		{
			if (strstr(version, "mu") || strstr(version, "me"))
				set_server_version(from_server, Server_u2_8);
			else
				set_server_version(from_server, Server2_8);
		}
		else if (!strncmp(version, "2.9", 3))
			set_server_version(from_server, Server2_9);
		else if (!strncmp(version, "2.10", 4))
			set_server_version(from_server, Server2_10);
		else if (!strncmp(version, "u2.9", 4))
			set_server_version(from_server, Server_u2_9);
		else if (!strncmp(version, "u2.10", 4))
			set_server_version(from_server, Server_u2_10);
		else if (!strncmp(version, "u3.0", 4))
			set_server_version(from_server, Server_u3_0);
		else
			set_server_version(from_server, Server2_8);

		set_server_version_string(from_server, version);
		set_server_itsname(from_server, server);
		set_possible_umodes(from_server, umodes);
	}

	reconnect_all_channels();
	server_did_rejoin_channels(from_server);
	message_from(NULL, LOG_CRAP);
	reinstate_user_modes();

	if (never_connected)
	{
		never_connected = 0;
		permit_status_update(1);

		if (!ircrc_loaded)
			load_ircrc();

		if (default_channel)
		{
			e_channel("JOIN", default_channel, empty_string);
			new_free(&default_channel);
		}
	}
	else if (get_server_away(from_server))
		set_server_away(from_server, get_server_away(from_server));

	update_all_status();
	do_hook(CONNECT_LIST, "%s %d %s", get_server_name(from_server),
		get_server_port(from_server), get_server_itsname(from_server));
	window_check_channels();
}
Exemple #23
0
/*
 * numbered_command: does (hopefully) the right thing with the numbered
 * responses from the server.  I wasn't real careful to be sure I got them
 * all, but the default case should handle any I missed (sorry) 
 */
void
numbered_command(u_char *from, int comm, u_char **ArgList)
{
	u_char	*user;
	u_char	none_of_these = 0;
	u_char	blah[BIG_BUFFER_SIZE];
	int	flag,
		lastlog_level;
	const	int	from_server = parsing_server();
#if 0
	int	user_cnt,
		inv_cnt,
		server_cnt;
#endif /* 0 */

	if (!from || !*from)
		return;
	if (!*ArgList[0])
		user = NULL;
	else
		user = ArgList[0];
	if (!ArgList[1])
		return;
	lastlog_level = set_lastlog_msg_level(LOG_CRAP);
	save_message_from();
	message_from(NULL, LOG_CRAP);
	ArgList++;
	current_numeric_local = -comm;	/* must be negative of numeric! */
	switch (comm)
	{
	case 001:	/* #define RPL_WELCOME          001 */
		PasteArgs(ArgList, 0);
		if (my_strcmp(user, server_get_nickname(from_server)) != 0)
		{
			yell("=== Setting this servers nickname to \"%s\" from \"%s\"", user, server_get_nickname(from_server));
			server_set_nickname(from_server, user);
		}
		if (do_hook(current_numeric(), "%s %s", from, *ArgList)) 
			display_msg(from, ArgList);
		clean_whois_queue();
		break;
	case 002:	/* #define RPL_YOURHOST         002 */
		PasteArgs(ArgList, 0);
		snprintf(CP(blah), sizeof blah, "*** %s", ArgList[0]);
		got_initial_version(blah);
		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
			display_msg(from, ArgList);
		break;

/* should do something with this some day, 2.8 had channel/user mode switches */
	case 004:	/* #define RPL_MYINFO           004 */
		PasteArgs(ArgList, 0);
		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
			display_msg(from, ArgList);
		break;

/*
 * this part of ircii has been broken for most of ircd 2.7, so someday I'll
 * make it work for ircd 2.8 ...  phone..
 */
#if 0
	case 251:		/* #define RPL_LUSERCLIENT      251 */
		display_msg(from, ArgList);
		if (is_server_connected(from_server))
			break;
		if (from_server == get_primary_server() && ((sscanf(ArgList[1],
		    "There are %d users and %d invisible on %d servers",
		    &user_cnt, &inv_cnt, &server_cnt) == 3)||(sscanf(ArgList[1],
		    "There are %d users and %d invisible on %d servers",
		    &user_cnt, &inv_cnt, &server_cnt) == 3)))
		{
			user_cnt =+ inv_cnt;
			if ((server_cnt < get_int_var(MINIMUM_SERVERS_VAR)) ||
			    (user_cnt < get_int_var(MINIMUM_USERS_VAR)))
			{
				say("Trying better populated server...");
				get_connected(from_server + 1);
			}
		}
		break;
#endif /* 0 */
	case 301:		/* #define RPL_AWAY             301 */
		user_is_away(from, ArgList);
		break;

	case 302:		/* #define RPL_USERHOST         302 */
		userhost_returned(from, ArgList);
		break;

	case 303:		/* #define RPL_ISON             303 */
		ison_returned(from, ArgList);
		break;

	case 311:		/* #define RPL_WHOISUSER        311 */
		whois_name(from, ArgList);
		break;

	case 312:		/* #define RPL_WHOISSERVER      312 */
		whois_server(from, ArgList);
		break;

	case 313:		/* #define RPL_WHOISOPERATOR    313 */
		whois_oper(from, ArgList);
		break;

	case 314:		/* #define RPL_WHOWASUSER       314 */
		whowas_name(from, ArgList);
		break;

	case 316:		/* #define RPL_WHOISCHANOP      316 */
		whois_chop(from, ArgList);
		break;

	case 317:		/* #define RPL_WHOISIDLE        317 */
		whois_lastcom(from, ArgList);
		break;

	case 318:		/* #define RPL_ENDOFWHOIS       318 */
		end_of_whois(from, ArgList);
		break;

	case 319:		/* #define RPL_WHOISCHANNELS    319 */
		whois_channels(from, ArgList);
		break;

	case 321:		/* #define RPL_LISTSTART        321 */
		ArgList[0] = UP("Channel\0Users\0Topic");
		ArgList[1] = ArgList[0] + 8;
		ArgList[2] = ArgList[1] + 6;
		ArgList[3] = NULL;
		funny_list(from, ArgList);
		break;

	case 322:		/* #define RPL_LIST             322 */
		funny_list(from, ArgList);
		break;

	case 324:		/* #define RPL_CHANNELMODEIS    324 */
		funny_mode(from, ArgList);
		break;

	case 341:		/* #define RPL_INVITING         341 */
		invite(from, ArgList);
		break;

	case 352:		/* #define RPL_WHOREPLY         352 */
		whoreply(NULL, ArgList);
		break;

	case 353:		/* #define RPL_NAMREPLY         353 */
		funny_namreply(from, ArgList);
		break;

	case 366:		/* #define RPL_ENDOFNAMES       366 */
		{
			u_char	*tmp = NULL,
				*chan;

			PasteArgs(ArgList, 0);
			malloc_strcpy(&tmp, ArgList[0]);
			chan = next_arg(tmp, 0);
			flag = do_hook(current_numeric(), "%s %s", from, ArgList[0]);
			
			if (flag &&
			    channel_mode_lookup(chan, CHAN_NAMES | CHAN_MODE, 0) &&
			    get_int_var(SHOW_END_OF_MSGS_VAR) && flag)
				display_msg(from, ArgList);

			new_free(&tmp);
		}
		break;

	case 381: 		/* #define RPL_YOUREOPER        381 */
		PasteArgs(ArgList, 0);
		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
			display_msg(from, ArgList);
		server_set_operator(parsing_server(), 1);
		update_all_status();	/* fix the status line */
		break;

	case 401:		/* #define ERR_NOSUCHNICK       401 */
		no_such_nickname(from, ArgList);
		break;

	case 405:		/* #define ERR_TOOMANYCHANNELS  405 */
		remove_channel(ArgList[0], parsing_server());
		break;
		
	case 421:		/* #define ERR_UNKNOWNCOMMAND   421 */
		if (check_screen_redirect(ArgList[0]))
			break;
		if (check_wait_command(ArgList[0]))
			break;
		PasteArgs(ArgList, 0);
		flag = do_hook(current_numeric(), "%s %s", from, *ArgList);
		if (!my_strncmp("ISON", *ArgList, 4) || !my_strncmp("USERHOST",
		    *ArgList, 8))
		{
			server_set_2_6_2(parsing_server(), 0);
			convert_to_whois();
		}
		else if (flag)
			display_msg(from, ArgList);
		break;

	case 432:		/* #define ERR_ERRONEUSNICKNAME 432 */
	case 433:		/* #define ERR_NICKNAMEINUSE    433 */ 
		PasteArgs(ArgList, 0);
		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
			display_msg(from, ArgList);
		reset_nickname(from);
		break;

	case 437:		/* #define ERR_UNAVAILRESOURCE  437 */
		PasteArgs(ArgList, 0);
		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
			display_msg(from, ArgList);
		if (!is_channel(*ArgList))
			reset_nickname(from);
		break;

	case 463:		/* #define ERR_NOPERMFORHOST    463 */
		display_msg(from, ArgList);
		close_server(parsing_server(), empty_string());
		window_check_servers();
		if (!connected_to_server())
			get_connected(parsing_server() + 1);
		break;

	case 464:		/* #define ERR_PASSWDMISMATCH   464 */
		PasteArgs(ArgList, 0);
		flag = do_hook(current_numeric(), "%s %s", from, ArgList[0]);
		if (server_get_oper_command())
		{
			if (flag)
				display_msg(from, ArgList);
		}
		else
			get_password();
		break;

	case 465:		/* #define ERR_YOUREBANNEDCREEP 465 */
		{
			int	klined_server = parsing_server();

			PasteArgs(ArgList, 0);
			if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
				display_msg(from, ArgList);
			close_server(parsing_server(), empty_string());
			window_check_servers();
			if (number_of_servers() > 1)
				remove_from_server_list(klined_server);
			if (!connected_to_server())
				say("You are not connected to a server. Use /SERVER to connect.");
			break;
		}

	case 471:		/* #define ERR_CHANNELISFULL    471 */
	case 473:		/* #define ERR_INVITEONLYCHAN   473 */
	case 474:		/* #define ERR_BANNEDFROMCHAN   474 */
	case 475: 		/* #define ERR_BADCHANNELKEY    475 */
	case 476:		/* #define ERR_BADCHANMASK      476 */
		cannot_join_channel(from, ArgList);
		break;

	case 484:		/* #define ERR_RESTRICTED       484 */
		if (do_hook(current_numeric(), "%s %s", from, *ArgList))
			display_msg(from, ArgList);
		server_set_flag(parsing_server(), USER_MODE_R, 1);
		break;

		/*
		 * The following accumulates the remaining arguments
		 * in ArgSpace for hook detection.  We can't use
		 * PasteArgs here because we still need the arguments
		 * separated for use elsewhere.
		 */
	default:
		{
			u_char	*ArgSpace = NULL;
			int	i,
				do_message_from = 0;
			size_t	len;

			for (i = len = 0; ArgList[i]; len += my_strlen(ArgList[i++]))
				;
			len += (i - 1);
			ArgSpace = new_malloc(len + 1);
			ArgSpace[0] = '\0';
			/* this is cheating */
			if (ArgList[0] && is_channel(ArgList[0]))
				do_message_from = 1;
			for (i = 0; ArgList[i]; i++)
			{
				if (i)
					my_strcat(ArgSpace, " ");
				my_strcat(ArgSpace, ArgList[i]);
			}
			if (do_message_from)
				message_from(ArgList[0], LOG_CRAP);
			i = do_hook(current_numeric(), "%s %s", from, ArgSpace);
			new_free(&ArgSpace);
			if (do_message_from)
				restore_message_from();
			if (i == 0)
				goto done;
			none_of_these = 1;
		}
	}
	/* the following do not hurt the ircII if intercepted by a hook */
	if (none_of_these)
	{
		switch (comm)
		{
		case 221: 		/* #define RPL_UMODEIS          221 */
			put_it("%s Your user mode is \"%s\"", numeric_banner(),
				ArgList[0]);
			break;

		case 242:		/* #define RPL_STATSUPTIME      242 */
			PasteArgs(ArgList, 0);
			if (from && !my_strnicmp(server_get_itsname(parsing_server()),
			    from, my_strlen(server_get_itsname(parsing_server()))))
				from = NULL;
			if (from)
				put_it("%s %s from (%s)", numeric_banner(),
					*ArgList, from);
			else
				put_it("%s %s", numeric_banner(), *ArgList);
			break;

		case 332:		/* #define RPL_TOPIC            332 */
			channel_topic(from, ArgList);
			break;

		case 351:		/* #define RPL_VERSION          351 */
			version(from, ArgList);
			break;

		case 364:		/* #define RPL_LINKS            364 */
			if (ArgList[2])
			{
				PasteArgs(ArgList, 2);
				put_it("%s %-20s %-20s %s", numeric_banner(),
					ArgList[0], ArgList[1], ArgList[2]);
			}
			else
			{
				PasteArgs(ArgList, 1);
				put_it("%s %-20s %s", numeric_banner(),
					ArgList[0], ArgList[1]);
			}
			break;

		case 372:		/* #define RPL_MOTD             372 */
			if (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) ||
			    !server_get_motd(parsing_server()))
			{
				PasteArgs(ArgList, 0);
				put_it("%s %s", numeric_banner(), ArgList[0]);
			}
			break;

		case 375:		/* #define RPL_MOTDSTART        375 */
			if (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) ||
			    !server_get_motd(parsing_server()))
			{
				PasteArgs(ArgList, 0);
				put_it("%s %s", numeric_banner(), ArgList[0]);
			}
			break;

		case 376:		/* #define RPL_ENDOFMOTD        376 */
			if (server_get_attempting_to_connect(parsing_server()))
				got_initial_version(UP("*** Your host is broken and not running any version"));
			if (get_int_var(SHOW_END_OF_MSGS_VAR) &&
			    (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) ||
			    !server_get_motd(parsing_server())))
			{
				PasteArgs(ArgList, 0);
				put_it("%s %s", numeric_banner(), ArgList[0]);
			}
			server_set_motd(parsing_server(), 0);
			break;

		case 384:		/* #define RPL_MYPORTIS         384 */
			PasteArgs(ArgList, 0);
			put_it("%s %s %s", numeric_banner(), ArgList[0], user);
			break;

		case 385:		/* #define RPL_NOTOPERANYMORE   385 */
			server_set_operator(parsing_server(), 0);
			display_msg(from, ArgList);
			update_all_status();
			break;

		case 403:		/* #define ERR_NOSUCHCHANNEL    403 */
			not_valid_channel(from, ArgList);
			break;

		case 451:		/* #define ERR_NOTREGISTERED    451 */
	/*
	 * Sometimes the server doesn't catch the USER line, so
	 * here we send a simplified version again  -lynx 
	 */
			send_to_server("USER %s %s . :%s", my_username(),
				irc_umode(), my_realname());
			send_to_server("NICK %s",
				server_get_nickname(parsing_server()));
			break;

		case 462:		/* #define ERR_ALREADYREGISTRED 462 */
			display_msg(from, ArgList);
			break;

#define RPL_CLOSEEND         363
#define RPL_SERVLISTEND      235
		case 315:		/* #define RPL_ENDOFWHO         315 */
		case 323:               /* #define RPL_LISTEND          323 */
			funny_print_widelist();

		case 219:		/* #define RPL_ENDOFSTATS       219 */
		case 232:		/* #define RPL_ENDOFSERVICES    232 */
		case 365:		/* #define RPL_ENDOFLINKS       365 */
		case 368:		/* #define RPL_ENDOFBANLIST     368 */
		case 369:		/* #define RPL_ENDOFWHOWAS      369 */
		case 374:		/* #define RPL_ENDOFINFO        374 */
#if 0	/* this case needs special handing - see above */
		case 376:		/* #define RPL_ENDOFMOTD        376 */
#endif /* 0 */
		case 394:		/* #define RPL_ENDOFUSERS       394 */
			if (!get_int_var(SHOW_END_OF_MSGS_VAR))
				break;
		default:
			display_msg(from, ArgList);
		}
	}
	set_lastlog_msg_level(lastlog_level);
done:
	restore_message_from();
}
Exemple #24
0
static void p_kick(char *from, char **ArgList)
{
    char *channel, *who, *comment;
    char *chankey = NULL;
    struct channel *chan = NULL;
    struct nick_list *tmpnick = NULL;
    int t = 0;

    channel = ArgList[0];
    who = ArgList[1];
    comment = ArgList[2] ? ArgList[2] : "(no comment)";

    if ((chan = lookup_channel(channel, from_server, CHAN_NOUNLINK)))
	tmpnick = find_nicklist_in_channellist(from, chan, 0);
    message_from(channel, LOG_CRAP);
    if (channel && who && chan) {
	if (!my_stricmp(who, get_server_nickname(from_server))) {
	    Window *window = chan->window;

	    if (chan->key)
		malloc_strcpy(&chankey, chan->key);
	    if (get_int_var(AUTO_REJOIN_VAR)) {
		send_to_server(SERVER(from_server), "JOIN %s %s", channel, chankey ? chankey : empty_str);
		add_to_join_list(channel, from_server, window ? window->refnum : 0);
	    }
	    new_free(&chankey);
	    remove_channel(channel, from_server);
	    update_all_status(curr_scr_win, NULL, 0);
	    update_input(UPDATE_ALL);
	    if (do_hook(KICK_LIST, "%s %s %s %s", who, from, channel, comment ? comment : empty_str))
		put_it("%s",
		       convert_output_format(get_format(FORMAT_KICK_USER_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from,
					     channel, who, comment));
	} else {
	    int itsme = 0;

	    itsme = !my_stricmp(get_server_nickname(from_server), from) ? 1 : 0;

	    if ((check_ignore(from, FromUserHost, channel, IGNORE_KICKS | IGNORE_CRAP, NULL) != IGNORED) &&
		do_hook(KICK_LIST, "%s %s %s %s", who, from, channel, comment))
		put_it("%s",
		       convert_output_format(get_format(FORMAT_KICK_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, channel,
					     who, comment));
	    if (!itsme) {
		struct nick_list *f_nick = NULL;

		f_nick = find_nicklist_in_channellist(who, chan, 0);
		if (chan->chop && tmpnick && is_other_flood(chan, tmpnick, KICK_FLOOD, &t)) {
		    if (get_int_var(KICK_ON_KICKFLOOD_VAR) > get_int_var(DEOP_ON_KICKFLOOD_VAR))
			send_to_server(SERVER(from_server), "MODE %s -o %s", chan->channel, from);
		    else if (!f_nick->kickcount++)
			send_to_server(SERVER(from_server), "KICK %s %s :\002Mass kick detected - (%d kicks in %dsec%s)\002",
				       chan->channel, from, get_int_var(KICK_ON_KICKFLOOD_VAR), t, plural(t));
		}
	    }
	    remove_from_channel(channel, who, from_server, 0, NULL);
	}

    }
    update_all_status(curr_scr_win, NULL, 0);
    message_from(NULL, LOG_CRAP);
}
Exemple #25
0
static void p_mode(char *from, char **ArgList)
{
    char *channel;
    char *line;
    int flag;

    struct channel *chan = NULL;
    char buffer[BIG_BUFFER_SIZE + 1];
    char *smode;

#ifdef COMPRESS_MODES
    char *tmpbuf = NULL;
#endif
    PasteArgs(ArgList, 1);
    channel = ArgList[0];
    line = ArgList[1];
    smode = strchr(from, '.');

    flag = check_ignore(from, FromUserHost, channel, (smode ? IGNORE_SMODES : IGNORE_MODES) | IGNORE_CRAP, NULL);

    message_from(channel, LOG_CRAP);
    if (channel && line) {
	strcpy(buffer, line);
	if (get_int_var(MODE_STRIPPER_VAR))
	    strip_modes(from, channel, line);
	if (is_channel(channel)) {
#ifdef COMPRESS_MODES
	    chan = (struct channel *) find_in_list((struct list **) &server_list[from_server].chan_list, channel, 0);
	    if (get_int_var(COMPRESS_MODES_VAR)) {
		tmpbuf = compress_modes(from_server, channel, line);
		if (tmpbuf)
		    strcpy(line, tmpbuf);
		else
		    goto end_p_mode;
	    }
#endif
	    /* CDE handle mode protection here instead of later */
	    update_channel_mode(from, channel, from_server, buffer, chan);

	    if (flag != IGNORED && do_hook(MODE_LIST, "%s %s %s", from, channel, line))
		put_it("%s",
		       convert_output_format(get_format(smode ? FORMAT_SMODE_FSET : FORMAT_MODE_FSET), "%s %s %s %s %s",
					     update_clock(GET_TIME), from, smode ? "*" : FromUserHost, channel, line));
	} else {
	    if (flag != IGNORED && do_hook(MODE_LIST, "%s %s %s", from, channel, line)) {
		if (!my_stricmp(from, channel)) {
		    if (!my_stricmp(from, get_server_nickname(from_server)))
			put_it("%s",
			       convert_output_format(get_format(FORMAT_USERMODE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from,
						     "*", channel, line));
		    else
			put_it("%s",
			       convert_output_format(get_format(FORMAT_USERMODE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from,
						     smode ? "*" : FromUserHost, channel, line));
		} else
		    put_it("%s",
			   convert_output_format(get_format(FORMAT_MODE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from,
						 smode ? "*" : FromUserHost, channel, line));
	    }
	    update_user_mode(line);
	}
#ifdef COMPRESS_MODES
      end_p_mode:
#endif
	update_all_status(curr_scr_win, NULL, 0);
    }
    message_from(NULL, LOG_CRAP);
}
Exemple #26
0
static void p_channel(char *from, char **ArgList)
{
    char *channel;
    char *user, *host;
    struct channel *chan = NULL;
    struct whowas_list *whowas = NULL;
    int its_me = 0;

    if (!strcmp(ArgList[0], "0")) {
	fake();
	return;
    }

    channel = ArgList[0];
    message_from(channel, LOG_CRAP);
    malloc_strcpy(&joined_nick, from);

    if (!my_stricmp(from, get_server_nickname(from_server))) {
	int refnum;
	Window *old_window = curr_scr_win;
	int switched = 0;

	if (!in_join_list(channel, from_server))
	    add_to_join_list(channel, from_server, curr_scr_win->refnum);
	else {

	    if (curr_scr_win->refnum != (refnum = get_win_from_join_list(channel, from_server))) {
		switched = 1;
		set_current_window(get_window_by_refnum(refnum));
	    }
	}

	if (*channel != '+')
	    send_to_server(SERVER(from_server), "MODE %s\r\nMODE %s b", channel, channel, channel);

	(void) do_hook(JOIN_ME_LIST, "%s", channel);
	its_me = 1;
	chan = add_channel(channel, from_server);
	if (*channel == '+') {
	    got_info(channel, from_server, GOTBANS);
	    got_info(channel, from_server, GOTMODE);
	}
	if (switched)
	    set_current_window(old_window);
    } else {
	int op = 0, vo = 0;
	char *c;

	/* 
	 * Workaround for gratuitous protocol change in ef2.9
	 */
	if ((c = strchr(channel, '\007'))) {
	    for (*c++ = 0; *c; c++) {
		if (*c == 'o')
		    op = 1;
		else if (*c == 'v')
		    vo = 1;
	    }
	}

	chan = add_to_channel(channel, from, from_server, op, vo, FromUserHost, NULL, NULL);
    }

    flush_mode_all(chan);

    user = m_strdup(FromUserHost);
    host = strchr(user, '@');
    *host++ = '\0';

    if (check_ignore(from, FromUserHost, channel, IGNORE_JOINS | IGNORE_CRAP, NULL) != IGNORED && chan) {
	irc_server *irc_serv = NULL;
	char *tmp2 = NULL;

	if (get_int_var(AUTO_NSLOOKUP_VAR) && isdigit(*(host + strlen(host) - 1)))
	    tmp2 = do_nslookup(host);
	message_from(channel, LOG_CRAP);
	if ((whowas = check_whosplitin_buffer(from, FromUserHost, channel, 0)) && (irc_serv = check_split_server(whowas->server1))) {
	    if (do_hook(LLOOK_JOIN_LIST, "%s %s", irc_serv->name, irc_serv->link))
		put_it("%s",
		       convert_output_format(get_format(FORMAT_NETJOIN_FSET), "%s %s %s %d", update_clock(GET_TIME), irc_serv->name,
					     irc_serv->link, 0));
	    remove_split_server(whowas->server1);
	}
	if (do_hook(JOIN_LIST, "%s %s %s", from, channel, tmp2 ? tmp2 : FromUserHost ? FromUserHost : "UnKnown")) {
	    put_it("%s",
		   convert_output_format(get_format(FORMAT_JOIN_FSET), "%s %s %s %s", update_clock(GET_TIME), from,
					 tmp2 ? tmp2 : FromUserHost ? FromUserHost : "UnKnown", channel));
	}
	message_from(NULL, LOG_CRAP);
    }
    set_input_prompt(curr_scr_win, get_string_var(INPUT_PROMPT_VAR), 0);
    update_all_status(curr_scr_win, NULL, 0);
    notify_mark(from, user, host, 1);
    new_free(&user);
}
Exemple #27
0
/*
 * numbered_command: does (hopefully) the right thing with the numbered
 * responses from the server.  I wasn't real careful to be sure I got them
 * all, but the default case should handle any I missed (sorry) 
 *
 * The format of a numeric looks like so:
 *
 *	:server-name XXX our-nick Arg1 Arg2 Arg3 ... :ArgN
 *
 * The last argument traditionally has a colon before it, but this is not
 * compulsary.  The BreakArgs function has already broken this up into 
 * words for us, so that what we get, looks like this:
 *
 *	server-name	-> 	from parameter
 *	XXX		->	comm parameter
 *	our-nick	->	ArgList[0]
 *	Arg1		->	ArgList[1]
 *	Arg2		->	ArgList[2]
 *	...			...
 *
 * BUT!  There's a wrinkle in the ointment.  The first thing we do is slurp
 * up ArgList[0] (our-nick) and put it in 'user'.  Then we increment the 
 * ArgList array, so what we actually end up with is:
 *
 *	server-name	-> 	from parameter
 *	XXX		->	comm parameter
 *	our-nick	->	user
 *	Arg1		->	ArgList[0]
 *	Arg2		->	ArgList[1]
 *	...			...
 *	ArgN		->	ArgList[N-1]
 *	NULL		->	ArgList[N]
 */
void 	numbered_command (const char *from, const char *comm, char const **ArgList)
{
	const char	*target;
	char	*copy;
	int	i;
	int	lastlog_level;
	int	old_current_numeric = current_numeric;
	int	numeric;

	/* All numerics must have a target (our nickname) */
	if (!comm || !*comm)
		{ rfc1459_odd(from, comm, ArgList); return; }
	numeric = atol(comm);
	if (numeric < 0 || numeric > 999)
		{ rfc1459_odd(from, comm, ArgList); return; }

	if (!(target = ArgList[0]))
		{ rfc1459_odd(from, comm, ArgList); return; }
	ArgList++;

	lastlog_level = set_lastlog_msg_level(LOG_CRAP);
	if (ArgList[0] && is_channel(ArgList[0]))
		message_from(ArgList[0], LOG_CRAP);
	else
		message_from(NULL, LOG_CRAP);

	current_numeric = -numeric;	/* must be negative of numeric! */

	/*
	 * This first switch statement is only used for those numerics
	 * which either need to perform some action before the numeric
	 * is offered to the user, or by those actions which need to offer
	 * the numeric to the user in some special manner.  
	 *
	 * Those numerics which require only special display if the user
	 * does not hook them, are handled below.
	 *
	 * Those numerics which require special action after the numeric
	 * is offered to the user, are also handled below.
	 *
	 * Each of these numerics must either "break" (go to step 2)
	 * or must "goto END" (goto step 3).
	 */
	switch (numeric)
	{
	/*
	 * I added the "set_server_nickname" here because the client
	 * when auto-fudging your nick will sometimes be confused as
	 * what your nickname really is when you connect.  Since the
	 * server always tells us who the message was set to (ie, us)
	 * we just kind of take it at its word.
	 */
	case 001:	/* #define RPL_WELCOME          001 */
	{
		Timeval i;

                i.tv_sec = 0;
                i.tv_usec = 50000;
                select(0, NULL, NULL, NULL, &i);

		accept_server_nickname(from_server, target);
		server_is_registered(from_server, 1);
		userhostbase(from_server, NULL, got_my_userhost, 1);
		break;
	}

	/* 
	 * Now instead of the terribly horrible hack using numeric 002
	 * to get the server name/server version info, we use the 004
	 * numeric which is what is the most logical choice for it.
	 *
	 * If any of the arguments are missing, we don't abort, because
	 * the client needs 004 to sync.  Instead, we just pass in the
	 * NULL values and hope for the best...
	 */
	case 004:	/* #define RPL_MYINFO           004 */
	{
		const char 	*server = NULL, 
				*version = NULL, 
				*umodes = NULL;

		/* The 004 numeric is too import to "odd server stuff" over. */
		/* So if the reply is useless, we'll just wing it */
		if (!(server = ArgList[0]))
			server = version = umodes = NULL;
		else if (!(version = ArgList[1]))
			server = version = umodes = NULL;
		else if (!(umodes = ArgList[2]))
			server = version = umodes = NULL;
		else
		{
		  /* Work around ratbox-1.2-3. */
		  if (!my_stricmp(umodes, "(brown"))
		   if (ArgList[3] && !my_stricmp(ArgList[3], "paper"))
		    if (ArgList[4] && !my_stricmp(ArgList[4], "bag"))
		     if (ArgList[5] && !my_stricmp(ArgList[5], "release)"))
		     {
			if (!(umodes = ArgList[6]))
				{ rfc1459_odd(from, comm, ArgList); goto END; }
		     }
		}

		got_initial_version_28(server, version, umodes);
		break;
	}

	case 005:
	{
		int	arg;
		char	*set, *value;

		for (arg = 0; ArgList[arg] && !strchr(ArgList[arg], ' '); arg++) {
			set = LOCAL_COPY(ArgList[arg]);
			value = strchr(set, '=');
			if (value && *value) 
				*value++ = 0;

			if (*set == '+') /* parameter append */
			{
				const char *ov = get_server_005(from_server, ++set);
				value = malloc_strdup2(ov, value);
				set_server_005(from_server, set, value);
				new_free(&value);
			}
			else if (*set == '-') /* parameter removal */
				set_server_005(from_server, ++set, NULL);
			else if (value && *value)
				set_server_005(from_server, set, value);
			else
				set_server_005(from_server, set, space);
		}
		break;
	}

	case 10:		/* EFNext "Use another server"	010 */
	{
		const char *new_server, *new_port_s, *message;
		int	new_port, old_server;

		PasteArgs(ArgList, 2);
		if (!(new_server = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(new_port_s = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(message = ArgList[2]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		new_port = atol(ArgList[1]);

		/* Must do these things before calling "display_msg" */
		old_server = from_server;
		add_to_server_list(new_server, new_port, NULL, NULL,
				get_server_group(from_server), NULL, 0);
		server_reconnects_to(old_server, from_server);
		from_server = old_server;

		break;
	}

	case 14:		/* Erf/TS4 "cookie" numeric	014 */
	{
		const char *	cookie;

		PasteArgs(ArgList, 0);
		if (!(cookie = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		use_server_cookie(from_server);
		set_server_cookie(from_server, cookie);
		goto END;
	}

	case 42:		/* ircnet's "unique id" numeric	042 */
	{
		const char *	unique_id;
		const char *	message;

		PasteArgs(ArgList, 1);
		if (!(unique_id = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		else if (!(message = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		set_server_unique_id(from_server, unique_id);
		if (do_hook(current_numeric, "%s %s %s", 
					from, unique_id, message))
			goto DISPLAY;
		goto END;
	}

        case 301:               /* #define RPL_AWAY             301 */
        {
		const char *nick, *message;

		PasteArgs(ArgList, 1);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(message = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		/* Ach.  /on 301 doesn't offer 'from' as $0.  Bummer. */
                if (do_hook(current_numeric, "%s %s", nick, message))
			goto DISPLAY;
		goto END;
        }

	case 340:		/* #define RPL_USERIP           307 */
		if (!get_server_005(from_server, "USERIP"))
			break;
		/* FALLTHROUGH */
	case 302:		/* #define RPL_USERHOST         302 */
		userhost_returned(from_server, from, comm, ArgList);
		goto END;

	case 303:		/* #define RPL_ISON             303 */
		ison_returned(from_server, from, comm, ArgList);
		goto END;

	case 315:		/* #define RPL_ENDOFWHO         315 */
		who_end(from_server, from, comm, ArgList);
		goto END;

	case 321:		/* #define RPL_LISTSTART        321 */
	{
		const char *channel, *user_cnt, *line;

		channel = ArgList[0] = "Channel";
		user_cnt = ArgList[1] = "Users";
		line = ArgList[2] = "Topic";
		ArgList[3] = NULL;

		/* Then see if they want to hook /ON LIST */
		if (!do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line))
			goto END;

		/*
		 * Otherwise, this line is ok.
		 */
		break;
	}

	case 322:		/* #define RPL_LIST             322 */
	{
		const char *channel, *user_cnt, *line;
		int	cnt;
		int	funny_flags, funny_min, funny_max;
		const char *funny_match;

		PasteArgs(ArgList, 2);
		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(user_cnt = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(line = ArgList[2]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		funny_flags = get_server_funny_flags(from_server);
		funny_min = get_server_funny_min(from_server);
		funny_max = get_server_funny_max(from_server);
		funny_match = get_server_funny_match(from_server);

		/*
		 * Do not display if the channel has no topic and the user asked
		 * for only channels with topics.
		 */
		if (funny_flags & FUNNY_TOPIC && !(line && *line))
			goto END;

		/*
		 * Do not display if the channel does not have the necessary 
		 * number of users the user asked for
		 */
		cnt = my_atol(user_cnt);
		if (funny_min && (cnt < funny_min))
			goto END;
		if (funny_max && (cnt > funny_max))
			goto END;

		/*
		 * Do not display if the channel is not private or public as the
		 * user requested.
		 */
		if ((funny_flags & FUNNY_PRIVATE) && (*channel != '*'))
			goto END;
		if ((funny_flags & FUNNY_PUBLIC) && (*channel == '*'))
			goto END;

		/*
		 * Do not display if the channel does not match the user's 
		 * supplied wildcard pattern
		 */
		if (funny_match && wild_match(funny_match, channel) == 0)
			goto END;

		/* Then see if they want to hook /ON LIST */
		if (!do_hook(LIST_LIST, "%s %s %s", channel, user_cnt, line))
			goto END;

		/*
		 * Otherwise, this line is ok.
		 */
		break;
	}

	case 324:		/* #define RPL_CHANNELMODEIS    324 */
	{
		const char      *mode, *channel;

		PasteArgs(ArgList, 1);
		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(mode = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		/* If we're waiting for MODE reply. */
		if (channel_is_syncing(channel, from_server))
		{
		    int	numonchannel, maxnum;

		    copy = LOCAL_COPY(channel);
		    update_channel_mode(channel, mode);
		    update_all_status();

		    maxnum = get_server_max_cached_chan_size(from_server);
		    if (maxnum >= 0)
		    {
			numonchannel = number_on_channel(copy, from_server);
			if (numonchannel <= maxnum)
			    whobase(from_server, copy, add_user_who, 
						add_user_end);
			else
			    channel_not_waiting(copy, from_server);
		    }
		    else
			    whobase(from_server, copy, add_user_who, 
						add_user_end);
#if 0
		    goto END;
#endif
		}

		break;
	}

	case 352:		/* #define RPL_WHOREPLY         352 */
		whoreply(from_server, NULL, comm, ArgList);
		goto END;

	case 353:		/* #define RPL_NAMREPLY         353 */
	{
		const char	*type, *channel, *line;

		PasteArgs(ArgList, 2);
		if (!(type = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(channel = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(line = ArgList[2]))
			{ line = empty_string; }

		if (channel_is_syncing(channel, from_server))
		{
		    char *line_copy = LOCAL_COPY(line);
		    char *nick;

		    while ((nick = next_arg(line_copy, &line_copy)) != NULL)
		    {
			/* XXX - Hack to work around space at end of 353 */
			forcibly_remove_trailing_spaces(nick, NULL);

			/*
			 * 1999 Oct 29 -- This is a hack to compensate for
			 * a bug in older ircd implementations that can result
			 * in a truncated nickname at the end of a names reply.
			 * The last nickname in a names list is then always
			 * treated with suspicion until the WHO reply is 
			 * completed and we know that its not truncated. --esl
			 */
			if (!line || !*line)
				add_to_channel(channel, nick, from_server, 
								1, 0, 0, 0);
			else
				add_to_channel(channel, nick, from_server, 
								0, 0, 0, 0);
		    }

		    message_from(channel, LOG_CRAP);
		    break;
		}
		else
		{
		    int	cnt;
		    const char	*ptr;
		    int	funny_flags, funny_min, funny_max;
		    const char *funny_match;

		    funny_flags = get_server_funny_flags(from_server);
		    funny_min = get_server_funny_min(from_server);
		    funny_max = get_server_funny_max(from_server);
		    funny_match = get_server_funny_match(from_server);

		    ptr = line;
		    for (cnt = -1; ptr; cnt++)
		    {
			if ((ptr = strchr(ptr, ' ')) != NULL)
				ptr++;
		    }

		    if (funny_min && (cnt < funny_min))
			goto END;
		    else if (funny_max && (cnt > funny_max))
			goto END;

		    if ((funny_flags & FUNNY_PRIVATE) && 
					(*type == '='))
			goto END;
		    if ((funny_flags & FUNNY_PUBLIC) && 
					((*type == '*') || (*type == '@')))
			goto END;

		    if (funny_match && wild_match(funny_match, channel) == 0)
			goto END;
		}

		/* Everything is OK. */
		break;
	}

	case 354:		/* #define RPL_XWHOREPLY	354 */
		xwhoreply(from_server, NULL, comm, ArgList);
		goto END;

	/* XXX Yea yea, these are out of order. so shoot me. */
	case 346:		/* #define RPL_INVITELIST (+I for erf) */
	case 348:		/* #define RPL_EXCEPTLIST (+e for erf) */
	case 367:		/* #define RPL_BANLIST */
		number_of_bans++;
		break;

	case 347:		/* #define END_OF_INVITELIST */
	case 349:		/* #define END_OF_EXCEPTLIST */
	case 368:		/* #define END_OF_BANLIST */
	{
		const char	*channel;

		if (!get_int_var(SHOW_END_OF_MSGS_VAR))
			goto END;

		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

#ifdef IRCII_LIKE_BAN_SUMMARY
		if (do_hook(current_numeric, "%s %s %d", 
			from, channel, number_of_bans))
#else
		if (do_hook(current_numeric, "%s %d %s", 
				from, number_of_bans, channel))
#endif
		{
			put_it("%s Total number of %s on %s - %d",
				banner(), 
				 numeric == 347 ? "invites" :
				(numeric == 349 ? "exceptions" :
				(numeric == 368 ? "bans" : "wounds")),
				channel, number_of_bans);
		}
		goto END;
	}

	/* XXX Shouldn't this set "You're operator" flag for hybrid? */
	case 381: 		/* #define RPL_YOUREOPER        381 */
		if (!is_server_registered(from_server))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		break;

        /* ":%s 401 %s %s :No such nick/channel" */
	case 401:		/* #define ERR_NOSUCHNICK       401 */
	{
		const char	*nick;

		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		if (!is_channel(nick))
		{
		    notify_mark(from_server, nick, 0, 0);
		    if (get_int_var(AUTO_WHOWAS_VAR))
		    {
			int foo = get_int_var(NUM_OF_WHOWAS_VAR);

			if (foo > -1)
				send_to_server("WHOWAS %s %d", nick, foo);
			else
				send_to_server("WHOWAS %s", nick);
		    }
		}

		break;
	}

	/* Bizarre dalnet extended who replies. */
        /* ":%s 402 %s %s :No such server" */
	case 402:
	{
		const char	*server;

		if (!(server = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		fake_who_end(from_server, from, comm, server);
		break;
	}

	/* Yet more bizarre dalnet extended who replies. */
	/* ":%s 522 %s :/WHO Syntax incorrect, use /who ? for help" */
        /* ":%s 523 %s :Error, /who limit of %d exceed." */
	case 522:
	case 523:
	{
		/* 
		 * This dalnet error message doesn't even give us the
		 * courtesy of telling us which who request was in error,
		 * so we have to guess.  Whee.
		 */
		fake_who_end(from_server, from, comm, NULL);
		break;
	}

	case 403:		/* #define ERR_NOSUCHCHANNEL    403 */
	{
		const char *	s;
		const char *	channel;
		const char *	message;

		PasteArgs(ArgList, 1);

		/* Some servers BBC and send back an empty reply. */
		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(message = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		/* Do not accept 403's from remote servers. */
		s = get_server_itsname(from_server);
		if (my_strnicmp(s, from, strlen(s)))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		/* 
		 * Some servers BBC and send this instead of a
		 * 315 numeric when a who request has been completed.
		 */
		if (fake_who_end(from_server, from, comm, channel))
			;

		/*
		 * If you try to JOIN or PART the "*" named channel, as may
		 * happen if epic gets confused, the server may tell us that
		 * channel does not exist.  But it would be death to try to 
		 * destroy that channel as epic will surely do the wrong thing!
		 * Otherwise, we somehow tried to reference a channel that
		 * this server claims does not exist; we blow the channel away
		 * for good measure.
		 */
		else if (strcmp(channel, "*"))
			remove_channel(channel, from_server);

		break;
	}

	case 421:		/* #define ERR_UNKNOWNCOMMAND   421 */
	{
		const char	*token;

		if (!(token = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		if (check_server_redirect(from_server, token))
			goto END;
		if (check_server_wait(from_server, token))
			goto END;

		break;
	}
	case 432:		/* #define ERR_ERRONEUSNICKNAME 432 */
	{
		const char	*nick;

		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		if (!my_stricmp(target, nick))
			yell("WARNING:  Strange invalid nick message received."
					"  You are probably lagged.");
		else if (get_int_var(AUTO_NEW_NICK_VAR))
			fudge_nickname(from_server);
		else
			reset_nickname(from_server);

		break;
	}

	case 437:		/* av2.9's "Nick collision" numeric 437 */
				/* Also, undernet/dalnet "You are banned" */
				/* Also, av2.10's "Can't do that" numeric */
				/* Also, cs's "too many nick changes" num */
	{
		/*
		 * Ugh. What a total trainwreck this is.  Sometimes, I
		 * really hate all the ircd's out there in the world that
		 * have to be supported.
		 *
		 * Well, there are at least four different, occasionally
		 * scrutable ways we can get this numeric.
		 *
		 * 1a) On ircnet -- As an unregistered user, the NICK that
		 *	we are trying to register was used in the past 90
		 *	seconds or so.  The server expects us to send
		 *	another NICK request.
		 *		ARGV[0] IS NICK, REGISTERED IS NO
		 * 1b) On ircnet -- As a registered user, the NICK that 
		 *	we are trying to register was used in the past 90
		 *	seconds or so.  The server expects us not to do
		 * 	anything (like a 432 numeric).
		 *		ARGV[0] IS NICK, REGISTERED IS YES
		 * 2) On ircnet -- As a registered user, we are trying to
		 *	join a channel that was netsplit in the past 24 hours
		 *	or so.  The server expects us not to do anything.
		 *		ARGV[0] IS CHANNEL, REGISTERED IS YES
		 * 3) On undernet/dalnet -- As a registered user, who is
		 *	on a channel where we are banned, a NICK request
		 *	was rejected (because we are banned).  The server
		 *	expects us not to do anything.
		 *		ARGV[0] IS CHANNEL, REGISTERED IS YES
		 * 4) On a comstud efnet servers -- As a registered user, 
		 *	we have changed our nicknames too many times in
		 *	too short a time.  The server expects us not to do
		 *	anything.
		 *		ARGV[0] IS ERROR, ARGV[1] IS NULL.
		 *	I understand this numeric will be moving to 439.
		 */

		/*
		 * Weed out the comstud one first, since it's the most bizarre.
		 */
		if (ArgList[0] && ArgList[1] == NULL)
		{
			accept_server_nickname(from_server, target);
			break;
		}

		/*
		 * Now if it's a channel, it might be ircnet telling us we
		 * can't join the channel, or undernet telling us that we 
		 * can't change our nickname because we're banned.  The 
		 * easiest way to tell is to see if we are on the channel.
		 */
		if (is_channel(ArgList[0]))
		{
			/* XXX Is this really neccesary? */
			if (!im_on_channel(ArgList[0], from_server))
				remove_channel(ArgList[0], from_server);

			break;
		}

		/*
		 * Otherwise, a nick command failed.  Oh boy.
		 * If we are registered, abort the nick change and
		 * hope for the best.
		 */
		if (is_server_registered(from_server))
		{
			accept_server_nickname(from_server, target);
			break;
		}

		/* 
		 * Otherwise, it's an ircnet "nick not available" error.
		 * Let the nickname reset numerics handle this mess.
		 */
		/* FALLTHROUGH */
	}

	case 433:		/* #define ERR_NICKNAMEINUSE    433 */ 
	case 438:		/* EFnet/TS4 "nick collision" numeric 438 */
	case 453:		/* EFnet/TS4 "nickname lost" numeric 453 */
	{
		const char	*nick;

		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		if (!my_stricmp(target, nick))
			/* 
			 * This should stop the "rolling nicks" in their tracks.
			 */
			yell("WARNING:  Strange invalid nick message received."
					"  You are probably lagged.");
		else if (get_int_var(AUTO_NEW_NICK_VAR))
			fudge_nickname(from_server);
		else
			reset_nickname(from_server);

		if (!from)
			from = "-1";

		break;
	}

	case 439:		/* Comstud's "Can't change nickname" */
	{
		accept_server_nickname(from_server, target);
		break;
	}

	case 442:		/* #define ERR_NOTONCHANNEL	442 */
	{
		const char *	s;
		const char *	channel;
		const char *	message;

		PasteArgs(ArgList, 1);

		/* Some servers BBC and send back an empty reply. */
		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(message = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		/* Do not accept this numeric from remote servers */
		s = get_server_itsname(from_server);
		if (my_strnicmp(s, from, strlen(s)))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		/* Do not ever delete the "*" channel */
		if (strcmp(ArgList[0], "*"))
		    remove_channel(ArgList[0], from_server);

		break;
	}

	case 451:		/* #define ERR_NOTREGISTERED    451 */
	/*
	 * Sometimes the server doesn't catch the USER line, so
	 * here we send a simplified version again  -lynx 
	 */
		register_server(from_server, NULL);
		break;

	case 462:		/* #define ERR_ALREADYREGISTRED 462 */
		change_server_nickname(from_server, NULL);
		break;

	case 465:		/* #define ERR_YOUREBANNEDCREEP 465 */
	{
		/* 
		 * There used to be a say() here, but if we arent 
		 * connected to a server, then doing say() is not
		 * a good idea.  So now it just doesnt do anything.
		 */
		server_reconnects_to(from_server, NOSERV);
		break;
	}

	case 477:		/* #define ERR_NEEDREGGEDNICK	477 */
		/* IRCnet has a different 477 numeric. */
		if (ArgList[0] && *ArgList[0] == '+')
			break;
		/* FALLTHROUGH */
	case 471:		/* #define ERR_CHANNELISFULL    471 */
	case 473:		/* #define ERR_INVITEONLYCHAN   473 */
	case 474:		/* #define ERR_BANNEDFROMCHAN   474 */
	case 475: 		/* #define ERR_BADCHANNELKEY    475 */
	case 476:		/* #define ERR_BADCHANMASK      476 */
	{
		const char	*channel;

		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		cant_join_channel(ArgList[0], from_server);
		break;
	}
	}

/* DEFAULT OFFER */
	/*
	 * This is the "default hook" case, where we offer to the user all of
	 * the numerics that were not offered above.  We simply catenate
	 * all of the arguments into a string and offer to the user.
	 * If the user bites, then we skip the "default display" section.
	 */
	copy = alloca(IRCD_BUFFER_SIZE + 1);
	*copy = 0;

	for (i = 0; ArgList[i]; i++)
	{
		if (i)
			strlcat(copy, " ", IRCD_BUFFER_SIZE);
		strlcat(copy, ArgList[i], IRCD_BUFFER_SIZE);
	}

	if (!do_hook(current_numeric, "%s %s", from, copy))
		goto END;

DISPLAY:
/* DEFAULT DISPLAY */
	/*
	 * This is the "default display" case, where if the user does not 
	 * hook the numeric, we output the message in some special way.
	 * If a numeric does not require special outputting, then we will
	 * just display it with ``display_msg''
	 */
	switch (numeric)
	{
	case 221: 		/* #define RPL_UMODEIS          221 */
	{
		const char *umode;

		PasteArgs(ArgList, 0);
		if (!(umode = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s Your user mode is \"%s\"", banner(), umode);
		break;
	}

	case 271:		/* #define SILENCE_LIST		271 */
	{
		const char *perp, *victim;

		PasteArgs(ArgList, 1);
		if (!(perp = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(victim = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s is ignoring %s", banner(), perp, victim);
		break;
	}

	case 301:		/* #define RPL_AWAY             301 */
	{
		const char *nick, *message;

		PasteArgs(ArgList, 1);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(message = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s is away: %s", banner(), nick, message);
		break;
	}

	case 311:		/* #define RPL_WHOISUSER        311 */
	{
		const char *nick, *user, *host, *channel, *name;

		PasteArgs(ArgList, 4);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(user = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(host = ArgList[2]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(channel = ArgList[3]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(name = ArgList[4]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s is %s@%s (%s)", banner(), nick, user, host, name);
		break;
	}

	case 312:		/* #define RPL_WHOISSERVER      312 */
	{
		const char *nick, *server, *pithy;

		PasteArgs(ArgList, 2);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(server = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(pithy = ArgList[2]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s on irc via server %s (%s)", banner(), server, pithy);
		break;
	}

	case 313:		/* #define RPL_WHOISOPERATOR    313 */
	{
		const char *nick, *message;

		PasteArgs(ArgList, 1);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(message = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s %s", banner(), ArgList[0], ArgList[1]);
		break;
	}

	case 314:		/* #define RPL_WHOWASUSER       314 */
	{
		const char *nick, *user, *host, *unused, *name;

		PasteArgs(ArgList, 4);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(user = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(host = ArgList[2]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(unused = ArgList[3]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(name = ArgList[4]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s was %s@%s (%s)",banner(), nick, user, host, name);
		break;
	}

	case 317:		/* #define RPL_WHOISIDLE        317 */
	{
		const char *nick, *idle_str, *startup_str;
		int		idle;
		const char *	unit;
		char 	startup_ctime[128];

		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(idle_str = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(startup_str = ArgList[2])) { /* No problem */; } 

		*startup_ctime = 0;
		if (startup_str)		/* Undernet/TS4 */
		{
		    time_t	startup;

		    if ((startup = atol(startup_str)) != 0)
			snprintf(startup_ctime, 128, ", signed on at %s", 
							my_ctime(startup));
		}

		if ((idle = atoi(idle_str)) > 59)
		{
			idle /= 60;
			unit = "minute";
		}
		else
			unit = "second";

		put_it ("%s %s has been idle %d %ss%s",
			banner(), nick, idle, unit, startup_ctime);
		break;
	}

	case 318:		/* #define RPL_ENDOFWHOIS       318 */
	{
		PasteArgs(ArgList, 0);
		if (get_int_var(SHOW_END_OF_MSGS_VAR))
			display_msg(from, comm, ArgList);
		break;
	}

	case 319:		/* #define RPL_WHOISCHANNELS    319 */
	{
		const char *nick, *channels;

		PasteArgs(ArgList, 1);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(channels = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s on channels: %s", banner(), channels);
		break;
	}

	case 321:		/* #define RPL_LISTSTART	321 */
		/* Our screwy 321 handling demands this. BAH! */
		put_it("%s Channel Users Topic", banner());
		break;

	case 322:		/* #define RPL_LIST             322 */
	{
		static char format[25];
		static int last_width = -1;
		const char *channel, *user_cnt, *line;

		PasteArgs(ArgList, 2);
		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(user_cnt = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(line = ArgList[2]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		/* Figure out how to display this to the user. */
		if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
		{
			if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)))
				snprintf(format, 25, "%%-%u.%us %%-5s  %%s",
				(unsigned) last_width,
				(unsigned) last_width);
			else
				strlcpy(format, "%s\t%-5s  %s", sizeof format);
		}

		if (*channel == '*')
			say(format, "Prv", user_cnt, line);
		else
			say(format, check_channel_type(channel),
				user_cnt, line);

		break;
	}

	case 324:		/* #define RPL_CHANNELMODEIS    324 */
	{
		const char      *mode, *channel;

		PasteArgs(ArgList, 1);
		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(mode = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s Mode for channel %s is \"%s\"",
				banner(), channel, mode);
		break;
	}

	case 329:		/* #define CREATION_TIME	329 */
	{
		const char *channel, *time1_str, *time2_str, *time3_str;
		time_t	time1, time2, time3;

		PasteArgs(ArgList, 2);
		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(time1_str = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(time2_str = ArgList[2])) { /* No problem */; }
		if (!(time3_str = ArgList[3])) { /* No problem */; }


		/* Erf/TS4 support */
		if (time2_str && time3_str)
		{
			time1 = (time_t)my_atol(time1_str);
			time2 = (time_t)my_atol(time2_str);
			time3 = (time_t)my_atol(time3_str);

			put_it("%s Channel %s was created at %ld, "
				  "+c was last set at %ld, "
				  "and has been opless since %ld", banner(), 
					channel, time1, time2, time3);
		}
		else
		{
			time1 = (time_t)my_atol(time1_str);

			put_it("%s Channel %s was created at %s",
					banner(), channel, my_ctime(time1));
		}
		break;
	}

	case 330:		/* #define RPL_WHOISLOGGEDIN	330 */
	{
		const char *nick, *login, *reason;

		PasteArgs(ArgList, 2);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(login = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(reason = ArgList[2]))
			{ reason = "is logged in as"; }

		put_it("%s %s %s %s", banner(), nick, reason, login);
		break;
	}

	case 332:		/* #define RPL_TOPIC            332 */
	{
		const char *channel, *topic;

		PasteArgs(ArgList, 1);
		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(topic = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s Topic for %s: %s", banner(), channel, topic);
		break;
	}

	case 333:		/* #define RPL_TOPICWHOTIME	333 */
	{
		const char *channel, *nick, *when_str;
		time_t	howlong;

		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(nick = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(when_str = ArgList[2]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		howlong = time(NULL) - my_atol(when_str);
		put_it("%s The topic was set by %s %ld sec ago",banner(), 
				nick, howlong);
		break;
	}

	case 341:		/* #define RPL_INVITING         341 */
	{
		const char *nick, *channel;

		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(channel = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		message_from(channel, LOG_CRAP);
		put_it("%s Inviting %s to channel %s", banner(), nick, channel);
		break;
	}

	case 351:		/* #define RPL_VERSION          351 */
	{
		const char *version, *itsname, *stuff;

		PasteArgs(ArgList, 2);
		if (!(version = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(itsname = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(stuff = ArgList[2]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s Server %s: %s %s",banner(), itsname, version, stuff);
		break;
	}

	case 353:		/* #define RPL_NAMREPLY         353 */
	{
		static int last_width;
		char format[41];
		const char	*type, *channel, *line;

		PasteArgs(ArgList, 2);
		if (!(type = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(channel = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(line = ArgList[2]))
			{ line = empty_string; }

		/* This is only for when the user joined the channel */
		if (channel_is_syncing(channel, from_server))
		{
			/* If the user bites on /ON NAMES, then skip the rest */
			message_from(channel, LOG_CRAP);
			if (do_hook(NAMES_LIST, "%s %s", channel, line))
			    if (get_int_var(SHOW_CHANNEL_NAMES_VAR))
				say("Users on %s: %s",
					check_channel_type(channel), line);
			break;
		}

		/* If the user grabs /ON NAMES then just stop right here */
		if (!do_hook(NAMES_LIST, "%s %s", channel, line))
			break;

		/* This all is for when the user has not just joined channel */
		if (last_width != get_int_var(CHANNEL_NAME_WIDTH_VAR))
		{
			if ((last_width = get_int_var(CHANNEL_NAME_WIDTH_VAR)))
				snprintf(format, 40, "%%s: %%-%u.%us %%s",
					(unsigned char) last_width,
					(unsigned char) last_width);
			else
				strlcpy(format, "%s: %s\t%s", sizeof format);
		}
		else
			strlcpy(format, "%s: %s\t%s", sizeof format);

		message_from(channel, LOG_CRAP);
		if (*type == '=') 
		{
		    if (last_width && ((int)strlen(channel) > last_width))
		    {
			char *channel_copy = LOCAL_COPY(channel);
			channel_copy[last_width-1] = '>';
			channel_copy[last_width] = 0;
			channel = channel_copy;
		    }
		    put_it(format, "Pub", check_channel_type(channel), line);
		}
		else if (*type == '*') 
		    put_it(format, "Prv", check_channel_type(channel), line);
		else if (*type == '@')
		    put_it(format, "Sec", check_channel_type(channel), line);

		break;
	}

	case 364:		/* #define RPL_LINKS            364 */
	{
		const char	*itsname, *uplink, *stuff;

		PasteArgs(ArgList, 2);
		if (!(itsname = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(uplink = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(stuff = ArgList[2])) { stuff = empty_string; }

		if (stuff)
			put_it("%s %-20s %-20s %s", banner(),
					itsname, uplink, stuff);
		else
			put_it("%s %-20s %s", banner(), itsname, uplink);

		break;
	}

	case 366:		/* #define RPL_ENDOFNAMES       366 */
	{
		const char	*channel;

		if (!get_int_var(SHOW_END_OF_MSGS_VAR))
			break;

		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		if (!channel_is_syncing(channel, from_server))
			display_msg(from, comm, ArgList);

		break;
	}

	case 346:		/* +I on erf */
	case 348:		/* +e on erf */
	case 367:		/* +b */
	{
		const char	*channel, *ban, *perp, *when_str;
		time_t	howlong;

		if (!(channel = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(ban = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(perp = ArgList[2])) { /* No problem. */ }
		if (!(when_str = ArgList[3])) { /* No problem. */ }

		if (perp && when_str) 
		{
			howlong = time(NULL) - my_atol(when_str);
			put_it("%s %s %-25s set by %-10s %ld sec ago", 
				banner(), channel, ban, perp, howlong);
		}
		else
			put_it("%s %s %s", banner(), channel, ban);

		break;
	}

	case 401:		/* #define ERR_NOSUCHNICK       401 */
	{
		const char	*nick, *stuff;

		PasteArgs(ArgList, 1);
		if (!(nick = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }
		if (!(stuff = ArgList[1]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s: %s", banner(), nick, stuff);
		break;
	}

	case 219:		/* #define RPL_ENDOFSTATS       219 */
	case 232:		/* #define RPL_ENDOFSERVICES    232 */
	case 365:		/* #define RPL_ENDOFLINKS       365 */
	case 369:		/* #define RPL_ENDOFWHOWAS      369 */
	case 374:		/* #define RPL_ENDOFINFO        374 */
	case 394:		/* #define RPL_ENDOFUSERS       394 */
	{
		PasteArgs(ArgList, 0);
		if (get_int_var(SHOW_END_OF_MSGS_VAR))
			display_msg(from, comm, ArgList);
		break;
	}

	case 471:		/* #define ERR_CHANNELISFULL    471 */
	{
		const char *message;

		PasteArgs(ArgList, 0);
		if (!(message = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s (Channel is full)", banner(), message);
		break;
	}
	case 473:		/* #define ERR_INVITEONLYCHAN   473 */
	{
		const char *message;

		PasteArgs(ArgList, 0);
		if (!(message = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s (You must be invited)", banner(), message);
		break;
	}
	case 474:		/* #define ERR_BANNEDFROMCHAN   474 */
	{
		const char *message;

		PasteArgs(ArgList, 0);
		if (!(message = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s (You are banned)", banner(), message);
		break;
	}
	case 475: 		/* #define ERR_BADCHANNELKEY    475 */
	{
		const char *message;

		PasteArgs(ArgList, 0);
		if (!(message = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s (You must give the correct key)", 
						banner(), message);
		break;
	}
	case 476:		/* #define ERR_BADCHANMASK      476 */
	{
		const char *message;

		PasteArgs(ArgList, 0);
		if (!(message = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		put_it("%s %s (Bad channel mask)", banner(), message);
		break;
	}
	case 477:		/* #define ERR_NEEDREGGEDNICK	477 */
	{
		const char *message;

		PasteArgs(ArgList, 0);
		if (!(message = ArgList[0]))
			{ rfc1459_odd(from, comm, ArgList); goto END; }

		/* IRCnet has a different 477 numeric. */
		if (message && *message == '+')
		{
			display_msg(from, comm, ArgList);
			break;
		}

		PasteArgs(ArgList, 0);
		put_it("%s %s (You must use a registered nickname)", 
					banner(), message);
		break;
	}

	default:
		display_msg(from, comm, ArgList);
	}

END:
	/*
	 * This is where we clean up after our numeric.  Numeric-specific
	 * cleanups can occur here, and then below we reset the display
	 * settings.
	 */
	switch (numeric)
	{
	case 347:		/* #define END_OF_INVITELIST */
	case 349:		/* #define END_OF_EXCEPTLIST */
	case 368:
		number_of_bans = 0;
		break;
	case 464:		/* #define ERR_PASSWDMISMATCH   464 */
	{
		char	server_num[8];

		if (oper_command)
			oper_command = 0;
		else if (!is_server_registered(from_server))
		{
			server_reconnects_to(from_server, NOSERV);
			say("Password required for connection to server %s",
				get_server_name(from_server));
			if (!dumb_mode)
			{
				strlcpy(server_num, ltoa(from_server), sizeof server_num);
				add_wait_prompt("Server Password:", 
					password_sendline,
				       server_num, WAIT_PROMPT_LINE, 0);
			}
		}
	}
	}

	current_numeric = old_current_numeric;
	set_lastlog_msg_level(lastlog_level);
	message_from(NULL, LOG_CRAP);
}
Exemple #28
0
static void	update_all_status_wrapper (void *stuff)
{
	update_all_status();
}