init
This commit is contained in:
543
ircd/list.c
Normal file
543
ircd/list.c
Normal file
@@ -0,0 +1,543 @@
|
||||
/************************************************************************
|
||||
* IRC - Internet Relay Chat, ircd/list.c
|
||||
* Copyright (C) 1990 Jarkko Oikarinen and
|
||||
* University of Oulu, Finland
|
||||
*
|
||||
* 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* -- Jto -- 20 Jun 1990
|
||||
* extern void free() fixed as suggested by
|
||||
* gruner@informatik.tu-muenchen.de
|
||||
*/
|
||||
|
||||
/* -- Jto -- 03 Jun 1990
|
||||
* Added chname initialization...
|
||||
*/
|
||||
|
||||
/* -- Jto -- 24 May 1990
|
||||
* Moved is_full() to channel.c
|
||||
*/
|
||||
|
||||
/* -- Jto -- 10 May 1990
|
||||
* Added #include <sys.h>
|
||||
* Changed memset(xx,0,yy) into bzero(xx,yy)
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)list.c 2.24 4/20/94 (C) 1988 University of Oulu, \
|
||||
Computing Center and Jarkko Oikarinen";
|
||||
#endif
|
||||
|
||||
#include "struct.h"
|
||||
#include "common.h"
|
||||
#include "sys.h"
|
||||
#include "h.h"
|
||||
#include "numeric.h"
|
||||
#ifdef DBMALLOC
|
||||
#include "malloc.h"
|
||||
#endif
|
||||
void free_link PROTO((Link *));
|
||||
Link *make_link PROTO(());
|
||||
|
||||
#ifdef DEBUGMODE
|
||||
static struct liststats {
|
||||
int inuse;
|
||||
} cloc, crem, users, servs, links, classs, aconfs;
|
||||
|
||||
#endif
|
||||
|
||||
void outofmemory();
|
||||
|
||||
int numclients = 0;
|
||||
|
||||
void initlists()
|
||||
{
|
||||
#ifdef DEBUGMODE
|
||||
bzero((char *)&cloc, sizeof(cloc));
|
||||
bzero((char *)&crem, sizeof(crem));
|
||||
bzero((char *)&users, sizeof(users));
|
||||
bzero((char *)&servs, sizeof(servs));
|
||||
bzero((char *)&links, sizeof(links));
|
||||
bzero((char *)&classs, sizeof(classs));
|
||||
bzero((char *)&aconfs, sizeof(aconfs));
|
||||
#endif
|
||||
}
|
||||
|
||||
void outofmemory()
|
||||
{
|
||||
Debug((DEBUG_FATAL, "Out of memory: restarting server..."));
|
||||
restart("Out of Memory");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Create a new aClient structure and set it to initial state.
|
||||
**
|
||||
** from == NULL, create local client (a client connected
|
||||
** to a socket).
|
||||
**
|
||||
** from, create remote client (behind a socket
|
||||
** associated with the client defined by
|
||||
** 'from'). ('from' is a local client!!).
|
||||
*/
|
||||
aClient *make_client(from)
|
||||
aClient *from;
|
||||
{
|
||||
Reg1 aClient *cptr = NULL;
|
||||
Reg2 unsigned size = CLIENT_REMOTE_SIZE;
|
||||
|
||||
/*
|
||||
* Check freelists first to see if we can grab a client without
|
||||
* having to call malloc.
|
||||
*/
|
||||
if (!from)
|
||||
size = CLIENT_LOCAL_SIZE;
|
||||
|
||||
if (!(cptr = (aClient *)MyMalloc(size)))
|
||||
outofmemory();
|
||||
bzero((char *)cptr, (int)size);
|
||||
|
||||
#ifdef DEBUGMODE
|
||||
if (size == CLIENT_LOCAL_SIZE)
|
||||
cloc.inuse++;
|
||||
else
|
||||
crem.inuse++;
|
||||
#endif
|
||||
|
||||
/* Note: structure is zero (calloc) */
|
||||
cptr->from = from ? from : cptr; /* 'from' of local client is self! */
|
||||
cptr->next = NULL; /* For machines with NON-ZERO NULL pointers >;) */
|
||||
cptr->prev = NULL;
|
||||
cptr->hnext = NULL;
|
||||
cptr->user = NULL;
|
||||
cptr->serv = NULL;
|
||||
cptr->status = STAT_UNKNOWN;
|
||||
cptr->fd = -1;
|
||||
(void)strcpy(cptr->username, "unknown");
|
||||
if (size == CLIENT_LOCAL_SIZE)
|
||||
{
|
||||
cptr->since = cptr->lasttime = cptr->firsttime = now;
|
||||
cptr->lastnick = TStime();
|
||||
#ifdef NICK_DELAY
|
||||
cptr->nextnick = now - NICK_DELAY;
|
||||
#endif /* NICK_DELAY */
|
||||
cptr->cookie = 0;
|
||||
cptr->confs = NULL;
|
||||
cptr->sockhost[0] = '\0';
|
||||
cptr->buffer[0] = '\0';
|
||||
cptr->authfd = -1;
|
||||
cptr->listing = NULL;
|
||||
}
|
||||
return (cptr);
|
||||
}
|
||||
|
||||
void free_client(cptr)
|
||||
aClient *cptr;
|
||||
{
|
||||
MyFree((char *)cptr);
|
||||
}
|
||||
|
||||
/*
|
||||
** 'make_user' add's an User information block to a client
|
||||
** if it was not previously allocated.
|
||||
*/
|
||||
anUser *make_user(cptr)
|
||||
aClient *cptr;
|
||||
{
|
||||
Reg1 anUser *user;
|
||||
|
||||
user = cptr->user;
|
||||
if (!user)
|
||||
{
|
||||
user = (anUser *)MyMalloc(sizeof(anUser));
|
||||
#ifdef DEBUGMODE
|
||||
users.inuse++;
|
||||
#endif
|
||||
user->away = NULL;
|
||||
user->refcnt = 1;
|
||||
user->joined = 0;
|
||||
user->channel = NULL;
|
||||
user->invited = NULL;
|
||||
user->silence = NULL;
|
||||
cptr->user = user;
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
aServer *make_server(cptr)
|
||||
aClient *cptr;
|
||||
{
|
||||
Reg1 aServer *serv = cptr->serv;
|
||||
|
||||
if (!serv)
|
||||
{
|
||||
serv = (aServer *)MyMalloc(sizeof(aServer));
|
||||
#ifdef DEBUGMODE
|
||||
servs.inuse++;
|
||||
#endif
|
||||
serv->ghost = 0;
|
||||
cptr->serv = serv;
|
||||
serv->user = NULL;
|
||||
serv->nexts = NULL;
|
||||
*serv->by = '\0';
|
||||
serv->up = NULL;
|
||||
serv->down = NULL;
|
||||
serv->client = NULL;
|
||||
}
|
||||
return cptr->serv;
|
||||
}
|
||||
|
||||
/*
|
||||
** free_user
|
||||
** Decrease user reference count by one and realease block,
|
||||
** if count reaches 0
|
||||
*/
|
||||
void free_user(user, cptr)
|
||||
Reg1 anUser *user;
|
||||
aClient *cptr;
|
||||
{
|
||||
if (--user->refcnt <= 0)
|
||||
{
|
||||
if (user->away)
|
||||
MyFree((char *)user->away);
|
||||
/*
|
||||
* sanity check
|
||||
*/
|
||||
if (user->joined || user->refcnt < 0 ||
|
||||
user->invited || user->channel)
|
||||
#ifdef DEBUGMODE
|
||||
dumpcore("%#x user (%s!%s@%s) %#x %#x %#x %d %d",
|
||||
cptr, cptr ? cptr->name : "<noname>",
|
||||
user->username, user->host, user,
|
||||
user->invited, user->channel, user->joined,
|
||||
user->refcnt);
|
||||
#else
|
||||
sendto_ops("* %#x user (%s!%s@%s) %#x %#x %#x %d %d *",
|
||||
cptr, cptr ? cptr->name : "<noname>",
|
||||
user->username, user->host, user,
|
||||
user->invited, user->channel, user->joined,
|
||||
user->refcnt);
|
||||
#endif
|
||||
MyFree((char *)user);
|
||||
#ifdef DEBUGMODE
|
||||
users.inuse--;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* taken the code from ExitOneClient() for this and placed it here.
|
||||
* - avalon
|
||||
*/
|
||||
void remove_client_from_list(cptr)
|
||||
Reg1 aClient *cptr;
|
||||
{
|
||||
checklist();
|
||||
if (cptr->prev)
|
||||
cptr->prev->next = cptr->next;
|
||||
else
|
||||
{
|
||||
client = cptr->next;
|
||||
client->prev = NULL;
|
||||
}
|
||||
if (cptr->next)
|
||||
cptr->next->prev = cptr->prev;
|
||||
if (IsPerson(cptr) && cptr->user)
|
||||
{
|
||||
add_history(cptr);
|
||||
off_history(cptr);
|
||||
}
|
||||
if (cptr->user)
|
||||
{
|
||||
cptr->user->clink = NULL;
|
||||
(void)free_user(cptr->user, cptr);
|
||||
}
|
||||
if (cptr->serv)
|
||||
{
|
||||
if (cptr->serv->user)
|
||||
free_user(cptr->serv->user, cptr);
|
||||
MyFree((char *)cptr->serv);
|
||||
#ifdef DEBUGMODE
|
||||
servs.inuse--;
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUGMODE
|
||||
if (cptr->fd == -2)
|
||||
cloc.inuse--;
|
||||
else
|
||||
crem.inuse--;
|
||||
#endif
|
||||
(void)free_client(cptr);
|
||||
numclients--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* although only a small routine, it appears in a number of places
|
||||
* as a collection of a few lines...functions like this *should* be
|
||||
* in this file, shouldnt they ? after all, this is list.c, isnt it ?
|
||||
* -avalon
|
||||
*/
|
||||
void add_client_to_list(cptr)
|
||||
aClient *cptr;
|
||||
{
|
||||
/*
|
||||
* since we always insert new clients to the top of the list,
|
||||
* this should mean the "me" is the bottom most item in the list.
|
||||
*/
|
||||
cptr->next = client;
|
||||
client = cptr;
|
||||
if (cptr->next)
|
||||
cptr->next->prev = cptr;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for ptr in the linked listed pointed to by link.
|
||||
*/
|
||||
Link *find_user_link(lp, ptr)
|
||||
Reg1 Link *lp;
|
||||
Reg2 aClient *ptr;
|
||||
{
|
||||
if (ptr)
|
||||
while (lp)
|
||||
{
|
||||
if (lp->value.cptr == ptr)
|
||||
return (lp);
|
||||
lp = lp->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Link *make_link()
|
||||
{
|
||||
Reg1 Link *lp;
|
||||
|
||||
lp = (Link *)MyMalloc(sizeof(Link));
|
||||
#ifdef DEBUGMODE
|
||||
links.inuse++;
|
||||
#endif
|
||||
return lp;
|
||||
}
|
||||
|
||||
void free_link(lp)
|
||||
Reg1 Link *lp;
|
||||
{
|
||||
MyFree((char *)lp);
|
||||
#ifdef DEBUGMODE
|
||||
links.inuse--;
|
||||
#endif
|
||||
}
|
||||
|
||||
Dlink *add_dlink(lpp, cp)
|
||||
Dlink **lpp;
|
||||
aClient *cp;
|
||||
{ register Dlink *lp;
|
||||
lp = (Dlink *)MyMalloc(sizeof(Dlink));
|
||||
lp->value.cptr = cp;
|
||||
lp->prev = NULL;
|
||||
if ((lp->next = *lpp))
|
||||
lp->next->prev = lp;
|
||||
*lpp = lp;
|
||||
return lp;
|
||||
}
|
||||
|
||||
void remove_dlink(lpp, lp)
|
||||
Dlink **lpp, *lp;
|
||||
{
|
||||
if (lp->prev)
|
||||
{ if ((lp->prev->next = lp->next))
|
||||
lp->next->prev = lp->prev; }
|
||||
else if ((*lpp = lp->next))
|
||||
lp->next->prev = NULL;
|
||||
MyFree(lp);
|
||||
}
|
||||
|
||||
aClass *make_class()
|
||||
{
|
||||
Reg1 aClass *tmp;
|
||||
|
||||
tmp = (aClass *)MyMalloc(sizeof(aClass));
|
||||
#ifdef DEBUGMODE
|
||||
classs.inuse++;
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void free_class(tmp)
|
||||
Reg1 aClass *tmp;
|
||||
{
|
||||
MyFree((char *)tmp);
|
||||
#ifdef DEBUGMODE
|
||||
classs.inuse--;
|
||||
#endif
|
||||
}
|
||||
|
||||
aConfItem *make_conf()
|
||||
{
|
||||
Reg1 aConfItem *aconf;
|
||||
|
||||
aconf = (struct ConfItem *)MyMalloc(sizeof(aConfItem));
|
||||
#ifdef DEBUGMODE
|
||||
aconfs.inuse++;
|
||||
#endif
|
||||
bzero((char *)&aconf->ipnum, sizeof(struct in_addr));
|
||||
aconf->next = NULL;
|
||||
aconf->host = aconf->passwd = aconf->name = NULL;
|
||||
aconf->status = CONF_ILLEGAL;
|
||||
aconf->clients = 0;
|
||||
aconf->port = 0;
|
||||
aconf->hold = 0;
|
||||
Class(aconf) = 0;
|
||||
return (aconf);
|
||||
}
|
||||
|
||||
void delist_conf(aconf)
|
||||
aConfItem *aconf;
|
||||
{
|
||||
if (aconf == conf)
|
||||
conf = conf->next;
|
||||
else
|
||||
{
|
||||
aConfItem *bconf;
|
||||
|
||||
for (bconf = conf; aconf != bconf->next; bconf = bconf->next)
|
||||
;
|
||||
bconf->next = aconf->next;
|
||||
}
|
||||
aconf->next = NULL;
|
||||
}
|
||||
|
||||
void free_conf(aconf)
|
||||
aConfItem *aconf;
|
||||
{
|
||||
aClient *cptr = &me;
|
||||
del_queries((char *)aconf);
|
||||
MyFree(aconf->host);
|
||||
if (aconf->passwd)
|
||||
bzero(aconf->passwd, strlen(aconf->passwd));
|
||||
MyFree(aconf->passwd);
|
||||
MyFree(aconf->name);
|
||||
MyFree((char *)aconf);
|
||||
#ifdef DEBUGMODE
|
||||
aconfs.inuse--;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
aGline *make_gline(host, reason, name, expire)
|
||||
char *host, *reason, *name;
|
||||
time_t expire;
|
||||
{
|
||||
Reg4 aGline *agline;
|
||||
|
||||
agline = (struct Gline *)MyMalloc(sizeof(aGline)); /* alloc memory */
|
||||
DupString(agline->host, host); /* copy vital information */
|
||||
DupString(agline->reason, reason);
|
||||
DupString(agline->name, name);
|
||||
agline->expire = expire;
|
||||
agline->active = GLINE_ACTIVE; /* gline is active */
|
||||
agline->next = gline; /* link it into the list */
|
||||
return (gline = agline);
|
||||
}
|
||||
|
||||
aGline *find_gline(host, name, pgline)
|
||||
Reg1 char *host, *name;
|
||||
aGline **pgline;
|
||||
{
|
||||
Reg3 aGline *agline = gline, *a2gline = NULL;
|
||||
|
||||
while (agline) { /* look through all glines */
|
||||
|
||||
if (agline->expire <= TStime()) { /* handle expired glines */
|
||||
free_gline(agline, a2gline);
|
||||
agline = a2gline ? a2gline->next : gline;
|
||||
if (!agline) break; /* agline == NULL means gline == NULL */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* does gline match? */
|
||||
if (match(agline->host, host) == 0 && match(agline->name, name) == 0) {
|
||||
if (pgline) *pgline = a2gline; /* if they need it, give them the
|
||||
previous gline entry (probably
|
||||
for free_gline, below) */
|
||||
return agline;
|
||||
}
|
||||
|
||||
a2gline = agline;
|
||||
agline = agline->next;
|
||||
}
|
||||
|
||||
return NULL; /* found no glines */
|
||||
}
|
||||
|
||||
void free_gline(agline, pgline)
|
||||
aGline *agline, *pgline;
|
||||
{
|
||||
if (pgline) pgline->next = agline->next; /* squeeze agline out */
|
||||
else gline = agline->next;
|
||||
|
||||
MyFree(agline->host); /* and free up the memory */
|
||||
MyFree(agline->reason);
|
||||
MyFree(agline->name);
|
||||
MyFree((char *)agline);
|
||||
}
|
||||
|
||||
#ifdef DEBUGMODE
|
||||
void send_listinfo(cptr, name)
|
||||
aClient *cptr;
|
||||
char *name;
|
||||
{
|
||||
int inuse = 0, mem = 0, tmp = 0;
|
||||
|
||||
sendto_one(cptr, ":%s %d %s :Local: inuse: %d(%d)",
|
||||
me.name, RPL_STATSDEBUG, name, inuse += cloc.inuse,
|
||||
tmp = cloc.inuse * CLIENT_LOCAL_SIZE);
|
||||
mem += tmp;
|
||||
sendto_one(cptr, ":%s %d %s :Remote: inuse: %d(%d)",
|
||||
me.name, RPL_STATSDEBUG, name,
|
||||
crem.inuse, tmp = crem.inuse * CLIENT_REMOTE_SIZE);
|
||||
mem += tmp;
|
||||
inuse += crem.inuse;
|
||||
sendto_one(cptr, ":%s %d %s :Users: inuse: %d(%d)",
|
||||
me.name, RPL_STATSDEBUG, name, users.inuse,
|
||||
tmp = users.inuse * sizeof(anUser));
|
||||
mem += tmp;
|
||||
inuse += users.inuse,
|
||||
sendto_one(cptr, ":%s %d %s :Servs: inuse: %d(%d)",
|
||||
me.name, RPL_STATSDEBUG, name, servs.inuse,
|
||||
tmp = servs.inuse * sizeof(aServer));
|
||||
mem += tmp;
|
||||
inuse += servs.inuse,
|
||||
sendto_one(cptr, ":%s %d %s :Links: inuse: %d(%d)",
|
||||
me.name, RPL_STATSDEBUG, name, links.inuse,
|
||||
tmp = links.inuse * sizeof(Link));
|
||||
mem += tmp;
|
||||
inuse += links.inuse,
|
||||
sendto_one(cptr, ":%s %d %s :Classes: inuse: %d(%d)",
|
||||
me.name, RPL_STATSDEBUG, name, classs.inuse,
|
||||
tmp = classs.inuse * sizeof(aClass));
|
||||
mem += tmp;
|
||||
inuse += classs.inuse,
|
||||
sendto_one(cptr, ":%s %d %s :Confs: inuse: %d(%d)",
|
||||
me.name, RPL_STATSDEBUG, name, aconfs.inuse,
|
||||
tmp = aconfs.inuse * sizeof(aConfItem));
|
||||
mem += tmp;
|
||||
inuse += aconfs.inuse,
|
||||
sendto_one(cptr, ":%s %d %s :Totals: inuse %d %d",
|
||||
me.name, RPL_STATSDEBUG, name, inuse, mem);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user