X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc-mode.c;h=aac8769512ac87eaf252feecb305ea8303aedf44;hb=c9540015c88c280a19ebbd872e7dcba47d5707ae;hp=d633a426ad16f01b4160b3db2f85ff4d260b22f9;hpb=c0d74a3860dcdf58a341d37740d48d0bc2952493;p=ngircd-alex.git diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index d633a426..aac87695 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -14,10 +14,12 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-mode.c,v 1.21 2002/12/15 16:29:18 alex Exp $"; +static char UNUSED id[] = "$Id: irc-mode.c,v 1.28 2003/01/02 17:57:09 alex Exp $"; #include "imp.h" #include +#include +#include #include #include "conn.h" @@ -140,7 +142,8 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) else { /* Append modifier character to result string */ - x[0] = *mode_ptr; strcat( the_modes, x ); + x[0] = *mode_ptr; + strlcat( the_modes, x, sizeof( the_modes )); } if( *mode_ptr == '+' ) set = TRUE; else set = FALSE; @@ -148,45 +151,46 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) continue; } + /* Validate modes */ x[0] = '\0'; - if( Client_Type( Client ) == CLIENT_SERVER ) - { - /* MODE request was received from a server: - * therefore don't validate but trust it! */ - x[0] = *mode_ptr; - } - else + switch( *mode_ptr ) { - /* Validate modes */ - switch( *mode_ptr ) - { - case 'i': - /* Invisible */ - x[0] = 'i'; - break; - case 'o': - /* IRC operator (only unsetable!) */ - if( ! set ) - { - Client_SetOperByMe( Target, FALSE ); - x[0] = 'o'; - } - else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin )); - break; - case 'r': - /* Restricted (only setable) */ - if( set ) x[0] = 'r'; - else ok = IRC_WriteStrClient( Origin, ERR_RESTRICTED_MSG, Client_ID( Origin )); - break; - case 's': - /* Server messages */ - x[0] = 's'; - break; - default: - Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin )); - ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr ); - x[0] = '\0'; - } + case 'a': + /* Away */ + if( Client_Type( Client ) == CLIENT_SERVER ) + { + x[0] = 'a'; + Client_SetAway( Client, DEFAULT_AWAY_MSG ); + } + else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin )); + break; + case 'i': + /* Invisible */ + x[0] = 'i'; + break; + case 'o': + /* IRC operator (only unsetable!) */ + if(( ! set ) || ( Client_Type( Client ) == CLIENT_SERVER )) + { + Client_SetOperByMe( Target, FALSE ); + x[0] = 'o'; + } + else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin )); + break; + case 'r': + /* Restricted (only setable) */ + if(( set ) || ( Client_Type( Client ) == CLIENT_SERVER )) x[0] = 'r'; + else ok = IRC_WriteStrClient( Origin, ERR_RESTRICTED_MSG, Client_ID( Origin )); + break; + case 's': + /* Server messages */ + x[0] = 's'; + break; + default: + Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin )); + if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr ); + x[0] = '\0'; + goto client_exit; } if( ! ok ) break; @@ -196,16 +200,17 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) if( set ) { /* Set mode */ - if( Client_ModeAdd( Target, x[0] )) strcat( the_modes, x ); + if( Client_ModeAdd( Target, x[0] )) strlcat( the_modes, x, sizeof( the_modes )); } else { /* Unset mode */ - if( Client_ModeDel( Target, x[0] )) strcat( the_modes, x ); + if( Client_ModeDel( Target, x[0] )) strlcat( the_modes, x, sizeof( the_modes )); } } - +client_exit: + /* Are there changed modes? */ if( the_modes[1] ) { @@ -235,10 +240,11 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) { /* Handle channel and channel-user modes */ - CHAR the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], *mode_ptr; + CHAR the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr; BOOLEAN ok, set, modeok, skiponce; INT mode_arg, arg_arg; CLIENT *client; + LONG l; /* Mode request: let's answer it :-) */ if( Req->argc == 1 ) return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), Channel_Modes( Channel )); @@ -304,7 +310,8 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) else { /* Append modifier character to result string */ - x[0] = *mode_ptr; strcat( the_modes, x ); + x[0] = *mode_ptr; + strlcat( the_modes, x, sizeof( the_modes )); } if( *mode_ptr == '+' ) set = TRUE; else set = FALSE; @@ -315,113 +322,156 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) /* Are there arguments left? */ if( arg_arg >= Req->argc ) arg_arg = -1; + /* Validate modes */ x[0] = '\0'; + argadd[0] = '\0'; client = NULL; - if( Client_Type( Client ) == CLIENT_SERVER ) - { - /* MODE request was received from a server: - * therefore don't validate but trust it! */ - x[0] = *mode_ptr; - } - else + switch( *mode_ptr ) { - /* Validate modes */ - switch( *mode_ptr ) - { - /* Channel modes */ - case 'i': - /* Invite-Only */ - if( modeok ) x[0] = 'i'; - else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); - break; - case 'm': - /* Moderated */ - if( modeok ) x[0] = 'm'; - else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); - break; - case 'n': - /* kein Schreiben in den Channel von aussen */ - if( modeok ) x[0] = 'n'; + /* Channel modes */ + case 'i': + /* Invite-Only */ + if( modeok ) x[0] = 'i'; + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + break; + case 'm': + /* Moderated */ + if( modeok ) x[0] = 'm'; + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + break; + case 'n': + /* kein Schreiben in den Channel von aussen */ + if( modeok ) x[0] = 'n'; + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + break; + case 't': + /* Topic Lock */ + if( modeok ) x[0] = 't'; + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + break; + case 'P': + /* Persistent channel */ + if( modeok ) + { + if( set && ( ! Client_OperByMe( Client ))) + { + /* Only IRC operators are allowed to set P mode */ + ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin )); + } + else x[0] = 'P'; + } + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + break; + + /* Channel user modes */ + case 'o': + /* Channel operator */ + case 'v': + /* Voice */ + if( arg_arg > mode_arg ) + { + if( modeok ) + { + client = Client_Search( Req->argv[arg_arg] ); + if( client ) x[0] = *mode_ptr; + else ok = IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[arg_arg] ); + } else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); - break; - case 't': - /* Topic Lock */ - if( modeok ) x[0] = 't'; + Req->argv[arg_arg][0] = '\0'; + arg_arg++; + } + else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command ); + break; + case 'k': + /* Channel key */ + if( ! set ) + { + if( modeok ) x[0] = *mode_ptr; else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); break; - case 'P': - /* Persistent channel */ + } + if( arg_arg > mode_arg ) + { if( modeok ) { - if( set && ( ! Client_OperByMe( Client ))) - { - /* Only IRC operators are allowed to set P mode */ - ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin )); - } - else x[0] = 'P'; + Channel_ModeDel( Channel, 'k' ); + Channel_SetKey( Channel, Req->argv[arg_arg] ); + strlcpy( argadd, Channel_Key( Channel ), sizeof( argadd )); + x[0] = *mode_ptr; } else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + Req->argv[arg_arg][0] = '\0'; + arg_arg++; + } + else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command ); + break; + case 'l': + /* Member limit */ + if( ! set ) + { + if( modeok ) x[0] = *mode_ptr; + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); break; - - /* Channel user modes */ - case 'o': - /* Channel operator */ - case 'v': - /* Voice */ - if( arg_arg > mode_arg ) + } + if( arg_arg > mode_arg ) + { + if( modeok ) { - if( modeok ) + l = atol( Req->argv[arg_arg] ); + if( l > 0 && l < 0xFFFF ) { - client = Client_Search( Req->argv[arg_arg] ); - if( client ) x[0] = *mode_ptr; - else ok = IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[arg_arg] ); + Channel_ModeDel( Channel, 'l' ); + Channel_SetMaxUsers( Channel, l ); + snprintf( argadd, sizeof( argadd ), "%ld", l ); + x[0] = *mode_ptr; } - else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); - Req->argv[arg_arg][0] = '\0'; - arg_arg++; } - else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command ); - break; + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + Req->argv[arg_arg][0] = '\0'; + arg_arg++; + } + else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command ); + break; - /* Channel lists */ - case 'I': - /* Invite lists */ - if( arg_arg > mode_arg ) + /* Channel lists */ + case 'I': + /* Invite lists */ + if( arg_arg > mode_arg ) + { + /* modify list */ + if( modeok ) { - /* modify list */ - if( modeok ) - { - if( set ) Add_Invite( Origin, Client, Channel, Req->argv[arg_arg] ); - else Del_Invite( Origin, Client, Channel, Req->argv[arg_arg] ); - } - else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); - Req->argv[arg_arg][0] = '\0'; - arg_arg++; + if( set ) Add_Invite( Origin, Client, Channel, Req->argv[arg_arg] ); + else Del_Invite( Origin, Client, Channel, Req->argv[arg_arg] ); } - else Lists_ShowInvites( Origin, Channel ); - break; - case 'b': - /* Ban lists */ - if( arg_arg > mode_arg ) + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + Req->argv[arg_arg][0] = '\0'; + arg_arg++; + } + else Lists_ShowInvites( Origin, Channel ); + break; + case 'b': + /* Ban lists */ + if( arg_arg > mode_arg ) + { + /* modify list */ + if( modeok ) { - /* modify list */ - if( modeok ) - { - if( set ) Add_Ban( Origin, Client, Channel, Req->argv[arg_arg] ); - else Del_Ban( Origin, Client, Channel, Req->argv[arg_arg] ); - } - else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); - Req->argv[arg_arg][0] = '\0'; - arg_arg++; + if( set ) Add_Ban( Origin, Client, Channel, Req->argv[arg_arg] ); + else Del_Ban( Origin, Client, Channel, Req->argv[arg_arg] ); } - else Lists_ShowBans( Origin, Channel ); - break; - - default: - Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\" on %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ), Channel_Name( Channel )); - ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr ); - x[0] = '\0'; - } + else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel )); + Req->argv[arg_arg][0] = '\0'; + arg_arg++; + } + else Lists_ShowBans( Origin, Channel ); + break; + + default: + Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\" on %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ), Channel_Name( Channel )); + if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr ); + x[0] = '\0'; + goto chan_exit; } if( ! ok ) break; @@ -436,8 +486,9 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) /* Channel-User-Mode */ if( Channel_UserModeAdd( Channel, client, x[0] )) { - strcat( the_args, Client_ID( client )); - strcat( the_args, " " ); strcat( the_modes, x ); + strlcat( the_args, Client_ID( client ), sizeof( the_args )); + strlcat( the_args, " ", sizeof( the_args )); + strlcat( the_modes, x, sizeof( the_modes )); Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client )); } } @@ -446,7 +497,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) /* Channel-Mode */ if( Channel_ModeAdd( Channel, x[0] )) { - strcat( the_modes, x ); + strlcat( the_modes, x, sizeof( the_modes )); Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel )); } } @@ -459,8 +510,9 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) /* Channel-User-Mode */ if( Channel_UserModeDel( Channel, client, x[0] )) { - strcat( the_args, Client_ID( client )); - strcat( the_args, " " ); strcat( the_modes, x ); + strlcat( the_args, Client_ID( client ), sizeof( the_args )); + strlcat( the_args, " ", sizeof( the_args )); + strlcat( the_modes, x, sizeof( the_modes )); Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client )); } } @@ -469,12 +521,20 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) /* Channel-Mode */ if( Channel_ModeDel( Channel, x[0] )) { - strcat( the_modes, x ); + strlcat( the_modes, x, sizeof( the_modes )); Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel )); } } - } + } + + /* Are there additional arguments to add? */ + if( argadd[0] ) + { + if( the_args[strlen( the_args ) - 1] != ' ' ) strlcat( the_args, " ", sizeof( the_args )); + strlcat( the_args, argadd, sizeof( the_args )); + } } +chan_exit: /* Are there changed modes? */ if( the_modes[1] ) @@ -517,13 +577,14 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req ) { /* AWAY setzen */ Client_SetAway( Client, Req->argv[0] ); + Client_ModeAdd( Client, 'a' ); IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client )); return IRC_WriteStrClient( Client, RPL_NOWAWAY_MSG, Client_ID( Client )); } else { /* AWAY loeschen */ - Client_SetAway( Client, NULL ); + Client_ModeDel( Client, 'a' ); IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client )); return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client )); }