+ 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 < 1 ) || ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
+
+ /* Client suchen */
+ c = Client_GetFromID( Req->argv[Req->argc - 1] );
+ if(( ! c ) || ( Client_Type( c ) != CLIENT_USER )) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[Req->argc - 1] );
+
+ /* Empfaenger des WHOIS suchen */
+ if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_GetFromID( Req->prefix );
+ else from = Client;
+ if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
+
+ /* Forwarden an anderen Server? */
+ if( Req->argc > 1 )
+ {
+ /* angegebenen Ziel-Server suchen */
+ target = Client_GetFromID( Req->argv[1] );
+ if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
+ ptr = Req->argv[1];
+ }
+ else target = Client_ThisServer( );
+
+ assert( target != NULL );
+
+ if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], ptr );
+
+ /* Nick, User und Name */
+ if( ! IRC_WriteStrClient( from, RPL_WHOISUSER_MSG, Client_ID( from ), Client_ID( c ), Client_User( c ), Client_Hostname( c ), Client_Info( c ))) return DISCONNECTED;
+
+ /* 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 )
+ {
+ chan = Channel_GetChannel( cl2chan );
+ assert( chan != NULL );
+
+ /* Channel-Name anhaengen */
+ if( str[strlen( str ) - 1] != ':' ) strcat( str, " " );
+ if( strchr( Channel_UserModes( chan, c ), 'v' )) strcat( str, "+" );
+ if( strchr( Channel_UserModes( chan, c ), 'o' )) strcat( str, "@" );
+ strcat( str, Channel_Name( chan ));
+
+ 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( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
+ }
+
+ /* Idle (nur lokale Clients) */
+ if( Client_Conn( c ) > NONE )
+ {
+ if( ! IRC_WriteStrClient( from, RPL_WHOISIDLE_MSG, Client_ID( from ), Client_ID( c ), Conn_GetIdle( Client_Conn ( c )))) return DISCONNECTED;
+ }
+
+ /* Away? */
+ if( Client_HasMode( c, 'a' ))
+ {
+ if( ! IRC_WriteStrClient( from, RPL_AWAY_MSG, Client_ID( from ), Client_ID( c ), Client_Away( c ))) return DISCONNECTED;
+ }
+
+ /* End of Whois */
+ return IRC_WriteStrClient( from, RPL_ENDOFWHOIS_MSG, Client_ID( from ), Client_ID( c ));
+} /* IRC_WHOIS */