X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc-login.c;h=cfdf9d010fe3f924c63f5ce969c2f17ff5bbe255;hb=4f759d811347a578624dde37462b9a056cca0720;hp=2fdc5d44d8c9996f6e377a920985766f5e1ca692;hpb=068d43352d98ca584af944c70a87134c28880c0e;p=ngircd-alex.git diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 2fdc5d44..cfdf9d01 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -40,6 +40,10 @@ static bool Hello_User PARAMS(( CLIENT *Client )); static void Kill_Nick PARAMS(( char *Nick, char *Reason )); +static void Introduce_Client PARAMS(( CLIENT *From, const char *Nick, + const int HopCount, const char *User, + const char *Host, const int Token, + const char *Mode, const char *Name )); /** @@ -168,6 +172,7 @@ GLOBAL bool IRC_NICK( CLIENT *Client, REQUEST *Req ) { CLIENT *intr_c, *target, *c; + CONN_ID conn; char *nick, *user, *hostname, *modes, *info; int token, hops; @@ -305,6 +310,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) Client_ID(Client), Req->command); if (Req->argc >= 7) { + /* RFC 2813 compatible syntax */ nick = Req->argv[0]; hops = atoi(Req->argv[1]); user = Req->argv[2]; @@ -313,6 +319,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) modes = Req->argv[5] + 1; info = Req->argv[6]; } else { + /* RFC 1459 compatible syntax */ nick = Req->argv[0]; hops = 1; user = Req->argv[0]; @@ -320,6 +327,15 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) token = atoi(Req->argv[1]); modes = ""; info = Req->argv[0]; + + conn = Client_Conn(Client); + if (conn != NONE && + !(Conn_Options(conn) & CONN_RFC1459)) { + Log(LOG_INFO, + "Switching connection %d (\"%s\") to RFC 1459 compatibility mode.", + conn, Client_ID(Client)); + Conn_SetOption(conn, CONN_RFC1459); + } } /* Nick ueberpruefen */ @@ -359,8 +375,11 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) if( *modes ) Log( LOG_DEBUG, "User \"%s\" (+%s) registered (via %s, on %s, %d hop%s).", Client_Mask( c ), modes, Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" ); else Log( LOG_DEBUG, "User \"%s\" registered (via %s, on %s, %d hop%s).", Client_Mask( c ), Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" ); - /* Andere Server, ausser dem Introducer, informieren */ - IRC_WriteStrServersPrefix( Client, Client, "NICK %s %d %s %s %d %s :%s", Req->argv[0], atoi( Req->argv[1] ) + 1, Req->argv[2], Req->argv[3], Client_MyToken( intr_c ), Req->argv[5], Req->argv[6] ); + /* Inform other servers about the new client */ + Introduce_Client(Client, Req->argv[0], atoi(Req->argv[1]) + 1, + Req->argv[2], Req->argv[3], + Client_MyToken(intr_c), Req->argv[5], + Req->argv[6]); return CONNECTED; } @@ -368,48 +387,88 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) } /* IRC_NICK */ +/** + * Handler for the IRC command "USER". + */ GLOBAL bool -IRC_USER( CLIENT *Client, REQUEST *Req ) +IRC_USER(CLIENT * Client, REQUEST * Req) { + CLIENT *c; #ifdef IDENTAUTH char *ptr; #endif - assert( Client != NULL ); - assert( Req != NULL ); + assert(Client != NULL); + assert(Req != NULL); + if (Client_Type(Client) == CLIENT_GOTNICK || #ifndef STRICT_RFC - if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_UNKNOWN ) -#else - if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS ) + Client_Type(Client) == CLIENT_UNKNOWN || #endif + Client_Type(Client) == CLIENT_GOTPASS) { - /* Wrong number of parameters? */ - if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + /* New connection */ + if (Req->argc != 4) + return IRC_WriteStrClient(Client, + ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), + Req->command); /* User name */ #ifdef IDENTAUTH - ptr = Client_User( Client ); - if( ! ptr || ! *ptr || *ptr == '~' ) Client_SetUser( Client, Req->argv[0], false ); + ptr = Client_User(Client); + if (!ptr || !*ptr || *ptr == '~') + Client_SetUser(Client, Req->argv[0], false); #else - Client_SetUser( Client, Req->argv[0], false ); + Client_SetUser(Client, Req->argv[0], false); #endif - /* "Real name" or user info text: Don't set it to the empty string, the original ircd - * can't deal with such "real names" (e. g. "USER user * * :") ... */ - if( *Req->argv[3] ) Client_SetInfo( Client, Req->argv[3] ); - else Client_SetInfo( Client, "-" ); + /* "Real name" or user info text: Don't set it to the empty + * string, the original ircd can't deal with such "real names" + * (e. g. "USER user * * :") ... */ + if (*Req->argv[3]) + Client_SetInfo(Client, Req->argv[3]); + else + Client_SetInfo(Client, "-"); - Log( LOG_DEBUG, "Connection %d: got valid USER command ...", Client_Conn( Client )); - if( Client_Type( Client ) == CLIENT_GOTNICK ) return Hello_User( Client ); - else Client_SetType( Client, CLIENT_GOTUSER ); + LogDebug("Connection %d: got valid 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_SERVER || + Client_Type(Client) == CLIENT_SERVICE) { + /* Server/service updating an user */ + if (Req->argc != 4) + return IRC_WriteStrClient(Client, + ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), + Req->command); + c = Client_Search(Req->prefix); + if (!c) + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), + Req->prefix); + + Client_SetUser(c, Req->argv[0], true); + Client_SetHostname(c, Req->argv[1]); + Client_SetInfo(c, Req->argv[3]); + + LogDebug("Connection %d: got valid USER command for \"%s\".", + Client_Conn(Client), Client_Mask(c)); + return CONNECTED; + } else if (Client_Type(Client) == CLIENT_USER) { + /* Already registered connection */ + return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG, + Client_ID(Client)); + } else { + /* Unexpected/invalid connection state? */ + return IRC_WriteStrClient(Client, ERR_NOTREGISTERED_MSG, + Client_ID(Client)); } - 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 */ @@ -616,6 +675,8 @@ IRC_PONG(CLIENT *Client, REQUEST *Req) static bool Hello_User(CLIENT * Client) { + char modes[CLIENT_MODE_LEN + 1] = "+"; + assert(Client != NULL); /* Check password ... */ @@ -632,10 +693,9 @@ Hello_User(CLIENT * Client) Client_Mask(Client), Client_Conn(Client)); /* Inform other servers */ - IRC_WriteStrServers(NULL, "NICK %s 1 %s %s 1 +%s :%s", - Client_ID(Client), Client_User(Client), - Client_Hostname(Client), Client_Modes(Client), - Client_Info(Client)); + strlcat(modes, Client_Modes(Client), sizeof(modes)); + Introduce_Client(NULL, Client_ID(Client), 1, Client_User(Client), + Client_Hostname(Client), 1, modes, Client_Info(Client)); if (!IRC_WriteStrClient (Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client))) @@ -691,4 +751,16 @@ Kill_Nick( char *Nick, char *Reason ) } /* Kill_Nick */ +static void +Introduce_Client(CLIENT *From, const char *Nick, const int HopCount, +const char *User, const char *Host, const int Token, const char *Mode, +const char *Name) +{ + IRC_WriteStrServersPrefix(From, + From != NULL ? From : Client_ThisServer(), + "NICK %s %d %s %s %d %s :%s", + Nick, HopCount, User, Host, Token, Mode, Name); +} /* Introduce_Client */ + + /* -eof- */