This repository has been archived on 2025-02-12. You can view files and clone it, but cannot push or open issues or pull requests.
NeoStats/server.c

382 lines
7.4 KiB
C
Raw Permalink Normal View History

/* NeoStats - IRC Statistical Services
2004-01-14 11:36:37 +00:00
** Copyright (c) 1999-2004 Adam Rutter, Justin Hammond
** http://www.neostats.net/
**
** Portions Copyright (c) 2000-2001 ^Enigma^
**
** Portions Copyright (c) 1999 Johnathan George net@lite.net
**
** 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
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA
**
** NeoStats CVS Identification
** $Id$
2002-02-27 12:33:13 +00:00
*/
#include "stats.h"
#include "dl.h"
2002-02-27 12:33:13 +00:00
#include "hash.h"
2003-04-11 09:26:31 +00:00
#include "log.h"
2004-01-14 21:02:28 +00:00
#include "ircd.h"
2004-01-26 11:33:52 +00:00
#include "exclude.h"
#include "server.h"
2004-07-06 10:58:05 +00:00
#include "users.h"
#ifdef SQLSRV
#include "sqlsrv/rta.h"
#endif
2002-02-27 12:33:13 +00:00
hash_t *sh;
2003-10-14 15:29:41 +00:00
static Server *
2004-01-12 22:00:11 +00:00
new_server (const char *name)
2002-02-27 12:33:13 +00:00
{
Server *s;
hnode_t *sn;
2002-02-27 12:33:13 +00:00
SET_SEGV_LOCATION();
2003-07-30 13:58:22 +00:00
s = calloc (sizeof (Server), 1);
bzero(s, sizeof(Server));
2004-01-12 22:00:11 +00:00
strlcpy (s->name, name, MAXHOST);
2003-07-30 13:58:22 +00:00
sn = hnode_create (s);
2002-02-27 13:30:59 +00:00
if (!sn) {
2003-07-30 13:58:22 +00:00
nlog (LOG_WARNING, LOG_CORE, "Eeek, Hash is broken\n");
2002-02-27 13:30:59 +00:00
}
2003-07-30 13:58:22 +00:00
if (hash_isfull (sh)) {
nlog (LOG_WARNING, LOG_CORE, "Eeek, Server Hash is full!\n");
} else {
2003-07-30 13:58:22 +00:00
hash_insert (sh, sn, s->name);
}
2002-02-27 12:33:13 +00:00
return s;
}
Server *
AddServer (const char *name, const char *uplink, const char* hops, const char *numeric, const char *infoline)
2002-02-27 12:33:13 +00:00
{
Server *s;
char **av;
int ac = 0;
2002-02-27 12:33:13 +00:00
2004-07-21 14:02:29 +00:00
nlog (LOG_DEBUG1, LOG_CORE, "New Server: %s Uplink; %s", name, uplink);
2003-07-30 13:58:22 +00:00
s = new_server (name);
2004-01-19 20:44:46 +00:00
if(hops) {
s->hops = atoi (hops);
}
if (uplink) {
strlcpy (s->uplink, uplink, MAXHOST);
}
if(infoline) {
strlcpy (s->infoline, infoline, MAXINFO);
}
if(numeric) {
s->numeric = atoi(numeric);
}
s->connected_since = me.now;
if (!ircstrcasecmp(name, me.name)) {
s->flags |= NS_FLAGS_ME;
}
2004-01-26 11:33:52 +00:00
/* check exclusions */
ns_do_exclude_server(s);
/* run the module event for a new server. */
AddStringToList (&av, (char*)name, &ac);
2004-01-12 22:00:11 +00:00
AddStringToList (&av, (char*)uplink, &ac);
2004-01-26 11:33:52 +00:00
AddStringToList (&av, (char*)hops, &ac);
AddStringToList (&av, (char*)numeric, &ac);
AddStringToList (&av, (char*)infoline, &ac);
2004-01-12 22:00:11 +00:00
ModuleEvent (EVENT_SERVER, av, ac);
2003-07-30 13:58:22 +00:00
free (av);
return(s);
2002-02-27 12:33:13 +00:00
}
static void del_server_leaves(Server* hub)
{
Server *s;
hscan_t ss;
hnode_t *sn;
nlog (LOG_DEBUG1, LOG_CORE, "del_server_leaves: %s", hub->name);
hash_scan_begin (&ss, sh);
while ((sn = hash_scan_next (&ss)) != NULL) {
s = hnode_get (sn);
if(ircstrcasecmp(hub->name, s->uplink) == 0) {
nlog (LOG_DEBUG1, LOG_CORE, "del_server_leaves: del child %s", s->name);
DelServer(s->name, hub->name);
}
}
}
2004-01-12 22:00:11 +00:00
void
DelServer (const char *name, const char* reason)
2002-02-27 12:33:13 +00:00
{
Server *s;
hnode_t *sn;
char **av;
int ac = 0;
2002-02-27 12:33:13 +00:00
if (!name) {
2002-02-27 12:33:13 +00:00
return;
}
2003-07-30 13:58:22 +00:00
sn = hash_lookup (sh, name);
if (!sn) {
nlog (LOG_WARNING, LOG_CORE, "DelServer: squit from unknown server %s", name);
return;
}
2003-07-30 13:58:22 +00:00
s = hnode_get (sn);
del_server_leaves(s);
if(ircd_srv.noquit) {
QuitServerUsers (s);
}
/* run the event for delete server */
2003-07-30 13:58:22 +00:00
AddStringToList (&av, s->name, &ac);
2004-01-12 22:00:11 +00:00
if(reason) {
AddStringToList (&av, (char*)reason, &ac);
}
ModuleEvent (EVENT_SQUIT, av, ac);
2003-07-30 13:58:22 +00:00
free (av);
2003-07-30 13:58:22 +00:00
hash_delete (sh, sn);
hnode_destroy (sn);
free (s);
2002-02-27 12:33:13 +00:00
}
#ifdef BASE64SERVERNAME
Server *
findserverbase64 (const char *num)
{
Server *s;
hscan_t ss;
hnode_t *sn;
hash_scan_begin (&ss, sh);
while ((sn = hash_scan_next (&ss)) != NULL) {
s = hnode_get (sn);
if(strncmp(s->name64, num, BASE64SERVERSIZE) == 0) {
nlog (LOG_DEBUG1, LOG_CORE, "findserverbase64: %s -> %s", num, s->name);
return s;
}
}
nlog (LOG_DEBUG3, LOG_CORE, "findserverbase64: %s not found!", num);
return NULL;
}
#endif
2003-07-30 13:58:22 +00:00
Server *
findserver (const char *name)
2002-02-27 12:33:13 +00:00
{
Server *s;
hnode_t *sn;
2002-02-27 12:33:13 +00:00
2003-07-30 13:58:22 +00:00
sn = hash_lookup (sh, name);
if (sn) {
2003-07-30 13:58:22 +00:00
s = hnode_get (sn);
2002-02-27 12:33:13 +00:00
return s;
}
nlog (LOG_DEBUG3, LOG_CORE, "findserver: %s not found!", name);
return NULL;
2002-02-27 12:33:13 +00:00
}
static void
dumpserver (Server *s)
{
#ifdef BASE64SERVERNAME
debugtochannel("Server: %s (%s)", s->name, s->name64);
#else
debugtochannel("Server: %s", s->name);
#endif
debugtochannel("Flags: %lx", s->flags);
debugtochannel("Uplink: %s", s->uplink);
debugtochannel("========================================");
}
2003-07-30 13:58:22 +00:00
void
ServerDump (const char *name)
2002-02-27 12:33:13 +00:00
{
Server *s;
hscan_t ss;
hnode_t *sn;
2002-02-27 12:33:13 +00:00
debugtochannel("================SERVDUMP================");
if (!name) {
hash_scan_begin (&ss, sh);
while ((sn = hash_scan_next (&ss)) != NULL) {
s = hnode_get (sn);
dumpserver (s);
}
} else {
s = findserver (name);
if (s) {
dumpserver (s);
} else {
debugtochannel("ServerDump: can't find server %s", name);
}
2002-02-27 12:33:13 +00:00
}
}
#ifdef SQLSRV
COLDEF neo_serverscols[] = {
{
"servers",
"name",
RTA_STR,
MAXHOST,
offsetof(struct Server, name),
RTA_READONLY,
NULL,
NULL,
"The name of the server linked to the IRC network"
},
{
"servers",
"hops",
RTA_INT,
sizeof(int),
offsetof(struct Server, hops),
RTA_READONLY,
NULL,
NULL,
"The Number of hops away from the NeoStats Server"
},
{
"servers",
"connected",
RTA_INT,
sizeof(int),
offsetof(struct Server, connected_since),
RTA_READONLY,
NULL,
NULL,
"The time the server connected to the IRC network"
},
{
"servers",
"last_ping",
RTA_INT,
sizeof(int),
offsetof(struct Server, ping),
RTA_READONLY,
NULL,
NULL,
"The last ping time to this server from the NeoStats Server"
},
2003-12-28 14:37:50 +00:00
{
"servers",
"flags",
RTA_INT,
sizeof(int),
offsetof(struct Server, flags),
RTA_READONLY,
NULL,
NULL,
"Flags that specify special functions for this Server"
},
{
"servers",
"uplink",
RTA_STR,
MAXHOST,
offsetof(struct Server, uplink),
RTA_READONLY,
NULL,
NULL,
"The uplink Server this server is connected to. if it = self, means the NeoStats Server"
},
{
"servers",
"infoline",
RTA_STR,
MAXINFO,
offsetof(struct Server, infoline),
RTA_READONLY,
NULL,
NULL,
"The description of this server"
},
};
TBLDEF neo_servers = {
"servers",
NULL, /* for now */
sizeof(struct Server),
0,
TBL_HASH,
neo_serverscols,
sizeof(neo_serverscols) / sizeof(COLDEF),
"",
"The list of Servers connected to the IRC network"
};
#endif /* SQLSRV */
int
2004-01-12 22:00:11 +00:00
init_server_hash (void)
2002-02-27 12:33:13 +00:00
{
2003-07-30 13:58:22 +00:00
sh = hash_create (S_TABLE_SIZE, 0, 0);
2002-02-27 13:30:59 +00:00
if (!sh) {
2003-07-30 13:58:22 +00:00
nlog (LOG_CRITICAL, LOG_CORE, "Create Server Hash Failed\n");
return NS_FAILURE;
2002-02-27 13:30:59 +00:00
}
AddServer (me.name, NULL, 0, NULL, me.infoline);
#ifdef SQLSRV
/* add the server hash to the sql library */
neo_servers.address = sh;
rta_add_table(&neo_servers);
#endif
return NS_SUCCESS;
2002-02-27 12:33:13 +00:00
}
2004-01-31 06:26:56 +00:00
2003-07-30 13:58:22 +00:00
void
PingServers (void)
{
Server *s;
hscan_t ss;
hnode_t *sn;
if(!me.synced)
return;
nlog (LOG_DEBUG3, LOG_CORE, "Sending pings...");
ping.ulag = 0;
2003-07-30 13:58:22 +00:00
hash_scan_begin (&ss, sh);
while ((sn = hash_scan_next (&ss)) != NULL) {
s = hnode_get (sn);
if (!strcmp (me.name, s->name)) {
s->ping = 0;
continue;
}
2004-01-13 21:11:05 +00:00
send_ping (me.name, me.name, s->name);
}
}
2004-01-31 06:26:56 +00:00
void
FreeServers ()
{
Server *s;
hnode_t *sn;
hscan_t hs;
hash_scan_begin(&hs, sh);
while ((sn = hash_scan_next(&hs)) != NULL ) {
s = hnode_get (sn);
hash_delete (sh, sn);
hnode_destroy (sn);
free (s);
}
hash_destroy(sh);
}