Commit Diff


commit - 175b20bbb558a3aa833ee5a37ab05913c5a9edc1
commit + f29ae5ae0e9be9b2c178e6cbe9b6a85c1e5bfe76
blob - 1c6e7b451e3bd690231d36366228ccbb117cc0e5
blob + ce06f069b72194b4dfad655f5634f1780634722b
--- src/ngircd/irc.c
+++ src/ngircd/irc.c
@@ -9,11 +9,14 @@
  * 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
@@ -1011,136 +1014,161 @@ GLOBAL BOOLEAN IRC_NOTICE( CLIENT *Client, REQUEST *Re
 
 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 */