X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Firc-login.c;h=6969fa338c22018643c5b08aa976bb0b2257fb7c;hp=c3f32b7e8b2516fe383b6482341817ce668269a6;hb=a14eb495b75c8c2a2a32ddb6eecf50dc174f811c;hpb=497edbaf3eb51e6c67975713ee5c52d2d1b48105 diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index c3f32b7e..6969fa33 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -39,8 +39,8 @@ #include "irc-login.h" static void Kill_Nick PARAMS((char *Nick, char *Reason)); -static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, - char *NewNick, bool RegisterWhowas)); +static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick, + bool InformClient)); /** @@ -146,7 +146,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) } else flags = ""; Log(LOG_INFO, - "Peer on conenction %d announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", + "Peer on connection %d announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", Client_Conn(Client), impl, serverver, protohigh, protolow, flags); } else { @@ -278,7 +278,8 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) Client_SetType( Client, CLIENT_GOTNICK ); } else { /* Nickname change */ - Change_Nick(Client, target, Req->argv[0], true); + Change_Nick(Client, target, Req->argv[0], + Client_Type(Client) == CLIENT_USER ? true : false); IRC_SetPenalty(target, 2); } @@ -359,6 +360,54 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) } /* IRC_NICK */ +/** + * Handler for the IRC "SVSNICK" command. + * + * @param Client The client from which this command has been received. + * @param Req Request structure with prefix and all parameters. + * @return CONNECTED or DISCONNECTED. + */ +GLOBAL bool +IRC_SVSNICK(CLIENT *Client, REQUEST *Req) +{ + CLIENT *from, *target; + + assert(Client != NULL); + assert(Req != NULL); + + if (Req->argc != 2) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + + /* Search the originator */ + from = Client_Search(Req->prefix); + if (!from) + from = Client; + + /* Search the target */ + target = Client_Search(Req->argv[0]); + if (!target || Client_Type(target) != CLIENT_USER) { + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), Req->argv[0]); + } + + if (Client_Conn(target) <= NONE) { + /* We have to forward the message to the server handling + * this user; this is required to make sure all servers + * in the network do follow the nick name change! */ + return IRC_WriteStrClientPrefix(Client_NextHop(target), from, + "SVSNICK %s %s", + Req->argv[0], Req->argv[1]); + } + + /* Make sure that the new nickname is valid */ + if (!Client_CheckNick(from, Req->argv[1])) + return CONNECTED; + + Change_Nick(from, target, Req->argv[1], true); + return CONNECTED; +} + /** * Handler for the IRC "USER" command. * @@ -394,8 +443,8 @@ IRC_USER(CLIENT * Client, REQUEST * Req) punctuation is allowed.*/ ptr = Req->argv[0]; while (*ptr) { - if (!isalnum(*ptr) && - *ptr != '+' && *ptr != '-' && + if (!isalnum((int)*ptr) && + *ptr != '+' && *ptr != '-' && *ptr != '@' && *ptr != '.' && *ptr != '_') { Conn_Close(Client_Conn(Client), NULL, "Invalid user name", true); @@ -404,6 +453,13 @@ IRC_USER(CLIENT * Client, REQUEST * Req) ptr++; } + /* Save the received username for authentication, and use + * it up to the first '@' as default user name (like ircd2.11, + * bahamut, ircd-seven, ...), prefixed with '~', if needed: */ + Client_SetOrigUser(Client, Req->argv[0]); + ptr = strchr(Req->argv[0], '@'); + if (ptr) + *ptr = '\0'; #ifdef IDENTAUTH ptr = Client_User(Client); if (!ptr || !*ptr || *ptr == '~') @@ -411,7 +467,6 @@ IRC_USER(CLIENT * Client, REQUEST * Req) #else Client_SetUser(Client, Req->argv[0], false); #endif - Client_SetOrigUser(Client, Req->argv[0]); /* "Real name" or user info text: Don't set it to the empty * string, the original ircd can't deal with such "real names" @@ -642,11 +697,11 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req ) } if (target != Client) { - Client_Destroy(target, "Got QUIT command.", + Client_Destroy(target, "Got QUIT command", Req->argc == 1 ? quitmsg : NULL, true); return CONNECTED; } else { - Conn_Close(Client_Conn(Client), "Got QUIT command.", + Conn_Close(Client_Conn(Client), "Got QUIT command", Req->argc == 1 ? quitmsg : NULL, true); return DISCONNECTED; } @@ -659,7 +714,7 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req ) } /* User, Service, or not yet registered */ - Conn_Close(Client_Conn(Client), "Got QUIT command.", + Conn_Close(Client_Conn(Client), "Got QUIT command", Req->argc == 1 ? quitmsg : NULL, true); return DISCONNECTED; @@ -858,8 +913,9 @@ IRC_PONG(CLIENT *Client, REQUEST *Req) if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) { Log(LOG_INFO, - "Synchronization with \"%s\" done (connection %d): %ld seconds [%ld users, %ld channels]", + "Synchronization with \"%s\" done (connection %d): %ld second%s [%ld users, %ld channels].", Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn), + time(NULL) - Conn_GetSignon(conn) == 1 ? "" : "s", Client_UserCount(), Channel_CountVisible(NULL)); Conn_UpdatePing(conn); } else @@ -889,7 +945,7 @@ Kill_Nick(char *Nick, char *Reason) r.argv[1] = Reason; r.argc = 2; - Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s", + Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s!", Nick, Reason); IRC_KILL(Client_ThisServer(), &r); @@ -904,7 +960,7 @@ Kill_Nick(char *Nick, char *Reason) * @param NewNick The new nickname. */ static void -Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool RegisterWhowas) +Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool InformClient) { if (Client_Conn(Target) > NONE) { /* Local client */ @@ -921,14 +977,15 @@ Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool RegisterWhowas) } /* Inform all servers and users (which have to know) of the new name */ - if (Client_Type(Origin) == CLIENT_USER) - IRC_WriteStrClientPrefix(Origin, Origin, "NICK :%s", NewNick); - IRC_WriteStrServersPrefix(Origin, Target, "NICK :%s", NewNick); + if (InformClient) { + IRC_WriteStrClientPrefix(Target, Target, "NICK :%s", NewNick); + IRC_WriteStrServersPrefix(NULL, Target, "NICK :%s", NewNick); + } else + IRC_WriteStrServersPrefix(Origin, Target, "NICK :%s", NewNick); IRC_WriteStrRelatedPrefix(Target, Target, false, "NICK :%s", NewNick); - /* Register old nickname for WHOWAS queries, if required */ - if (RegisterWhowas) - Client_RegisterWhowas(Target); + /* Register old nickname for WHOWAS queries */ + Client_RegisterWhowas(Target); /* Save new nickname */ Client_SetID(Target, NewNick);