Channel_Mode cleanups

- better indentation
- move answering request into seperate function.
This commit is contained in:
Florian Westphal 2008-02-24 18:44:41 +00:00
parent 89ba1bdcba
commit e710e8ae37
1 changed files with 108 additions and 94 deletions

View File

@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-mode.c,v 1.51 2008/02/16 11:27:49 fw Exp $"; static char UNUSED id[] = "$Id: irc-mode.c,v 1.52 2008/02/24 18:44:41 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@ -242,123 +242,140 @@ client_exit:
} /* Client_Mode */ } /* Client_Mode */
static bool
Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
{
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], argadd[CLIENT_PASS_LEN];
const char *mode_ptr;
/* Member or not? -- That's the question! */
if (!Channel_IsMemberOf(Channel, Origin))
return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
Client_ID(Origin), Channel_Name(Channel), Channel_Modes(Channel));
/* The sender is a member: generate extended reply */
strlcpy(the_modes, Channel_Modes(Channel), sizeof(the_modes));
mode_ptr = the_modes;
the_args[0] = '\0';
while(*mode_ptr) {
switch(*mode_ptr) {
case 'l':
snprintf(argadd, sizeof(argadd), " %lu", Channel_MaxUsers(Channel));
strlcat(the_args, argadd, sizeof(the_args));
break;
case 'k':
strlcat(the_args, " ", sizeof(the_args));
strlcat(the_args, Channel_Key(Channel), sizeof(the_args));
break;
}
mode_ptr++;
}
if (the_args[0])
strlcat(the_modes, the_args, sizeof(the_modes));
return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
Client_ID(Origin), Channel_Name(Channel), the_modes);
}
static bool static bool
Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
{ {
/* Handle channel and channel-user modes */ /* Handle channel and channel-user modes */
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr; char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr;
bool ok, set, modeok = false, skiponce, use_servermode = false; bool ok, set, modeok = true, skiponce, use_servermode = false;
int mode_arg, arg_arg; int mode_arg, arg_arg;
CLIENT *client; CLIENT *client;
long l; long l;
size_t len; size_t len;
/* Mode request: let's answer it :-) */ /* Mode request: let's answer it :-) */
if( Req->argc == 1 ) if (Req->argc <= 1)
{ return Channel_Mode_Answer_Request(Origin, Channel);
/* Member or not? -- That's the question! */
if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), Channel_Modes( Channel ));
/* The sender is a member: generate extended reply */
strlcpy( the_modes, Channel_Modes( Channel ), sizeof( the_modes ));
mode_ptr = the_modes;
the_args[0] = '\0';
while( *mode_ptr )
{
switch( *mode_ptr )
{
case 'l':
snprintf( argadd, sizeof( argadd ), " %lu", Channel_MaxUsers( Channel ));
strlcat( the_args, argadd, sizeof( the_args ));
break;
case 'k':
strlcat( the_args, " ", sizeof( the_args ));
strlcat( the_args, Channel_Key( Channel ), sizeof( the_args ));
break;
}
mode_ptr++;
}
if( the_args[0] ) strlcat( the_modes, the_args, sizeof( the_modes ));
return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), the_modes );
}
/* Is the user allowed to change modes? */ /* Is the user allowed to change modes? */
if( Client_Type( Client ) == CLIENT_USER ) if (Client_Type(Client) == CLIENT_USER) {
{
/* Is the originating user on that channel? */ /* Is the originating user on that channel? */
if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Channel_Name( Channel )); if (!Channel_IsMemberOf(Channel, Origin))
return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
/* Is he channel operator? */ Client_ID(Origin), Channel_Name(Channel));
if( strchr( Channel_UserModes( Channel, Origin ), 'o' )) modeok = true; modeok = false;
else if( Conf_OperCanMode ) /* channel operator? */
{ if (strchr(Channel_UserModes(Channel, Origin), 'o'))
modeok = true;
else if(Conf_OperCanMode) {
/* IRC-Operators can use MODE as well */ /* IRC-Operators can use MODE as well */
if( Client_OperByMe( Origin )) { if (Client_OperByMe(Origin)) {
modeok = true; modeok = true;
if ( Conf_OperServerMode ) use_servermode = true; /* Change Origin to Server */ if (Conf_OperServerMode)
use_servermode = true; /* Change Origin to Server */
} }
} }
} }
else modeok = true;
mode_arg = 1; mode_arg = 1;
mode_ptr = Req->argv[mode_arg]; mode_ptr = Req->argv[mode_arg];
if( Req->argc > mode_arg + 1 ) arg_arg = mode_arg + 1; if (Req->argc > mode_arg + 1)
else arg_arg = -1; arg_arg = mode_arg + 1;
else
arg_arg = -1;
/* Initial state: set or unset modes? */ /* Initial state: set or unset modes? */
skiponce = false; skiponce = false;
if( *mode_ptr == '-' ) set = false; switch (*mode_ptr) {
else if( *mode_ptr == '+' ) set = true; case '-': set = false; break;
else set = skiponce = true; case '+': set = true; break;
default:
set = true;
skiponce = true;
}
/* Prepare reply string */ /* Prepare reply string */
if( set ) strcpy( the_modes, "+" ); strcpy(the_modes, set ? "+" : "-");
else strcpy( the_modes, "-" );
the_args[0] = '\0'; the_args[0] = '\0';
x[1] = '\0'; x[1] = '\0';
ok = CONNECTED; ok = CONNECTED;
while( mode_ptr ) while (mode_ptr) {
{ if (! skiponce)
if( ! skiponce ) mode_ptr++; mode_ptr++;
if( ! *mode_ptr ) if (!*mode_ptr) {
{
/* Try next argument if there's any */ /* Try next argument if there's any */
if( arg_arg > mode_arg ) mode_arg = arg_arg; if (arg_arg > mode_arg)
else mode_arg++; mode_arg = arg_arg;
if( mode_arg < Req->argc ) mode_ptr = Req->argv[mode_arg]; else
else break; mode_arg++;
if( Req->argc > mode_arg + 1 ) arg_arg = mode_arg + 1;
else arg_arg = -1; if (mode_arg >= Req->argc)
break;
mode_ptr = Req->argv[mode_arg];
if (Req->argc > mode_arg + 1)
arg_arg = mode_arg + 1;
else
arg_arg = -1;
} }
skiponce = false; skiponce = false;
switch( *mode_ptr ) switch (*mode_ptr) {
{ case '+':
case '+': case '-':
case '-': if (((*mode_ptr == '+') && !set) || ((*mode_ptr == '-') && set)) {
if((( *mode_ptr == '+' ) && ( ! set )) || (( *mode_ptr == '-' ) && ( set ))) /* Action modifier ("+"/"-") must be changed ... */
{ len = strlen( the_modes ) - 1;
/* Action modifier ("+"/"-") must be changed ... */ if ((the_modes[len] == '+') || (the_modes[len] == '-')) {
len = strlen( the_modes ) - 1; /* Adjust last action modifier in result */
if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = *mode_ptr;
{ } else {
/* Adjust last action modifier in result */ /* Append modifier character to result string */
the_modes[len] = *mode_ptr; x[0] = *mode_ptr;
} strlcat(the_modes, x, sizeof(the_modes));
else
{
/* Append modifier character to result string */
x[0] = *mode_ptr;
strlcat( the_modes, x, sizeof( the_modes ));
}
if( *mode_ptr == '+' ) set = true;
else set = false;
} }
continue; set = *mode_ptr == '+';
}
continue;
} }
/* Are there arguments left? */ /* Are there arguments left? */
@ -579,22 +596,19 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
chan_exit: chan_exit:
/* Are there changed modes? */ /* Are there changed modes? */
if( the_modes[1] ) if (the_modes[1]) {
{
/* Clean up mode string */ /* Clean up mode string */
len = strlen( the_modes ) - 1; len = strlen(the_modes) - 1;
if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = '\0'; if ((the_modes[len] == '+') || (the_modes[len] == '-'))
the_modes[len] = '\0';
if( Client_Type( Client ) == CLIENT_SERVER ) if (Client_Type(Client) == CLIENT_SERVER) {
{
/* Forward mode changes to channel users and other servers */ /* Forward mode changes to channel users and other servers */
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args ); IRC_WriteStrServersPrefix(Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args);
IRC_WriteStrChannelPrefix( Client, Channel, Origin, false, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args ); IRC_WriteStrChannelPrefix(Client, Channel, Origin, false, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args);
} } else {
else if (use_servermode)
{ Origin = Client_ThisServer();
if ( use_servermode ) Origin = Client_ThisServer();
/* Send reply to client and inform other servers and channel users */ /* Send reply to client and inform other servers and channel users */
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args ); ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args ); IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );