/*
* ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2005 by Alexander Barton (alex@barton.de)
*
* 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
#include "portab.h"
-static char UNUSED id[] = "$Id: client.c,v 1.78 2005/03/19 18:43:48 fw Exp $";
+static char UNUSED id[] = "$Id: client.c,v 1.86 2006/03/10 20:25:29 fw Exp $";
#include "imp.h"
#include <assert.h>
#include <strings.h>
#include <netdb.h>
+#include "defines.h"
#include "conn.h"
#include "exp.h"
#define GETID_LEN (CLIENT_NICK_LEN-1) + 1 + (CLIENT_USER_LEN-1) + 1 + (CLIENT_HOST_LEN-1) + 1
-LOCAL CLIENT *This_Server, *My_Clients;
-LOCAL char GetID_Buffer[GETID_LEN];
+static CLIENT *This_Server, *My_Clients;
+static char GetID_Buffer[GETID_LEN];
+static WHOWAS My_Whowas[MAX_WHOWAS];
+static int Last_Whowas = -1;
-LOCAL long Count PARAMS(( CLIENT_TYPE Type ));
-LOCAL long MyCount PARAMS(( CLIENT_TYPE Type ));
-LOCAL CLIENT *New_Client_Struct PARAMS(( void ));
-LOCAL void Generate_MyToken PARAMS(( CLIENT *Client ));
-LOCAL void Adjust_Counters PARAMS(( CLIENT *Client ));
+static long Count PARAMS(( CLIENT_TYPE Type ));
+static long MyCount PARAMS(( CLIENT_TYPE Type ));
+
+static CLIENT *New_Client_Struct PARAMS(( void ));
+static void Generate_MyToken PARAMS(( CLIENT *Client ));
+static void Adjust_Counters PARAMS(( CLIENT *Client ));
#ifndef Client_DestroyNow
GLOBAL void Client_DestroyNow PARAMS((CLIENT *Client ));
Client_SetInfo( This_Server, Conf_ServerInfo );
My_Clients = This_Server;
+
+ memset( &My_Whowas, 0, sizeof( My_Whowas ));
} /* Client_Init */
} /* Client_NewRemoteUser */
-GLOBAL CLIENT *
+static CLIENT *
Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname, char *Info, int Hops, int Token, char *Modes, bool Idented )
{
CLIENT *client;
if( ! client ) return NULL;
/* Initialisieren */
+ client->starttime = time(NULL);
client->conn_id = Idx;
client->introducer = Introducer;
client->topserver = TopServer;
if( ! txt ) txt = "Reason unknown.";
/* Netz-Split-Nachricht vorbereiten (noch nicht optimal) */
- if( Client->type == CLIENT_SERVER ) snprintf( msg, sizeof( msg ), "%s: lost server %s", This_Server->id, Client->id );
+ if( Client->type == CLIENT_SERVER ) {
+ strlcpy(msg, This_Server->id, sizeof (msg));
+ strlcat(msg, " ", sizeof (msg));
+ strlcat(msg, Client->id, sizeof (msg));
+ }
last = NULL;
c = My_Clients;
else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :" );
}
}
+
+ /* Unregister client from channels */
Channel_Quit( c, FwdMsg ? FwdMsg : c->id );
+
+ /* Register client in My_Whowas structure */
+ Client_RegisterWhowas( c );
}
else if( c->type == CLIENT_SERVER )
{
} /* Client_IsValidNick */
-LOCAL long
+/**
+ * Return pointer to "My_Whowas" structure.
+ */
+GLOBAL WHOWAS *
+Client_GetWhowas( void )
+{
+ return My_Whowas;
+} /* Client_GetWhowas */
+
+/**
+ * Return the index of the last used WHOWAS entry.
+ */
+GLOBAL int
+Client_GetLastWhowasIndex( void )
+{
+ return Last_Whowas;
+} /* Client_GetLastWhowasIndex */
+
+
+/**
+ * Get the start time of this client.
+ * The result is the start time in seconds since 1970-01-01, as reported
+ * by the C function time(NULL).
+ */
+GLOBAL time_t
+Client_StartTime(CLIENT *Client)
+{
+ assert( Client != NULL );
+ return Client->starttime;
+} /* Client_Uptime */
+
+
+static long
Count( CLIENT_TYPE Type )
{
CLIENT *c;
} /* Count */
-LOCAL long
+static long
MyCount( CLIENT_TYPE Type )
{
CLIENT *c;
} /* MyCount */
-LOCAL CLIENT *
+static CLIENT *
New_Client_Struct( void )
{
/* Neue CLIENT-Struktur pre-initialisieren */
} /* New_Client */
-LOCAL void
+static void
Generate_MyToken( CLIENT *Client )
{
CLIENT *c;
} /* Generate_MyToken */
-LOCAL void
+static void
Adjust_Counters( CLIENT *Client )
{
long count;
} /* Adjust_Counters */
+/**
+ * Register client in My_Whowas structure for further recall by WHOWAS.
+ * Note: Only clients that have been connected at least 30 seconds will be
+ * registered to prevent automated IRC bots to "destroy" a nice server
+ * history database.
+ */
+GLOBAL void
+Client_RegisterWhowas( CLIENT *Client )
+{
+ int slot;
+
+ assert( Client != NULL );
+
+ /* Don't register clients that were connected less than 30 seconds. */
+ if( time(NULL) - Client->starttime < 30 )
+ return;
+
+ slot = Last_Whowas + 1;
+ if( slot >= MAX_WHOWAS || slot < 0 ) slot = 0;
+
+#ifdef DEBUG
+ Log( LOG_DEBUG, "Saving WHOWAS information to slot %d ...", slot );
+#endif
+
+ My_Whowas[slot].time = time( NULL );
+ strlcpy( My_Whowas[slot].id, Client_ID( Client ),
+ sizeof( My_Whowas[slot].id ));
+ strlcpy( My_Whowas[slot].user, Client_User( Client ),
+ sizeof( My_Whowas[slot].user ));
+ strlcpy( My_Whowas[slot].host, Client_Hostname( Client ),
+ sizeof( My_Whowas[slot].host ));
+ strlcpy( My_Whowas[slot].info, Client_Info( Client ),
+ sizeof( My_Whowas[slot].info ));
+ strlcpy( My_Whowas[slot].server, Client_ID( Client_Introducer( Client )),
+ sizeof( My_Whowas[slot].server ));
+
+ Last_Whowas = slot;
+} /* Client_RegisterWhowas */
+
+
/* -eof- */