- {
- /* Falsche Anzahl Parameter? */
- if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- Client_SetUser( Client, Req->argv[0], FALSE );
- Client_SetInfo( Client, Req->argv[3] );
-
- Log( LOG_DEBUG, "Connection %d: got USER command ...", Client_Conn( Client ));
- if( Client_Type( Client ) == CLIENT_GOTNICK ) return Hello_User( Client );
- else Client_SetType( Client, CLIENT_GOTUSER );
- return CONNECTED;
- }
- else if( Client_Type( Client ) == CLIENT_USER || Client_Type( Client ) == CLIENT_SERVER || Client_Type( Client ) == CLIENT_SERVICE )
- {
- return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
- }
- else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-} /* IRC_USER */
-
-
-GLOBAL BOOLEAN IRC_QUIT( CLIENT *Client, REQUEST *Req )
-{
- CLIENT *target;
-
- assert( Client != NULL );
- assert( Req != NULL );
-
- if(( Client_Type( Client ) == CLIENT_USER ) || ( Client_Type( Client ) == CLIENT_SERVICE ))
- {
- /* User / Service */
-
- /* Falsche Anzahl Parameter? */
- if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- if( Req->argc == 0 ) Conn_Close( Client_Conn( Client ), "Got QUIT command.", NULL, TRUE );
- else Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argv[0], TRUE );
-
- return DISCONNECTED;
- }
- else if ( Client_Type( Client ) == CLIENT_SERVER )
- {
- /* Server */
-
- /* Falsche Anzahl Parameter? */
- if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- target = Client_Search( Req->prefix );
- if( ! target )
- {
- Log( LOG_ERR, "Got QUIT from %s for unknown client!?", Client_ID( Client ));
- return CONNECTED;
- }
-
- if( Req->argc == 0 ) Client_Destroy( target, "Got QUIT command.", NULL );
- else Client_Destroy( target, "Got QUIT command.", Req->argv[0] );
-
- return CONNECTED;
- }
- else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-} /* IRC_QUIT */
-
-
-GLOBAL BOOLEAN IRC_SQUIT( CLIENT *Client, REQUEST *Req )
-{
- CLIENT *target;
-
- assert( Client != NULL );
- assert( Req != NULL );
-
- /* SQUIT ist nur fuer Server erlaubt */
- if( Client_Type( Client ) != CLIENT_SERVER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-
- /* Falsche Anzahl Parameter? */
- if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- target = Client_GetFromID( Req->argv[0] );
- if( ! target )
- {
- Log( LOG_ERR, "Got SQUIT from %s for unknown server \%s\"!?", Client_ID( Client ), Req->argv[0] );
- return CONNECTED;
- }
-
- if( target == Client ) Log( LOG_DEBUG, "Got SQUIT from %s: %s", Client_ID( Client ), Req->argv[1] );
- else Log( LOG_DEBUG, "Got SQUIT from %s for %s: %s", Client_ID( Client ), Client_ID( target ), Req->argv[1] );
-
- /* SQUIT an alle Server weiterleiten */
- IRC_WriteStrServers( Client, "SQUIT %s :%s", Req->argv[0], Req->argv[1] );
-
- if( Client_Conn( target ) > NONE )
- {
- if( Req->argv[1][0] ) Conn_Close( Client_Conn( target ), "Got SQUIT command.", Req->argv[1], TRUE );
- else Conn_Close( Client_Conn( target ), "Got SQUIT command.", NULL, TRUE );
- return DISCONNECTED;
- }
- else
- {
- Client_Destroy( target, "Got SQUIT command.", Req->argv[1] );
- return CONNECTED;
- }
-} /* IRC_SQUIT */
-
-
-GLOBAL BOOLEAN IRC_PING( CLIENT *Client, REQUEST *Req )
-{
- assert( Client != NULL );
- assert( Req != NULL );
-
- 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 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client ));
- if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- Log( LOG_DEBUG, "Connection %d: got PING, sending PONG ...", Client_Conn( Client ));
- return IRC_WriteStrClient( Client, "PONG %s :%s", Client_ID( Client_ThisServer( )), Client_ID( Client ));
-} /* IRC_PING */
-
-
-GLOBAL BOOLEAN IRC_PONG( CLIENT *Client, REQUEST *Req )
-{
- assert( Client != NULL );
- assert( Req != NULL );
-
- 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 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client ));
- if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- /* Der Connection-Timestamp wurde schon beim Lesen aus dem Socket
- * aktualisiert, daher muss das hier nicht mehr gemacht werden. */
-
- Log( LOG_DEBUG, "Connection %d: received PONG.", Client_Conn( Client ));
- return CONNECTED;
-} /* IRC_PONG */
-
-
-GLOBAL BOOLEAN IRC_MOTD( CLIENT *Client, REQUEST *Req )
-{
- assert( Client != NULL );
- assert( Req != NULL );
-
- if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-
- /* Falsche Anzahl Parameter? */
- if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- return Show_MOTD( Client );
-} /* IRC_MOTD */
-
-
-GLOBAL BOOLEAN IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
-{
- CLIENT *to, *from;
- CHANNEL *chan;
-
- assert( Client != NULL );
- assert( Req != NULL );
-
- 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 == 0 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
- if( Req->argc == 1 ) return IRC_WriteStrClient( Client, ERR_NOTEXTTOSEND_MSG, Client_ID( Client ));
- if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- 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 );
-
- to = Client_Search( Req->argv[0] );
- if( to )
- {
- /* Okay, Ziel ist ein User */
- if( Client_Conn( from ) > NONE ) Conn_UpdateIdle( Client_Conn( from ));
- return IRC_WriteStrClientPrefix( to, from, "PRIVMSG %s :%s", Client_ID( to ), Req->argv[1] );
- }
-
- chan = Channel_Search( Req->argv[0] );
- if( chan )
- {
- /* Okay, Ziel ist ein Channel */
- if( Client_Conn( from ) > NONE ) Conn_UpdateIdle( Client_Conn( from ));
- return IRC_WriteStrChannelPrefix( Client, chan, from, TRUE, "PRIVMSG %s :%s", Req->argv[0], Req->argv[1] );
- }
-
- return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[0] );
-} /* IRC_PRIVMSG */
-
-
-GLOBAL BOOLEAN IRC_NOTICE( CLIENT *Client, REQUEST *Req )
-{
- CLIENT *to, *from;
-
- assert( Client != NULL );
- assert( Req != NULL );
-
- 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 ) return CONNECTED;
-
- 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 );
-
- to = Client_Search( Req->argv[0] );
- if( to )
- {
- /* Okay, Ziel ist ein User */
- return IRC_WriteStrClientPrefix( to, from, "NOTICE %s :%s", Client_ID( to ), Req->argv[1] );
- }
- else return CONNECTED;
-} /* IRC_NOTICE */
-
-
-GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req )
-{
- CHAR x[2], new_modes[CLIENT_MODE_LEN], *ptr;
- BOOLEAN set, ok;
- CLIENT *target;
-
- assert( Client != NULL );
- assert( Req != NULL );
-
- 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 );
-
- /* "Ziel-Client" suchen */
- target = Client_Search( Req->argv[0] );
-
- /* Wer ist der Anfragende? */
- 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] );
- }
-
- /* Werden die Modes erfragt? */
- if( Req->argc == 1 ) return IRC_WriteStrClient( Client, RPL_UMODEIS_MSG, Client_ID( Client ), Client_Modes( Client ));
-
- ptr = Req->argv[1];
-
- /* Sollen Modes gesetzt oder geloescht werden? */
- if( *ptr == '+' ) set = TRUE;
- else if( *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, "-" );
-
- ptr++;
- ok = TRUE;
- x[1] = '\0';
- while( *ptr )
- {
- x[0] = '\0';
- if( Client_Type( Client ) == CLIENT_SERVER )
- {
- x[0] = *ptr;
- ok = TRUE;
- }
- else
- {
- 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( 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';
- }
- }
- if( ! ok ) break;
-
- ptr++;
- if( ! x[0] ) continue;
-
- /* Okay, gueltigen Mode gefunden */
- if( set )
- {
- /* Mode setzen. Wenn der Client ihn noch nicht hatte: merken */
- if( Client_ModeAdd( target, x[0] )) strcat( new_modes, x );
- }
- else
- {
- /* Modes geloescht. Wenn der Client ihn hatte: merken */
- if( Client_ModeDel( target, x[0] )) strcat( new_modes, x );
- }
- }
-
- /* Geanderte Modes? */
- if( new_modes[1] )
- {
- if( Client_Type( Client ) == CLIENT_SERVER )
- {
- /* 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 ));
- }
- return ok;
-} /* IRC_MODE */
-
-
-GLOBAL BOOLEAN IRC_OPER( CLIENT *Client, REQUEST *Req )
-{
- INT i;
-
- assert( Client != NULL );
- assert( Req != NULL );
-
- if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-
- /* Falsche Anzahl Parameter? */
- if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- /* Operator suchen */
- for( i = 0; i < Conf_Oper_Count; i++)
- {
- if( Conf_Oper[i].name[0] && Conf_Oper[i].pwd[0] && ( strcmp( Conf_Oper[i].name, Req->argv[0] ) == 0 )) break;
- }
- if( i >= Conf_Oper_Count )
- {
- Log( LOG_WARNING, "Got invalid OPER from \"%s\": Name \"%s\" not configured!", Client_Mask( Client ), Req->argv[0] );
- return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
- }
-
- /* Stimmt das Passwort? */
- if( strcmp( Conf_Oper[i].pwd, Req->argv[1] ) != 0 )
- {
- Log( LOG_WARNING, "Got invalid OPER from \"%s\": Bad password for \"%s\"!", Client_Mask( Client ), Conf_Oper[i].name );
- return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
- }
-
- if( ! Client_HasMode( Client, 'o' ))
- {
- /* noch kein o-Mode gesetzt */
- Client_ModeAdd( Client, 'o' );
- if( ! IRC_WriteStrClient( Client, "MODE %s :+o", Client_ID( Client ))) return DISCONNECTED;
- IRC_WriteStrServersPrefix( NULL, Client, "MODE %s :+o", Client_ID( Client ));
- }
-
- if( ! Client_OperByMe( Client )) Log( LOG_NOTICE, "Got valid OPER from \"%s\", user is an IRC operator now.", Client_Mask( Client ));
-
- Client_SetOperByMe( Client, TRUE );
- return IRC_WriteStrClient( Client, RPL_YOUREOPER_MSG, Client_ID( Client ));
-} /* IRC_OPER */
-
-
-GLOBAL BOOLEAN IRC_DIE( CLIENT *Client, REQUEST *Req )
-{
- assert( Client != NULL );
- assert( Req != NULL );
-
- if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-
- /* Falsche Anzahl Parameter? */
- if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
-
- Log( LOG_NOTICE, "Got DIE command from \"%s\", going down!", Client_Mask( Client ));
- NGIRCd_Quit = TRUE;
- return CONNECTED;
-} /* IRC_DIE */
-
-
-GLOBAL BOOLEAN IRC_RESTART( CLIENT *Client, REQUEST *Req )
-{
- assert( Client != NULL );
- assert( Req != NULL );
-
- if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-
- /* Falsche Anzahl Parameter? */
- if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
-
- Log( LOG_NOTICE, "Got RESTART command from \"%s\", going down!", Client_Mask( Client ));
- NGIRCd_Restart = TRUE;
- return CONNECTED;
-} /* IRC_RESTART */
-
-
-GLOBAL BOOLEAN IRC_NAMES( CLIENT *Client, REQUEST *Req )
-{
- CHAR rpl[COMMAND_LEN];
- CLIENT *c;
-
- assert( Client != NULL );
- assert( Req != NULL );
-
- if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-
- /* Falsche Anzahl Parameter? */
- if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- /* Noch alle User ausgeben, die in keinem Channel sind */
- rpl[0] = '\0';
- c = Client_First( );
- while( c )
- {
- if( Client_Type( c ) == CLIENT_USER )
- {
- /* Okay, das ist ein User */
- strcat( rpl, Client_ID( c ));
- strcat( rpl, " " );
- }
-
- /* Antwort zu lang? Splitten. */
- if( strlen( rpl ) > 480 )
- {
- if( rpl[strlen( rpl ) - 1] == ' ' ) rpl[strlen( rpl ) - 1] = '\0';
- if( ! IRC_WriteStrClient( Client, RPL_NAMREPLY_MSG, Client_ID( Client ), "*", "*", rpl )) return DISCONNECTED;
- rpl[0] = '\0';
- }
-
- c = Client_Next( c );
- }
- if( rpl[0] )
- {
- /* es wurden User gefunden */
- if( rpl[strlen( rpl ) - 1] == ' ' ) rpl[strlen( rpl ) - 1] = '\0';
- if( ! IRC_WriteStrClient( Client, RPL_NAMREPLY_MSG, Client_ID( Client ), "*", "*", rpl )) return DISCONNECTED;
- }
- return IRC_WriteStrClient( Client, RPL_ENDOFNAMES_MSG, Client_ID( Client ), "*" );
-} /* IRC_NAMES */
-
-
-GLOBAL BOOLEAN IRC_ISON( CLIENT *Client, REQUEST *Req )
-{
- CHAR rpl[COMMAND_LEN];
- CLIENT *c;
- CHAR *ptr;
- INT i;
-
- assert( Client != NULL );
- assert( Req != NULL );
-
- if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
-
- /* Falsche Anzahl Parameter? */
- if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
- strcpy( rpl, RPL_ISON_MSG );
- for( i = 0; i < Req->argc; i++ )
- {
- ptr = strtok( Req->argv[i], " " );
- while( ptr )
- {
- ngt_TrimStr( ptr );
- c = Client_GetFromID( ptr );
- if( c && ( Client_Type( c ) == CLIENT_USER ))
- {
- /* Dieser Nick ist "online" */
- strcat( rpl, ptr );
- strcat( rpl, " " );