+GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req )
+{
+ CHAR x[2], new_modes[CLIENT_MODE_LEN], *ptr, *p;
+ BOOLEAN set, ok;
+
+ assert( Client != NULL );
+ assert( Req != NULL );
+
+ if( ! Check_Valid_User( Client )) return CONNECTED;
+
+ /* Falsche Anzahl Parameter? */
+ if(( Req->argc > 2 ) || ( Req->argc < 1 )) return IRC_WriteStrClient( Client, This_Server, ERR_NEEDMOREPARAMS_MSG, Client_Name( Client ), Req->command );
+
+ /* MODE ist nur fuer sich selber zulaessig */
+ if( Client_Search( Req->argv[0] ) != Client ) return IRC_WriteStrClient( Client, This_Server, ERR_USERSDONTMATCH_MSG, Client_Name( Client ));
+
+ /* Werden die Modes erfragt? */
+ if( Req->argc == 1 ) return IRC_WriteStrClient( Client, This_Server, RPL_UMODEIS_MSG, Client_Name( Client ), Client->modes );
+
+ ptr = Req->argv[1];
+
+ /* Sollen Modes gesetzt oder geloescht werden? */
+ if( *ptr == '+' ) set = TRUE;
+ else if( *ptr == '-' ) set = FALSE;
+ else return IRC_WriteStrClient( Client, This_Server, ERR_UMODEUNKNOWNFLAG_MSG, Client_Name( Client ));
+
+ /* Reply-String mit Aenderungen vorbereiten */
+ if( set ) strcpy( new_modes, "+" );
+ else strcpy( new_modes, "-" );
+
+ ptr++;
+ ok = TRUE;
+ x[1] = '\0';
+ while( *ptr )
+ {
+ x[0] = '\0';
+ switch( *ptr )
+ {
+ case 'i':
+ /* invisible */
+ x[0] = 'i';
+ break;
+ case 'r':
+ /* restricted (kann nur gesetzt werden) */
+ if( set ) x[0] = 'r';
+ else ok = IRC_WriteStrClient( Client, This_Server, ERR_RESTRICTED_MSG, Client_Name( Client ));
+ break;
+ default:
+ ok = IRC_WriteStrClient( Client, This_Server, ERR_UMODEUNKNOWNFLAG_MSG, Client_Name( Client ));
+ x[0] = '\0';
+ }
+ if( ! ok ) break;
+
+ ptr++;
+ if( ! x[0] ) continue;
+
+ /* Okay, gueltigen Mode gefunden */
+ if( set )
+ {
+ /* Modes sollen gesetzt werden */
+ if( ! strchr( Client->modes, x[0] ))
+ {
+ /* Client hat den Mode noch nicht -> setzen */
+ strcat( Client->modes, x );
+ strcat( new_modes, x );
+ }
+ }
+ else
+ {
+ /* Modes sollen geloescht werden */
+ p = strchr( Client->modes, x[0] );
+ if( p )
+ {
+ /* Client hat den Mode -> loeschen */
+ while( *p )
+ {
+ *p = *(p + 1);
+ p++;
+ }
+ strcat( new_modes, x );
+ }
+ }
+ }
+
+ /* Geanderte Modes? */
+ if( new_modes[1] && ok )
+ {
+ ok = IRC_WriteStrRelated( Client, "MODE %s :%s", Client->nick, new_modes );
+ Log( LOG_DEBUG, "User \"%s!%s@%s\": Mode change, now \"%s\".", Client->nick, Client->user, Client->host, Client->modes );
+ }
+ return ok;
+} /* IRC_MODE */
+
+