* 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.41 2002/01/27 17:15:49 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
+ * LINKS wieder korrekt.
+ *
+ * Revision 1.47 2002/01/28 13:05:48 alex
+ * - nach einem JOIN wird die Liste der Mitglieder an den Client geschickt.
+ * - MODE fuer Channels wird nun komplett ignoriert (keine Fehlermeldung mehr).
+ *
+ * Revision 1.46 2002/01/28 01:45:43 alex
+ * - SERVER-Meldungen an neue Server sind nun in der richtigen Reihenfolge.
+ *
+ * Revision 1.45 2002/01/28 01:18:14 alex
+ * - connectierenden Servern werden Channels nun mit NJOIN bekannt gemacht.
+ *
+ * Revision 1.44 2002/01/28 00:55:08 alex
+ * - ein neu connectierender Server wird nun korrekt im Netz bekannt gemacht.
+ *
+ * Revision 1.43 2002/01/27 21:56:39 alex
+ * - IRC_WriteStrServersPrefixID() und IRC_WriteStrClientPrefixID() wieder entfernt.
+ * - einige kleinere Fixes bezueglich Channels ...
+ *
+ * Revision 1.42 2002/01/27 18:28:01 alex
+ * - bei NICK wurde das falsche Prefix an andere Server weitergegeben.
+ *
* Revision 1.41 2002/01/27 17:15:49 alex
* - anderungen an den Funktions-Prototypen von IRC_WriteStrChannel() und
* IRC_WriteStrChannelPrefix(),
LOCAL VOID Kill_Nick( CHAR *Nick );
+LOCAL BOOLEAN Send_NAMES( CLIENT *Client, CHANNEL *Chan );
+
GLOBAL VOID IRC_Init( VOID )
{
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
- return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Client_Mask( Prefix ), buffer );
-} /* IRC_WriteStrClientPrefix */
-
-
-GLOBAL BOOLEAN IRC_WriteStrClientPrefixID( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... )
-{
- /* Text an Clients, lokal bzw. remote, senden. */
-
- CHAR buffer[1000];
- va_list ap;
-
- assert( Client != NULL );
- assert( Format != NULL );
- assert( Prefix != NULL );
-
- va_start( ap, Format );
- vsnprintf( buffer, 1000, Format, ap );
- va_end( ap );
-
return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Client_ID( Prefix ), buffer );
-} /* IRC_WriteStrClientPrefixID */
+} /* IRC_WriteStrClientPrefix */
GLOBAL BOOLEAN IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... )
cl2chan = Channel_FirstMember( Chan );
while( cl2chan )
{
- if( Remote ) c = Client_NextHop( Channel_GetClient( cl2chan ));
- else
+ c = Channel_GetClient( cl2chan );
+ if( ! Remote )
{
- c = Channel_GetClient( cl2chan );
if( Client_Conn( c ) <= NONE ) c = NULL;
+ else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
}
+ if( c ) c = Client_NextHop( c );
if( c && ( c != Client ))
{
} /* IRC_WriteStrServersPrefix */
-GLOBAL VOID IRC_WriteStrServersPrefixID( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... )
-{
- CHAR buffer[1000];
- CLIENT *c;
- va_list ap;
-
- assert( Format != NULL );
- assert( Prefix != NULL );
-
- va_start( ap, Format );
- vsnprintf( buffer, 1000, Format, ap );
- va_end( ap );
-
- c = Client_First( );
- while( c )
- {
- if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
- {
- /* Ziel-Server gefunden */
- IRC_WriteStrClientPrefixID( c, Prefix, buffer );
- }
- c = Client_Next( c );
- }
-} /* IRC_WriteStrServersPrefixID */
-
-
GLOBAL BOOLEAN IRC_PASS( CLIENT *Client, REQUEST *Req )
{
assert( Client != NULL );
{
CHAR str[LINE_LEN], *ptr;
BOOLEAN ok;
- CLIENT *c;
- INT i;
+ CLIENT *from, *c;
+ CHANNEL *chan;
+ CL2CHAN *cl2chan;
+ INT max_hops, i;
assert( Client != NULL );
assert( Req != NULL );
Client_SetType( Client, CLIENT_SERVER );
- /* Alle bisherigen Server dem neuen Server bekannt machen,
- * die bisherigen Server ueber den neuen informierenn */
+ /* maximalen Hop Count ermitteln */
+ max_hops = 0;
c = Client_First( );
while( c )
{
- if(( Client_Type( c ) == CLIENT_SERVER ) && ( c != Client ) && ( c != Client_ThisServer( )))
+ if( Client_Hops( c ) > max_hops ) max_hops = Client_Hops( c );
+ c = Client_Next( c );
+ }
+
+ /* Alle bisherigen Server dem neuen Server bekannt machen,
+ * die bisherigen Server ueber den neuen informierenn */
+ for( i = 0; i < ( max_hops + 1 ); i++ )
+ {
+ c = Client_First( );
+ while( c )
{
- if( Client_Conn( c ) > NONE )
+ if(( Client_Type( c ) == CLIENT_SERVER ) && ( c != Client ) && ( c != Client_ThisServer( )) && ( Client_Hops( c ) == i ))
{
- /* Dem gefundenen Server gleich den neuen
- * Server bekannt machen */
- if( ! IRC_WriteStrClient( c, "SERVER %s %d %d :%s", Client_ID( Client ), Client_Hops( Client ) + 1, Client_MyToken( Client ), Client_Info( Client ))) return DISCONNECTED;
+ if( Client_Conn( c ) > NONE )
+ {
+ /* Dem gefundenen Server gleich den neuen
+ * Server bekannt machen */
+ if( ! IRC_WriteStrClient( c, "SERVER %s %d %d :%s", Client_ID( Client ), Client_Hops( Client ) + 1, Client_MyToken( Client ), Client_Info( Client ))) return DISCONNECTED;
+ }
+
+ /* Den neuen Server ueber den alten informieren */
+ if( ! IRC_WriteStrClientPrefix( Client, Client_Hops( c ) == 1 ? Client_ThisServer( ) : Client_Introducer( c ), "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ))) return DISCONNECTED;
}
-
- /* Den neuen Server ueber den alten informieren */
- if( ! IRC_WriteStrClientPrefix( Client, Client_Introducer( c ), "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ))) return DISCONNECTED;
+ c = Client_Next( c );
}
- c = Client_Next( c );
}
/* alle User dem neuen Server bekannt machen */
}
c = Client_Next( c );
}
+
+ /* Channels dem neuen Server bekannt machen */
+ chan = Channel_First( );
+ while( chan )
+ {
+ sprintf( str, "NJOIN %s :", Channel_Name( chan ));
+
+ /* alle Member suchen */
+ cl2chan = Channel_FirstMember( chan );
+ while( cl2chan )
+ {
+ if( str[strlen( str ) - 1] != ':' ) strcat( str, "," );
+ strcat( str, Client_ID( Channel_GetClient( cl2chan )));
+
+ if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
+ {
+ /* Zeile senden */
+ if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
+ sprintf( str, "NJOIN %s :", Channel_Name( chan ));
+ }
+
+ cl2chan = Channel_NextMember( chan, cl2chan );
+ }
+
+ /* noch Daten da? */
+ if( str[strlen( str ) - 1] != ':')
+ {
+ /* Ja; Also senden ... */
+ if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
+ }
+
+ /* naechsten Channel suchen */
+ chan = Channel_Next( chan );
+ }
return CONNECTED;
}
ptr = strchr( Req->argv[3] + 2, '[' );
if( ! ptr ) ptr = Req->argv[3];
+ from = Client_GetFromID( Req->prefix );
+ if( ! from )
+ {
+ /* Hm, Server, der diesen einfuehrt, ist nicht bekannt!? */
+ Log( LOG_ALERT, "Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)", Req->prefix, Client_Conn( Client ));
+ Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", TRUE );
+ return DISCONNECTED;
+ }
+
/* Neue Client-Struktur anlegen */
- c = Client_NewRemoteServer( Client, Req->argv[0], atoi( Req->argv[1] ), atoi( Req->argv[2] ), ptr, TRUE );
+ c = Client_NewRemoteServer( Client, Req->argv[0], from, atoi( Req->argv[1] ), atoi( Req->argv[2] ), ptr, TRUE );
if( ! c )
{
/* Neue Client-Struktur konnte nicht angelegt werden */
}
/* Log-Meldung zusammenbauen und ausgeben */
- if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) sprintf( str, "connected to %s, ", Req->prefix );
+ if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) sprintf( str, "connected to %s, ", Client_ID( from ));
else strcpy( str, "" );
Log( LOG_NOTICE, "Server \"%s\" registered (via %s, %s%d hop%s).", Client_ID( c ), Client_ID( Client ), str, Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
-
+
+ /* Andere Server informieren */
+ IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
+
return CONNECTED;
}
else return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
{
/* Nick-Aenderung: allen mitteilen! */
Log( LOG_DEBUG, "User \"%s\" changed nick: \"%s\" -> \"%s\".", Client_Mask( target ), Client_ID( target ), Req->argv[0] );
- IRC_WriteStrServersPrefix( Client, Client, "NICK :%s", Req->argv[0] );
+ IRC_WriteStrServersPrefix( Client, target, "NICK :%s", Req->argv[0] );
}
/* Client-Nick registrieren */
GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req )
{
- CHAR x[2], new_modes[CLIENT_MODE_LEN], *ptr;
+ CHAR *mode_ptr, the_modes[CLIENT_MODE_LEN], x[2];
BOOLEAN set, ok;
- CLIENT *target;
+ 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? */
- if(( Req->argc > 2 ) || ( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
+ /* Keine Parameter? */
+ if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
- /* "Ziel-Client" suchen */
- target = Client_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] );
- /* Wer ist der Anfragende? */
+ /* Kein Ziel gefunden? */
+ if(( ! cl ) && ( ! chan )) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
+
+ /* 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 );
+
+ /* 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 );
+ 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 ));
}
- else
+ if( chan )
{
- /* 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 ));
}
+
return ok;
} /* IRC_MODE */
GLOBAL BOOLEAN IRC_WHOIS( CLIENT *Client, REQUEST *Req )
{
CLIENT *from, *target, *c;
- CHAR *ptr = NULL;
+ CHAR str[LINE_LEN + 1], *ptr = NULL;
+ CL2CHAN *cl2chan;
assert( Client != NULL );
assert( Req != NULL );
/* Server */
if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED;
+ /* Channels */
+ sprintf( str, RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c ));
+ cl2chan = Channel_FirstChannelOf( c );
+ while( cl2chan )
+ {
+ /* Channel-Name anhaengen */
+ if( str[strlen( str ) - 1] != ':' ) strcat( str, " " );
+ strcat( str, Channel_Name( Channel_GetChannel( cl2chan )));
+
+ if( strlen( str ) > ( LINE_LEN - CHANNEL_NAME_LEN - 4 ))
+ {
+ /* Zeile wird zu lang: senden! */
+ if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
+ sprintf( str, RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c ));
+ }
+
+ /* naechstes Mitglied suchen */
+ cl2chan = Channel_NextChannelOf( c, cl2chan );
+ }
+ if( str[strlen( str ) - 1] != ':')
+ {
+ /* Es sind noch Daten da, die gesendet werden muessen */
+ if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
+ }
+
/* IRC-Operator? */
if( Client_HasMode( c, 'o' ))
{
{
if( Client_Type( c ) == CLIENT_SERVER )
{
- if( ! IRC_WriteStrClient( target, RPL_LINKS_MSG, Client_ID( target ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
+ if( ! IRC_WriteStrClient( target, RPL_LINKS_MSG, Client_ID( target ), Client_ID( c ), Client_ID( Client_TopServer( c ) ? Client_TopServer( c ) : Client_ThisServer( )), Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
}
c = Client_Next( c );
}
continue;
}
- /* An andere Server weiterleiten, an Client bestaetigen */
- IRC_WriteStrServersPrefixID( Client, target, "JOIN :%s", chan );
- IRC_WriteStrClientPrefix( Client, target, "JOIN :%s", chan );
+ /* An andere Server weiterleiten */
+ IRC_WriteStrServersPrefix( Client, target, "JOIN :%s", chan );
IRC_WriteStrChannelPrefix( Client, Channel_Search( chan ), target, FALSE, "JOIN :%s", chan );
if( Client_Type( Client ) == CLIENT_USER )
{
+ /* an Client bestaetigen */
+ IRC_WriteStrClientPrefix( Client, target, "JOIN :%s", chan );
/* Topic an Client schicken */
IRC_WriteStrClient( Client, RPL_TOPIC_MSG, Client_ID( Client ), chan, "What a wonderful channel!" );
+ /* Mitglieder an Client Melden */
+ Send_NAMES( Client, Channel_Search( chan ));
}
/* naechsten Namen ermitteln */
} /* Kill_Nick */
+LOCAL BOOLEAN Send_NAMES( CLIENT *Client, CHANNEL *Chan )
+{
+ CHAR str[LINE_LEN + 1];
+ CL2CHAN *cl2chan;
+
+ assert( Client != NULL );
+ assert( Chan != NULL );
+
+ /* Alle Mitglieder suchen */
+ sprintf( str, RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan ));
+ cl2chan = Channel_FirstMember( Chan );
+ while( cl2chan )
+ {
+ /* Nick anhaengen */
+ if( str[strlen( str ) - 1] != ':' ) strcat( str, " " );
+ strcat( str, Client_ID( Channel_GetClient( cl2chan )));
+
+ if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
+ {
+ /* Zeile wird zu lang: senden! */
+ if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
+ sprintf( str, RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan ));
+ }
+
+ /* naechstes Mitglied suchen */
+ cl2chan = Channel_NextMember( Chan, cl2chan );
+ }
+ if( str[strlen( str ) - 1] != ':')
+ {
+ /* Es sind noch Daten da, die gesendet werden muessen */
+ if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
+ }
+
+ /* Ende anzeigen */
+ IRC_WriteStrClient( Client, RPL_ENDOFNAMES_MSG, Client_ID( Client ), Channel_Name( Chan ));
+
+ return CONNECTED;
+} /* Send_NAMES */
+
+
/* -eof- */