Exemple #1
0
static void cmd_info(irc_t *irc, char **cmd)
{
	struct im_connection *ic;
	account_t *a;

	if (!cmd[2]) {
		irc_user_t *iu = irc_user_by_name(irc, cmd[1]);
		if (!iu || !iu->bu) {
			irc_rootmsg(irc, "Nick `%s' does not exist", cmd[1]);
			return;
		}
		ic = iu->bu->ic;
		cmd[2] = iu->bu->handle;
	} else if (!(a = account_get(irc->b, cmd[1]))) {
		irc_rootmsg(irc, "Invalid account");
		return;
	} else if (!((ic = a->ic) && (a->ic->flags & OPT_LOGGED_IN))) {
		irc_rootmsg(irc, "That account is not on-line");
		return;
	}

	if (!ic->acc->prpl->get_info) {
		irc_rootmsg(irc, "Command `%s' not supported by this protocol", cmd[0]);
	} else {
		ic->acc->prpl->get_info(ic, cmd[2]);
	}
}
Exemple #2
0
static void irc_cmd_whois( irc_t *irc, char **cmd )
{
	char *nick = cmd[1];
	irc_user_t *iu = irc_user_by_name( irc, nick );
	
	if( iu )
		irc_send_whois( iu );
	else
		irc_send_num( irc, 401, "%s :Nick does not exist", nick );
}
Exemple #3
0
static void irc_cmd_ison( irc_t *irc, char **cmd )
{
	char buff[IRC_MAX_LINE];
	int lenleft, i;
	
	buff[0] = '\0';
	
	/* [SH] Leave room for : and \0 */
	lenleft = IRC_MAX_LINE - 2;
	
	for( i = 1; cmd[i]; i ++ )
	{
		char *this, *next;
		
		this = cmd[i];
		while( *this )
		{
			irc_user_t *iu;
			
			if( ( next = strchr( this, ' ' ) ) )
				*next = 0;
			
			if( ( iu = irc_user_by_name( irc, this ) ) &&
			    iu->bu && iu->bu->flags & BEE_USER_ONLINE )
			{
				lenleft -= strlen( iu->nick ) + 1;
				
				if( lenleft < 0 )
					break;
				
				strcat( buff, iu->nick );
				strcat( buff, " " );
			}
			
			if( next )
			{
				*next = ' ';
				this = next + 1;
			}
			else
			{
				break;
			}    
		}
		
		/* *sigh* */
		if( lenleft < 0 )
			break;
	}
	
	if( strlen( buff ) > 0 )
		buff[strlen(buff)-1] = '\0';
	
	irc_send_num( irc, 303, ":%s", buff );
}
Exemple #4
0
static void irc_cmd_privmsg( irc_t *irc, char **cmd )
{
	irc_channel_t *ic;
	irc_user_t *iu;
	
	if( !cmd[2] ) 
	{
		irc_send_num( irc, 412, ":No text to send" );
		return;
	}
	
	/* Don't treat CTCP actions as real CTCPs, just convert them right now. */
	if( g_strncasecmp( cmd[2], "\001ACTION", 7 ) == 0 )
	{
		cmd[2] += 4;
		memcpy( cmd[2], "/me", 3 );
		if( cmd[2][strlen(cmd[2])-1] == '\001' )
			cmd[2][strlen(cmd[2])-1] = '\0';
	}
	
	if( irc_channel_name_ok( cmd[1] ) &&
	    ( ic = irc_channel_by_name( irc, cmd[1] ) ) )
	{
		if( cmd[2][0] == '\001' )
		{
			/* CTCPs to channels? Nah. Maybe later. */
		}
		else if( ic->f->privmsg )
			ic->f->privmsg( ic, cmd[2] );
	}
	else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) )
	{
		if( cmd[2][0] == '\001' )
		{
			char **ctcp;
			
			if( iu->f->ctcp == NULL )
				return;
			if( cmd[2][strlen(cmd[2])-1] == '\001' )
				cmd[2][strlen(cmd[2])-1] = '\0';
			
			ctcp = split_command_parts( cmd[2] + 1 );
			iu->f->ctcp( iu, ctcp );
		}
		else if( iu->f->privmsg )
		{
			iu->last_channel = NULL;
			iu->f->privmsg( iu, cmd[2] );
		}
	}
	else
	{
		irc_send_num( irc, 401, "%s :No such nick/channel", cmd[1] );
	}
}
Exemple #5
0
static void cmd_rename(irc_t *irc, char **cmd)
{
	irc_user_t *iu, *old;
	gboolean del = g_strcasecmp(cmd[1], "-del") == 0;

	iu = irc_user_by_name(irc, cmd[del ? 2 : 1]);

	if (iu == NULL) {
		irc_rootmsg(irc, "Nick `%s' does not exist", cmd[1]);
	} else if (del) {
		if (iu->bu) {
			bee_irc_user_nick_reset(iu);
		}
		irc_rootmsg(irc, "Nickname reset to `%s'", iu->nick);
	} else if (iu == irc->user) {
		irc_rootmsg(irc, "Use /nick to change your own nickname");
	} else if (!nick_ok(irc, cmd[2])) {
		irc_rootmsg(irc, "Nick `%s' is invalid", cmd[2]);
	} else if ((old = irc_user_by_name(irc, cmd[2])) && old != iu) {
		irc_rootmsg(irc, "Nick `%s' already exists", cmd[2]);
	} else {
		if (!irc_user_set_nick(iu, cmd[2])) {
			irc_rootmsg(irc, "Error while changing nick");
			return;
		}

		if (iu == irc->root) {
			/* If we're called internally (user did "set root_nick"),
			   let's not go O(INF). :-) */
			if (strcmp(cmd[0], "set_rename") != 0) {
				set_setstr(&irc->b->set, "root_nick", cmd[2]);
			}
		} else if (iu->bu) {
			nick_set(iu->bu, cmd[2]);
		}

		irc_rootmsg(irc, "Nick successfully changed");
	}
}
Exemple #6
0
static void cmd_allow(irc_t *irc, char **cmd)
{
	struct im_connection *ic;
	account_t *a;

	if (!cmd[2] && (a = account_get(irc->b, cmd[1])) && a->ic) {
		char *format;
		GSList *l;

		if (strchr(irc->umode, 'b') != NULL) {
			format = "%s\t%s";
		} else {
			format = "%-32.32s  %-16.16s";
		}

		irc_rootmsg(irc, format, "Handle", "Nickname");
		for (l = a->ic->permit; l; l = l->next) {
			bee_user_t *bu = bee_user_by_handle(irc->b, a->ic, l->data);
			irc_user_t *iu = bu ? bu->ui_data : NULL;
			irc_rootmsg(irc, format, l->data, iu ? iu->nick : "(none)");
		}
		irc_rootmsg(irc, "End of list.");

		return;
	} else if (!cmd[2]) {
		irc_user_t *iu = irc_user_by_name(irc, cmd[1]);
		if (!iu || !iu->bu) {
			irc_rootmsg(irc, "Nick `%s' does not exist", cmd[1]);
			return;
		}
		ic = iu->bu->ic;
		cmd[2] = iu->bu->handle;
	} else if (!(a = account_get(irc->b, cmd[1]))) {
		irc_rootmsg(irc, "Invalid account");
		return;
	} else if (!((ic = a->ic) && (a->ic->flags & OPT_LOGGED_IN))) {
		irc_rootmsg(irc, "That account is not on-line");
		return;
	}

	if (!ic->acc->prpl->rem_deny || !ic->acc->prpl->add_permit) {
		irc_rootmsg(irc, "Command `%s' not supported by this protocol", cmd[0]);
	} else {
		imc_rem_block(ic, cmd[2]);
		imc_add_allow(ic, cmd[2]);

		irc_rootmsg(irc, "Buddy `%s' moved from block- to allow-list", cmd[2]);
	}
}
Exemple #7
0
static void irc_cmd_watch( irc_t *irc, char **cmd )
{
	int i;
	
	/* Obviously we could also mark a user structure as being
	   watched, but what if the WATCH command is sent right
	   after connecting? The user won't exist yet then... */
	for( i = 1; cmd[i]; i ++ )
	{
		char *nick;
		irc_user_t *iu;
		
		if( !cmd[i][0] || !cmd[i][1] )
			break;
		
		nick = g_strdup( cmd[i] + 1 );
		nick_lc( nick );
		
		iu = irc_user_by_name( irc, nick );
		
		if( cmd[i][0] == '+' )
		{
			if( !g_hash_table_lookup( irc->watches, nick ) )
				g_hash_table_insert( irc->watches, nick, nick );
			
			if( iu && iu->bu && iu->bu->flags & BEE_USER_ONLINE )
				irc_send_num( irc, 604, "%s %s %s %d :%s", iu->nick, iu->user,
				              iu->host, (int) time( NULL ), "is online" );
			else
				irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*",
				              (int) time( NULL ), "is offline" );
		}
		else if( cmd[i][0] == '-' )
		{
			gpointer okey, ovalue;
			
			if( g_hash_table_lookup_extended( irc->watches, nick, &okey, &ovalue ) )
			{
				g_hash_table_remove( irc->watches, okey );
				g_free( okey );
				
				irc_send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );
			}
		}
	}
}
Exemple #8
0
static void irc_cmd_notice( irc_t *irc, char **cmd )
{
	irc_user_t *iu;
	
	if( !cmd[2] ) 
	{
		irc_send_num( irc, 412, ":No text to send" );
		return;
	}
	
	/* At least for now just echo. IIRC some IRC clients use self-notices
	   for lag checks, so try to support that. */
	if( nick_cmp( cmd[1], irc->user->nick ) == 0 )
		irc_send_msg( irc->user, "NOTICE", irc->user->nick, cmd[2], NULL );
	else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) )
		iu->f->privmsg( iu, cmd[2] );
}
Exemple #9
0
static void irc_cmd_userhost( irc_t *irc, char **cmd )
{
	int i;
	
	/* [TV] Usable USERHOST-implementation according to
		RFC1459. Without this, mIRC shows an error
		while connecting, and the used way of rejecting
		breaks standards.
	*/
	
	for( i = 1; cmd[i]; i ++ )
	{
		irc_user_t *iu = irc_user_by_name( irc, cmd[i] );
		
		if( iu )
			irc_send_num( irc, 302, ":%s=%c%s@%s", iu->nick,
			              irc_user_get_away( iu ) ? '-' : '+',
			              iu->user, iu->host );
	}
}
Exemple #10
0
static void irc_cmd_who( irc_t *irc, char **cmd )
{
	char *channel = cmd[1];
	irc_channel_t *ic;
	irc_user_t *iu;
	
	if( !channel || *channel == '0' || *channel == '*' || !*channel )
		irc_send_who( irc, irc->users, "**" );
	else if( ( ic = irc_channel_by_name( irc, channel ) ) )
		irc_send_who( irc, ic->users, channel );
	else if( ( iu = irc_user_by_name( irc, channel ) ) )
	{
		/* Tiny hack! */
		GSList *l = g_slist_append( NULL, iu );
		irc_send_who( irc, l, channel );
		g_slist_free( l );
	}
	else
		irc_send_num( irc, 403, "%s :No such channel", channel );
}
Exemple #11
0
static void irc_cmd_invite( irc_t *irc, char **cmd )
{
	irc_channel_t *ic;
	irc_user_t *iu;
	
	if( ( iu = irc_user_by_name( irc, cmd[1] ) ) == NULL )
	{
		irc_send_num( irc, 401, "%s :No such nick", cmd[1] );
		return;
	}
	else if( ( ic = irc_channel_by_name( irc, cmd[2] ) ) == NULL )
	{
		irc_send_num( irc, 403, "%s :No such channel", cmd[2] );
		return;
	}
	
	if( !ic->f->invite )
		irc_send_num( irc, 482, "%s :Can't invite people here", cmd[2] );
	else if( ic->f->invite( ic, iu ) )
		irc_send_num( irc, 341, "%s %s", iu->nick, ic->name );
}
Exemple #12
0
static void irc_cmd_nick( irc_t *irc, char **cmd )
{
	irc_user_t *iu;
	
	if( ( iu = irc_user_by_name( irc, cmd[1] ) ) && iu != irc->user )
	{
		irc_send_num( irc, 433, "%s :This nick is already in use", cmd[1] );
	}
	else if( !nick_ok( cmd[1] ) )
	{
		/* [SH] Invalid characters. */
		irc_send_num( irc, 432, "%s :This nick contains invalid characters", cmd[1] );
	}
	else if( irc->status & USTATUS_LOGGED_IN )
	{
		/* WATCH OUT: iu from the first if reused here to check if the
		   new nickname is the same (other than case, possibly). If it
		   is, no need to reset identify-status. */
		if( ( irc->status & USTATUS_IDENTIFIED ) && iu != irc->user )
		{
			irc_setpass( irc, NULL );
			irc->status &= ~USTATUS_IDENTIFIED;
			irc_umode_set( irc, "-R", 1 );
			irc_rootmsg( irc, "Changing nicks resets your identify status. "
			             "Re-identify or register a new account if you want "
			             "your configuration to be saved. See \x02help "
			             "nick_changes\x02." );
		}
		
		if( strcmp( cmd[1], irc->user->nick ) != 0 )
			irc_user_set_nick( irc->user, cmd[1] );
	}
	else
	{
		g_free( irc->user->nick );
		irc->user->nick = g_strdup( cmd[1] );
		
		irc_check_login( irc );
	}
}
Exemple #13
0
static void cmd_remove(irc_t *irc, char **cmd)
{
	irc_user_t *iu;
	bee_user_t *bu;
	char *s;

	if (!(iu = irc_user_by_name(irc, cmd[1])) || !(bu = iu->bu)) {
		irc_rootmsg(irc, "Buddy `%s' not found", cmd[1]);
		return;
	}
	s = g_strdup(bu->handle);

	bu->ic->acc->prpl->remove_buddy(bu->ic, bu->handle, NULL);
	nick_del(bu);
	if (g_slist_find(irc->users, iu)) {
		bee_user_free(irc->b, bu);
	}

	irc_rootmsg(irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1]);
	g_free(s);

	return;
}
Exemple #14
0
static void irc_cmd_nick( irc_t *irc, char **cmd )
{
	irc_user_t *iu;
	
	if( ( iu = irc_user_by_name( irc, cmd[1] ) ) && iu != irc->user )
	{
		irc_send_num( irc, 433, "%s :This nick is already in use", cmd[1] );
	}
	else if( !nick_ok( cmd[1] ) )
	{
		/* [SH] Invalid characters. */
		irc_send_num( irc, 432, "%s :This nick contains invalid characters", cmd[1] );
	}
	else if( irc->status & USTATUS_LOGGED_IN )
	{
		if( irc->status & USTATUS_IDENTIFIED )
		{
			irc_setpass( irc, NULL );
			irc->status &= ~USTATUS_IDENTIFIED;
			irc_umode_set( irc, "-R", 1 );
			irc_usermsg( irc, "Changing nicks resets your identify status. "
			             "Re-identify or register a new account if you want "
			             "your configuration to be saved. See \x02help "
			             "nick_changes\x02." );
		}
		
		irc_user_set_nick( irc->user, cmd[1] );
	}
	else
	{
		g_free( irc->user->nick );
		irc->user->nick = g_strdup( cmd[1] );
		
		irc_check_login( irc );
	}
}
Exemple #15
0
static void cmd_add(irc_t *irc, char **cmd)
{
	account_t *a;
	int add_on_server = 1;
	char *handle = NULL, *s;

	if (g_strcasecmp(cmd[1], "-tmp") == 0) {
		MIN_ARGS(3);
		add_on_server = 0;
		cmd++;
	}

	if (!(a = account_get(irc->b, cmd[1]))) {
		irc_rootmsg(irc, "Invalid account");
		return;
	} else if (!(a->ic && (a->ic->flags & OPT_LOGGED_IN))) {
		irc_rootmsg(irc, "That account is not on-line");
		return;
	}

	if (cmd[3]) {
		if (!nick_ok(irc, cmd[3])) {
			irc_rootmsg(irc, "The requested nick `%s' is invalid", cmd[3]);
			return;
		} else if (irc_user_by_name(irc, cmd[3])) {
			irc_rootmsg(irc, "The requested nick `%s' already exists", cmd[3]);
			return;
		} else {
			nick_set_raw(a, cmd[2], cmd[3]);
		}
	}

	if ((a->flags & ACC_FLAG_HANDLE_DOMAINS) && cmd[2][0] != '_' &&
	    (!(s = strchr(cmd[2], '@')) || s[1] == '\0')) {
		/* If there's no @ or it's the last char, append the user's
		   domain name now. Exclude handles starting with a _ so
		   adding _xmlconsole will keep working. */
		if (s) {
			*s = '\0';
		}
		if ((s = strchr(a->user, '@'))) {
			cmd[2] = handle = g_strconcat(cmd[2], s, NULL);
		}
	}

	if (add_on_server) {
		irc_channel_t *ic;
		char *s, *group = NULL;;

		if ((ic = irc->root->last_channel) &&
		    (s = set_getstr(&ic->set, "fill_by")) &&
		    strcmp(s, "group") == 0 &&
		    (group = set_getstr(&ic->set, "group"))) {
			irc_rootmsg(irc, "Adding `%s' to contact list (group %s)",
			            cmd[2], group);
		} else {
			irc_rootmsg(irc, "Adding `%s' to contact list", cmd[2]);
		}

		a->prpl->add_buddy(a->ic, cmd[2], group);
	} else {
		bee_user_t *bu;
		irc_user_t *iu;

		/* Only for add -tmp. For regular adds, this callback will
		   be called once the IM server confirms. */
		if ((bu = bee_user_new(irc->b, a->ic, cmd[2], BEE_USER_LOCAL)) &&
		    (iu = bu->ui_data)) {
			irc_rootmsg(irc, "Temporarily assigned nickname `%s' "
			            "to contact `%s'", iu->nick, cmd[2]);
		}
	}

	g_free(handle);
}
Exemple #16
0
static void cmd_chat(irc_t *irc, char **cmd)
{
	account_t *acc;

	if (g_strcasecmp(cmd[1], "add") == 0) {
		char *channel, *s;
		struct irc_channel *ic;

		MIN_ARGS(3);

		if (!(acc = account_get(irc->b, cmd[2]))) {
			irc_rootmsg(irc, "Invalid account");
			return;
		} else if (!acc->prpl->chat_join) {
			irc_rootmsg(irc, "Named chatrooms not supported on that account.");
			return;
		}

		if (cmd[4] == NULL) {
			channel = g_strdup(cmd[3]);
			if ((s = strchr(channel, '@'))) {
				*s = 0;
			}
		} else {
			channel = g_strdup(cmd[4]);
		}

		if (strchr(CTYPES, channel[0]) == NULL) {
			s = g_strdup_printf("#%s", channel);
			g_free(channel);
			channel = s;

			irc_channel_name_strip(channel);
		}

		if ((ic = irc_channel_new(irc, channel)) &&
		    set_setstr(&ic->set, "type", "chat") &&
		    set_setstr(&ic->set, "chat_type", "room") &&
		    set_setstr(&ic->set, "account", cmd[2]) &&
		    set_setstr(&ic->set, "room", cmd[3])) {
			irc_rootmsg(irc, "Chatroom successfully added.");
		} else {
			if (ic) {
				irc_channel_free(ic);
			}

			irc_rootmsg(irc, "Could not add chatroom.");
		}
		g_free(channel);
	} else if (g_strcasecmp(cmd[1], "with") == 0) {
		irc_user_t *iu;

		MIN_ARGS(2);

		if ((iu = irc_user_by_name(irc, cmd[2])) &&
		    iu->bu && iu->bu->ic->acc->prpl->chat_with) {
			if (!iu->bu->ic->acc->prpl->chat_with(iu->bu->ic, iu->bu->handle)) {
				irc_rootmsg(irc, "(Possible) failure while trying to open "
				            "a groupchat with %s.", iu->nick);
			}
		} else {
			irc_rootmsg(irc, "Can't open a groupchat with %s.", cmd[2]);
		}
	} else if (g_strcasecmp(cmd[1], "list") == 0 ||
	           g_strcasecmp(cmd[1], "set") == 0 ||
	           g_strcasecmp(cmd[1], "del") == 0) {
		irc_rootmsg(irc,
		            "Warning: The \002chat\002 command was mostly replaced with the \002channel\002 command.");
		cmd_channel(irc, cmd);
	} else {
		irc_rootmsg(irc,
		            "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat",
		            cmd[1]);
	}
}