commit - 175b20bbb558a3aa833ee5a37ab05913c5a9edc1
commit + f29ae5ae0e9be9b2c178e6cbe9b6a85c1e5bfe76
blob - 1c6e7b451e3bd690231d36366228ccbb117cc0e5
blob + ce06f069b72194b4dfad655f5634f1780634722b
--- src/ngircd/irc.c
+++ src/ngircd/irc.c
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
*
- * $Id: irc.c,v 1.48 2002/01/29 00:13:45 alex Exp $
+ * $Id: irc.c,v 1.49 2002/02/06 16:51:22 alex Exp $
*
* irc.c: IRC-Befehle
*
* $Log: irc.c,v $
+ * Revision 1.49 2002/02/06 16:51:22 alex
+ * - neue Funktion zur MODE-Behandlung, fuer Channel-Modes vorbereitet.
+ *
* Revision 1.48 2002/01/29 00:13:45 alex
* - WHOIS zeigt nun auch die Channels an, in denen der jeweilige User Mitglied ist.
* - zu jedem Server wird nun der "Top-Server" gespeichert, somit funktioniert
GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req )
{
- CHAR x[2], new_modes[CLIENT_MODE_LEN], *ptr;
- BOOLEAN set, ok;
- CLIENT *target;
+ CHAR *mode_ptr, the_modes[CLIENT_MODE_LEN], x[2];
+ BOOLEAN set, ok;
CHANNEL *chan;
+ CLIENT *cl;
assert( Client != NULL );
assert( Req != NULL );
+ cl = NULL;
+ chan = NULL;
+
+ /* Valider Client? */
if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
- /* Falsche Anzahl Parameter? */
+ /* Keine Parameter? */
if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
- /* "Ziel-Client" bzw. Channel suchen */
- chan = NULL;
- target = Client_Search( Req->argv[0] );
- if( ! target )
- {
- chan = Channel_Search( Req->argv[0] );
- }
+ /* Ziel suchen: Client bzw. Channel */
+ if( Client_IsValidNick( Req->argv[0] )) cl = Client_Search( Req->argv[0] );
+ if( Channel_IsValidName( Req->argv[0] )) chan = Channel_Search( Req->argv[0] );
- /* Falsche Anzahl Parameter? */
- if( target && ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
- if( chan && ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
+ /* Kein Ziel gefunden? */
+ if(( ! cl ) && ( ! chan )) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
- if( chan )
- {
- /* Channel Modes kennen wir noch nicht ... */
- Log( LOG_DEBUG, "MODE for channel \"%s\" ignored ...", Channel_Name( chan ));
- return CONNECTED;
- }
+ /* Falsche Anzahl Parameter? */
+ if(( cl ) && ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
+ if(( chan ) && ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
- /* Wer ist der Anfragende? */
+ /* Wenn Anfragender ein User ist: Zugriff erlaubt? */
if( Client_Type( Client ) == CLIENT_USER )
{
- /* User: MODE ist nur fuer sich selber zulaessig */
- if( target != Client ) return IRC_WriteStrClient( Client, ERR_USERSDONTMATCH_MSG, Client_ID( Client ));
- }
- else
- {
- /* Server: gibt es den Client ueberhaupt? */
- if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
+ if( cl )
+ {
+ /* MODE ist nur fuer sich selber zulaessig! */
+ if( cl != Client ) return IRC_WriteStrClient( Client, ERR_USERSDONTMATCH_MSG, Client_ID( Client ));
+ }
+ if( chan )
+ {
+ /* Darf der User die Channel-Modes ermitteln? */
+ }
}
- /* Werden die Modes erfragt? */
- if( Req->argc == 1 ) return IRC_WriteStrClient( Client, RPL_UMODEIS_MSG, Client_ID( Client ), Client_Modes( Client ));
+ /* Werden die Modes "nur" erfragt? */
+ if(( cl ) && ( Req->argc == 1 )) return IRC_WriteStrClient( Client, RPL_UMODEIS_MSG, Client_ID( Client ), Client_Modes( cl ));
+ if(( chan ) && ( Req->argc == 1 )) return IRC_WriteStrClient( Client, RPL_UMODEISCHAN_MSG, Client_ID( Client ), Channel_Name( chan ), Channel_Modes( chan ));
- ptr = Req->argv[1];
+ mode_ptr = Req->argv[1];
/* Sollen Modes gesetzt oder geloescht werden? */
- if( *ptr == '+' ) set = TRUE;
- else if( *ptr == '-' ) set = FALSE;
+ if( *mode_ptr == '+' ) set = TRUE;
+ else if( *mode_ptr == '-' ) set = FALSE;
else return IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Client ));
/* Reply-String mit Aenderungen vorbereiten */
- if( set ) strcpy( new_modes, "+" );
- else strcpy( new_modes, "-" );
+ if( set ) strcpy( the_modes, "+" );
+ else strcpy( the_modes, "-" );
- ptr++;
+ mode_ptr++;
ok = TRUE;
x[1] = '\0';
- while( *ptr )
+ while( *mode_ptr )
{
x[0] = '\0';
if( Client_Type( Client ) == CLIENT_SERVER )
{
- x[0] = *ptr;
- ok = TRUE;
+ /* Befehl kommt von einem Server, daher
+ * trauen wir ihm "unbesehen" ... */
+ x[0] = *mode_ptr;
}
else
{
- switch( *ptr )
+ /* Modes validieren */
+ if( cl )
{
- case 'i':
- /* invisible */
- x[0] = 'i';
- break;
- case 'r':
- /* restricted (kann nur gesetzt werden) */
- if( set ) x[0] = 'r';
- else ok = IRC_WriteStrClient( target, ERR_RESTRICTED_MSG, Client_ID( target ));
- break;
- case 'o':
- /* operator (kann nur geloescht werden) */
- if( ! set )
- {
- Client_SetOperByMe( target, FALSE );
- x[0] = 'o';
- }
- else ok = IRC_WriteStrClient( target, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( target ));
- break;
- default:
- ok = IRC_WriteStrClient( target, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( target ));
- x[0] = '\0';
+ /* User-Modes */
+ switch( *mode_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, ERR_RESTRICTED_MSG, Client_ID( Client ));
+ break;
+ case 'o':
+ /* operator (kann nur geloescht werden) */
+ if( ! set )
+ {
+ Client_SetOperByMe( Client, FALSE );
+ x[0] = 'o';
+ }
+ else ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Client ));
+ break;
+ default:
+ ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Client ));
+ x[0] = '\0';
+ }
}
+ if( chan )
+ {
+ /* Channel-Modes */
+ Log( LOG_DEBUG, "Channel-Mode '%c' not supported ...", *mode_ptr );
+ }
}
if( ! ok ) break;
-
- ptr++;
+
+ mode_ptr++;
if( ! x[0] ) continue;
/* Okay, gueltigen Mode gefunden */
- if( set )
+ if( cl )
{
- /* Mode setzen. Wenn der Client ihn noch nicht hatte: merken */
- if( Client_ModeAdd( target, x[0] )) strcat( new_modes, x );
+ /* Es geht um User-Modes */
+ if( set )
+ {
+ /* Mode setzen. Wenn der Client ihn noch nicht hatte: merken */
+ if( Client_ModeAdd( Client, x[0] )) strcat( the_modes, x );
+ }
+ else
+ {
+ /* Modes geloescht. Wenn der Client ihn hatte: merken */
+ if( Client_ModeDel( Client, x[0] )) strcat( the_modes, x );
+ }
}
- else
+ if( chan )
{
- /* Modes geloescht. Wenn der Client ihn hatte: merken */
- if( Client_ModeDel( target, x[0] )) strcat( new_modes, x );
+ /* Es geht um Channel-Modes */
}
}
-
- /* Geanderte Modes? */
- if( new_modes[1] )
+
+ /* Wurden Modes geaendert? */
+ if( the_modes[1] )
{
- if( Client_Type( Client ) == CLIENT_SERVER )
+ if( cl )
{
- /* Modes an andere Server forwarden */
- IRC_WriteStrServersPrefix( Client, Client, "MODE %s :%s", Client_ID( target ), new_modes );
- }
- else
- {
- /* Bestaetigung an Client schicken & andere Server informieren */
- ok = IRC_WriteStrClient( Client, "MODE %s :%s", Client_ID( target ), new_modes );
- IRC_WriteStrServers( Client, "MODE %s :%s", Client_ID( target ), new_modes );
- }
- Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( target ), Client_Modes( target ));
+ if( Client_Type( Client ) == CLIENT_SERVER )
+ {
+ /* Modes an andere Server forwarden */
+ IRC_WriteStrServersPrefix( Client, Client, "MODE %s :%s", Client_ID( cl ), the_modes );
+ }
+ else
+ {
+ /* Bestaetigung an Client schicken & andere Server informieren */
+ ok = IRC_WriteStrClient( Client, "MODE %s :%s", Client_ID( cl ), the_modes );
+ IRC_WriteStrServers( Client, "MODE %s :%s", Client_ID( cl ), the_modes );
+ }
+ Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( cl ), Client_Modes( cl ));
+ }
+ if( chan )
+ {
+ }
}
+
return ok;
} /* IRC_MODE */