diff options
Diffstat (limited to 'degesch.c')
| -rw-r--r-- | degesch.c | 113 | 
1 files changed, 85 insertions, 28 deletions
| @@ -6253,41 +6253,22 @@ handle_command_cycle (struct app_context *ctx, char *arguments)  	return true;  } -static bool -handle_command_channel_mode (struct app_context *ctx, char *arguments, -	const char *command_name, bool adding, char mode_char) +static void +mass_channel_mode (struct server *s, const char *channel_name, +	bool adding, char mode_char, struct str_vector *v)  { -	if (!server_command_check (ctx, command_name, true)) -		return true; - -	struct server *s = ctx->current_buffer->server; -	char *channel_name = try_get_channel (ctx, &arguments); -	if (!channel_name) -	{ -		buffer_send_error (ctx, ctx->current_buffer, -			"%s: %s", "Can't set mode", -			"no channel name given and this buffer is not a channel"); -		return true; -	} -	if (!*arguments) -		return false; - -	struct str_vector v; -	str_vector_init (&v); -	split_str_ignore_empty (arguments, ' ', &v); -  	size_t n; -	for (size_t i = 0; i < v.len; i += n) +	for (size_t i = 0; i < v->len; i += n)  	{  		struct str modes;   str_init (&modes);  		struct str params;  str_init (¶ms); -		n = MIN (v.len - i, s->irc_max_modes); +		n = MIN (v->len - i, s->irc_max_modes);  		str_append_printf (&modes, "MODE %s %c", channel_name, "-+"[adding]);  		for (size_t k = 0; k < n; k++)  		{  			str_append_c (&modes, mode_char); -			str_append_printf (¶ms, " %s", v.vector[i + k]); +			str_append_printf (¶ms, " %s", v->vector[i + k]);  		}  		irc_send (s, "%s%s", modes.str, params.str); @@ -6295,7 +6276,31 @@ handle_command_channel_mode (struct app_context *ctx, char *arguments,  		str_free (&modes);  		str_free (¶ms);  	} -	str_vector_free (&v); +} + +static bool +handle_command_channel_mode (struct app_context *ctx, char *arguments, +	const char *command_name, bool adding, char mode_char) +{ +	if (!server_command_check (ctx, command_name, true)) +		return true; + +	struct server *s = ctx->current_buffer->server; +	char *channel_name = try_get_channel (ctx, &arguments); +	if (!channel_name) +		buffer_send_error (ctx, ctx->current_buffer, +			"%s: %s", "Can't set mode", +			"no channel name given and this buffer is not a channel"); +	else if (*arguments) +	{ +		struct str_vector v; +		str_vector_init (&v); +		split_str_ignore_empty (arguments, ' ', &v); +		mass_channel_mode (s, channel_name, adding, mode_char, &v); +		str_vector_free (&v); +	} +	else +		return false;  	return true;  } @@ -6421,6 +6426,22 @@ handle_command_kickban (struct app_context *ctx, char *arguments)  	return true;  } +static void +complete_user_masks (struct str_vector *v) +{ +	// XXX: this may be a bit too trivial; we could map also nicknames +	//   to information from WHO polling or userhost-in-names +	for (size_t i = 0; i < v->len; i++) +	{ +		char *target = v->vector[i]; +		if (strpbrk (target, "!@*?")) +			continue; + +		v->vector[i] = xstrdup_printf ("%s!*@*", target); +		free (target); +	} +} +  static bool  handle_command_ban (struct app_context *ctx, char *arguments)  { @@ -6434,7 +6455,40 @@ handle_command_ban (struct app_context *ctx, char *arguments)  			"%s: %s", "Can't ban",  			"no channel name given and this buffer is not a channel");  	else if (*arguments) -		irc_send (s, "MODE %s +b %s", channel_name, arguments); +	{ +		struct str_vector v; +		str_vector_init (&v); +		split_str_ignore_empty (arguments, ' ', &v); +		complete_user_masks (&v); +		mass_channel_mode (s, channel_name, true, 'b', &v); +		str_vector_free (&v); +	} +	else +		irc_send (s, "MODE %s +b", channel_name); +	return true; +} + +static bool +handle_command_unban (struct app_context *ctx, char *arguments) +{ +	if (!server_command_check (ctx, "unban", true)) +		return true; + +	struct server *s = ctx->current_buffer->server; +	char *channel_name = try_get_channel (ctx, &arguments); +	if (!channel_name) +		buffer_send_error (ctx, ctx->current_buffer, +			"%s: %s", "Can't unban", +			"no channel name given and this buffer is not a channel"); +	else if (*arguments) +	{ +		struct str_vector v; +		str_vector_init (&v); +		split_str_ignore_empty (arguments, ' ', &v); +		complete_user_masks (&v); +		mass_channel_mode (s, channel_name, false, 'b', &v); +		str_vector_free (&v); +	}  	else  		return false;  	return true; @@ -6735,8 +6789,11 @@ g_command_handlers[] =  	  "[<channel>] <user> [<reason>]",  	  handle_command_kickban },  	{ "ban",        "Ban user from channel", -	  "[<channel>] <mask>", +	  "[<channel>] [<mask>...]",  	  handle_command_ban }, +	{ "unban",      "Unban user from channel", +	  "[<channel>] <mask>...", +	  handle_command_unban },  	{ "invite",     "Invite user to channel",  	  "[<channel>] <user>",  	  handle_command_invite }, | 
