X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Fclient.c;h=72774ca9f4c749449d40a9344393aa3f6eef54b0;hp=73dcfcad107e3ab9be51daef2faf613a334a0151;hb=3b65f4e38d1ab019513f16b70581ae10574006e8;hpb=8e60fac73b791129b69d20c9e5b02ee1e89f6eaa diff --git a/src/ngircd/client.c b/src/ngircd/client.c index 73dcfcad..72774ca9 100644 --- a/src/ngircd/client.c +++ b/src/ngircd/client.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2013 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 @@ -87,7 +87,7 @@ Client_Init( void ) exit( 1 ); } - /* Client-Struktur dieses Servers */ + /* Client structure for this server */ This_Server->next = NULL; This_Server->type = CLIENT_SERVER; This_Server->conn_id = NONE; @@ -124,6 +124,10 @@ Client_Exit( void ) { cnt++; next = (CLIENT *)c->next; + if (c->account_name) + free(c->account_name); + if (c->cloaked) + free(c->cloaked); free( c ); c = next; } @@ -217,7 +221,7 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, if (Type == CLIENT_SERVER) Generate_MyToken(client); - if (strchr(client->modes, 'a')) + if (Client_HasMode(client, 'a')) strlcpy(client->away, DEFAULT_AWAY_MSG, sizeof(client->away)); client->next = (POINTER *)My_Clients; @@ -318,6 +322,10 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen } } + if (c->account_name) + free(c->account_name); + if (c->cloaked) + free(c->cloaked); free( c ); break; } @@ -452,6 +460,22 @@ Client_SetFlags( CLIENT *Client, const char *Flags ) } /* Client_SetFlags */ +GLOBAL void +Client_SetAccountName(CLIENT *Client, const char *AccountName) +{ + assert(Client != NULL); + + if (Client->account_name) + free(Client->account_name); + + if (*AccountName) + Client->account_name = strndup(AccountName, + CLIENT_NICK_LEN - 1); + else + Client->account_name = NULL; +} + + GLOBAL void Client_SetAway( CLIENT *Client, const char *Txt ) { @@ -513,7 +537,7 @@ GLOBAL bool Client_ModeAdd( CLIENT *Client, char Mode ) { /* Set Mode. - * If Client already alread had Mode, return false. + * If Client already had Mode, return false. * If the Mode was newly set, return true. */ @@ -522,7 +546,7 @@ Client_ModeAdd( CLIENT *Client, char Mode ) assert( Client != NULL ); x[0] = Mode; x[1] = '\0'; - if (!strchr( Client->modes, x[0])) { + if (!Client_HasMode(Client, x[0])) { strlcat( Client->modes, x, sizeof( Client->modes )); return true; } @@ -589,7 +613,7 @@ Client_Search( const char *Nick ) /** - * Serach first CLIENT structure matching a given mask of a server. + * Search first CLIENT structure matching a given mask of a server. * * The order of servers is arbitrary, but this function makes sure that the * local server is always returned if the mask matches it. @@ -744,8 +768,6 @@ Client_HostnameCloaked(CLIENT *Client) * Get (potentially cloaked) hostname of a client to display it to other users. * * If the client has not enabled cloaking, the real hostname is used. - * Please note that this function uses a global static buffer, so you can't - * nest invocations without overwriting earlier results! * * @param Client Pointer to client structure * @return Pointer to client hostname @@ -760,7 +782,7 @@ Client_HostnameDisplayed(CLIENT *Client) return Client_Hostname(Client); /* Use an already saved cloaked hostname, if there is one */ - if (Client->cloaked[0]) + if (Client->cloaked) return Client->cloaked; Client_UpdateCloakedHostname(Client, NULL, NULL); @@ -781,25 +803,32 @@ GLOBAL void Client_UpdateCloakedHostname(CLIENT *Client, CLIENT *Origin, const char *Hostname) { - static char Cloak_Buffer[CLIENT_HOST_LEN]; + char Cloak_Buffer[CLIENT_HOST_LEN]; assert(Client != NULL); if (!Origin) Origin = Client_ThisServer(); + if (!Client->cloaked) { + Client->cloaked = malloc(CLIENT_HOST_LEN); + if (!Client->cloaked) + return; + } + if (!Hostname) { /* Generate new cloaked hostname */ if (*Conf_CloakHostModeX) { - strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN); + strlcpy(Cloak_Buffer, Client->host, + sizeof(Cloak_Buffer)); strlcat(Cloak_Buffer, Conf_CloakHostSalt, - CLIENT_HOST_LEN); - snprintf(Client->cloaked, sizeof(Client->cloaked), + sizeof(Cloak_Buffer)); + snprintf(Client->cloaked, CLIENT_HOST_LEN, Conf_CloakHostModeX, Hash(Cloak_Buffer)); } else strlcpy(Client->cloaked, Client_ID(Client->introducer), - sizeof(Client->cloaked)); + CLIENT_HOST_LEN); } else - strlcpy(Client->cloaked, Hostname, sizeof(Client->cloaked)); + strlcpy(Client->cloaked, Hostname, CLIENT_HOST_LEN); LogDebug("Cloaked hostname of \"%s\" updated to \"%s\"", Client_ID(Client), Client->cloaked); @@ -950,6 +979,14 @@ Client_HasMode( CLIENT *Client, char Mode ) } /* Client_HasMode */ +GLOBAL bool +Client_HasFlag( CLIENT *Client, char Flag ) +{ + assert( Client != NULL ); + return strchr( Client->flags, Flag ) != NULL; +} /* Client_HasFlag */ + + GLOBAL char * Client_Away( CLIENT *Client ) { @@ -958,6 +995,14 @@ Client_Away( CLIENT *Client ) } /* Client_Away */ +GLOBAL char * +Client_AccountName(CLIENT *Client) +{ + assert(Client != NULL); + return Client->account_name; +} + + /** * Make sure that a given nickname is valid. * @@ -976,11 +1021,11 @@ Client_CheckNick(CLIENT *Client, char *Nick) if (!Client_IsValidNick(Nick)) { if (strlen(Nick ) >= Conf_MaxNickLength) - IRC_WriteStrClient(Client, ERR_NICKNAMETOOLONG_MSG, + IRC_WriteErrClient(Client, ERR_NICKNAMETOOLONG_MSG, Client_ID(Client), Nick, Conf_MaxNickLength - 1); else - IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG, + IRC_WriteErrClient(Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID(Client), Nick); return false; } @@ -989,7 +1034,7 @@ Client_CheckNick(CLIENT *Client, char *Nick) && Client_Type(Client) != CLIENT_SERVICE) { /* Make sure that this isn't a restricted/forbidden nickname */ if (Conf_NickIsBlocked(Nick)) { - IRC_WriteStrClient(Client, ERR_FORBIDDENNICKNAME_MSG, + IRC_WriteErrClient(Client, ERR_FORBIDDENNICKNAME_MSG, Client_ID(Client), Nick); return false; } @@ -997,7 +1042,7 @@ Client_CheckNick(CLIENT *Client, char *Nick) /* Nickname already registered? */ if (Client_Search(Nick)) { - IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG, + IRC_WriteErrClient(Client, ERR_NICKNAMEINUSE_MSG, Client_ID(Client), Nick); return false; } @@ -1018,7 +1063,8 @@ Client_CheckID( CLIENT *Client, char *ID ) /* ID too long? */ if (strlen(ID) > CLIENT_ID_LEN) { - IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID(Client), ID); + IRC_WriteErrClient(Client, ERR_ERRONEUSNICKNAME_MSG, + Client_ID(Client), ID); return false; } @@ -1116,7 +1162,8 @@ Client_OperCount( void ) c = My_Clients; while( c ) { - if( c && ( c->type == CLIENT_USER ) && ( strchr( c->modes, 'o' ))) cnt++; + if (c && c->type == CLIENT_USER && Client_HasMode(c, 'o' )) + cnt++; c = (CLIENT *)c->next; } return cnt; @@ -1326,8 +1373,6 @@ MyCount( CLIENT_TYPE Type ) static CLIENT * New_Client_Struct( void ) { - /* Neue CLIENT-Struktur pre-initialisieren */ - CLIENT *c; c = (CLIENT *)malloc( sizeof( CLIENT )); @@ -1362,7 +1407,7 @@ Generate_MyToken( CLIENT *Client ) { if( c->mytoken == token ) { - /* Das Token wurde bereits vergeben */ + /* The token is already in use */ token++; c = My_Clients; continue; @@ -1567,7 +1612,7 @@ Client_Announce(CLIENT * Client, CLIENT * Prefix, CLIENT * User) } else { /* RFC 2813 mode: one combined NICK or SERVICE command */ if (Client_Type(User) == CLIENT_SERVICE - && strchr(Client_Flags(Client), 'S')) { + && Client_HasFlag(Client, 'S')) { if (!IRC_WriteStrClientPrefix(Client, Prefix, "SERVICE %s %d * +%s %d :%s", Client_Mask(User), @@ -1586,7 +1631,7 @@ Client_Announce(CLIENT * Client, CLIENT * Prefix, CLIENT * User) } } - if (strchr(Client_Flags(Client), 'M')) { + if (Client_HasFlag(Client, 'M')) { /* Synchronize metadata */ if (Client_HostnameCloaked(User)) { if (!IRC_WriteStrClientPrefix(Client, Prefix, @@ -1596,11 +1641,19 @@ Client_Announce(CLIENT * Client, CLIENT * Prefix, CLIENT * User) return DISCONNECTED; } - if (Conn_GetFingerprint(Client_Conn(User))) { + if (Client_AccountName(User)) { + if (!IRC_WriteStrClientPrefix(Client, Prefix, + "METADATA %s accountname :%s", + Client_ID(User), + Client_AccountName(User))) + return DISCONNECTED; + } + + if (Conn_GetCertFp(Client_Conn(User))) { if (!IRC_WriteStrClientPrefix(Client, Prefix, "METADATA %s certfp :%s", Client_ID(User), - Conn_GetFingerprint(Client_Conn(User)))) + Conn_GetCertFp(Client_Conn(User)))) return DISCONNECTED; } }