* 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.
+ *
+ * $Id$
*/
+#include "list.h"
-#include "sys.h"
-#include "h.h"
-#include "struct.h"
-#include "numeric.h"
-#include "send.h"
-#include "s_conf.h"
#include "class.h"
-#include "match.h"
+#include "client.h"
#include "ircd.h"
-#include "s_serv.h"
-#include "support.h"
-#include "s_misc.h"
-#include "s_bsd.h"
-#include "whowas.h"
+#include "ircd_alloc.h"
+#include "ircd_string.h"
+#include "listener.h"
+#include "match.h"
+#include "numeric.h"
#include "res.h"
-#include "common.h"
-#include "list.h"
+#include "s_bsd.h"
+#include "s_conf.h"
+#include "s_debug.h"
+#include "s_misc.h"
#include "s_user.h"
-#include "opercmds.h"
+#include "send.h"
+#include "struct.h"
+#include "support.h"
+#include "whowas.h"
-RCSTAG_CC("$Id$");
+#include <assert.h>
+#include <stddef.h> /* offsetof */
+#include <unistd.h> /* close */
+#include <string.h>
#ifdef DEBUGMODE
static struct liststats {
int inuse;
-} cloc, crem, users, servs, links, classs, aconfs;
+} cloc, crem, users, servs, links, classs;
#endif
-void outofmemory();
-
-#ifdef DEBUGMODE
-void initlists(void)
+void init_list(void)
{
+#ifdef DEBUGMODE
memset(&cloc, 0, sizeof(cloc));
memset(&crem, 0, sizeof(crem));
memset(&users, 0, sizeof(users));
memset(&servs, 0, sizeof(servs));
memset(&links, 0, sizeof(links));
memset(&classs, 0, sizeof(classs));
- memset(&aconfs, 0, sizeof(aconfs));
-}
#endif
-
-void outofmemory(void)
-{
- Debug((DEBUG_FATAL, "Out of memory: restarting server..."));
- restart("Out of Memory");
}
/*
- * Create a new aClient structure and set it to initial state.
+ * Create a new struct Client structure and set it to initial state.
*
* from == NULL, create local client (a client connected to a socket).
*
* the client defined by 'from').
* ('from' is a local client!!).
*/
-aClient *make_client(aClient *from, int status)
+struct Client* make_client(struct Client *from, int status)
{
- Reg1 aClient *cptr = NULL;
- Reg2 size_t size = CLIENT_REMOTE_SIZE;
+ struct Client *cptr = NULL;
+ size_t size = CLIENT_REMOTE_SIZE;
/*
* Check freelists first to see if we can grab a client without
if (!from)
size = CLIENT_LOCAL_SIZE;
- if (!(cptr = (aClient *)RunMalloc(size)))
- outofmemory();
- memset(cptr, 0, size); /* All variables are 0 by default */
+ cptr = (struct Client*) MyMalloc(size);
+ assert(0 != cptr);
+ /*
+ * NOTE: Do not remove this, a lot of code depends on the entire
+ * structure being zeroed out
+ */
+ memset(cptr, 0, size); /* All variables are 0 by default */
-#ifdef DEBUGMODE
+#ifdef DEBUGMODE
if (size == CLIENT_LOCAL_SIZE)
cloc.inuse++;
else
#endif
/* Note: structure is zero (memset) */
- cptr->from = from ? from : cptr; /* 'from' of local client is self! */
- cptr->fd = -1;
+ cptr->from = from ? from : cptr; /* 'from' of local client is self! */
cptr->status = status;
+ cptr->hnext = cptr;
strcpy(cptr->username, "unknown");
- if (size == CLIENT_LOCAL_SIZE)
- {
- cptr->since = cptr->lasttime = cptr->firsttime = now;
+
+ if (CLIENT_LOCAL_SIZE == size) {
+ cptr->fd = -1;
+ cptr->local = 1;
+ cptr->since = cptr->lasttime = cptr->firsttime = CurrentTime;
cptr->lastnick = TStime();
- cptr->nextnick = now - NICK_DELAY;
- cptr->nexttarget = now - (TARGET_DELAY * (STARTTARGETS - 1));
- cptr->authfd = -1;
+ cptr->nextnick = CurrentTime - NICK_DELAY;
+ cptr->nexttarget = CurrentTime - (TARGET_DELAY * (STARTTARGETS - 1));
+ cptr->handler = UNREGISTERED_HANDLER;
}
- return (cptr);
-}
-
-void free_client(aClient *cptr)
-{
- RunFree(cptr);
+ return cptr;
}
-/*
- * 'make_user' add's an User information block to a client
- * if it was not previously allocated.
- */
-anUser *make_user(aClient *cptr)
+void free_client(struct Client *cptr)
{
- Reg1 anUser *user;
+ if (cptr && cptr->local) {
+ /*
+ * make sure we have cleaned up local resources
+ */
+ if (cptr->dns_reply)
+ --cptr->dns_reply->ref_count;
+ if (-1 < cptr->fd)
+ close(cptr->fd);
+ DBufClear(&cptr->sendQ);
+ DBufClear(&cptr->recvQ);
+ if (cptr->listener)
+ release_listener(cptr->listener);
+ }
+ /*
+ * forget to remove the client from the hash table?
+ */
+ assert(cptr->hnext == cptr);
- user = cptr->user;
- if (!user)
- {
- if (!(user = (anUser *)RunMalloc(sizeof(anUser))))
- outofmemory();
- memset(user, 0, sizeof(anUser)); /* All variables are 0 by default */
-#ifdef DEBUGMODE
- users.inuse++;
-#endif
- user->refcnt = 1;
- *user->host = 0;
- cptr->user = user;
- }
- return user;
+ MyFree(cptr);
}
-aServer *make_server(aClient *cptr)
+struct Server *make_server(struct Client *cptr)
{
- Reg1 aServer *serv = cptr->serv;
+ struct Server *serv = cptr->serv;
if (!serv)
{
- if (!(serv = (aServer *)RunMalloc(sizeof(aServer))))
- outofmemory();
- memset(serv, 0, sizeof(aServer)); /* All variables are 0 by default */
-#ifdef DEBUGMODE
+ serv = (struct Server*) MyMalloc(sizeof(struct Server));
+ assert(0 != serv);
+ memset(serv, 0, sizeof(struct Server)); /* All variables are 0 by default */
+#ifdef DEBUGMODE
servs.inuse++;
#endif
cptr->serv = serv;
*serv->by = '\0';
- DupString(serv->last_error_msg, "<>"); /* String must be non-empty */
+ DupString(serv->last_error_msg, "<>"); /* String must be non-empty */
}
return cptr->serv;
}
-/*
- * free_user
- *
- * Decrease user reference count by one and realease block, if count reaches 0.
- */
-void free_user(anUser *user, aClient *cptr)
-{
- if (--user->refcnt == 0)
- {
- if (user->away)
- RunFree(user->away);
- /*
- * sanity check
- */
- if (user->joined || user->invited || user->channel)
-#ifdef DEBUGMODE
- dumpcore("%p user (%s!%s@%s) %p %p %p %d %d",
- cptr, cptr ? cptr->name : "<noname>",
- user->username, user->host, user,
- user->invited, user->channel, user->joined, user->refcnt);
-#else
- sendto_ops("* %p user (%s!%s@%s) %p %p %p %d %d *",
- cptr, cptr ? cptr->name : "<noname>",
- user->username, user->host, user,
- user->invited, user->channel, user->joined, user->refcnt);
-#endif
- RunFree(user);
-#ifdef DEBUGMODE
- users.inuse--;
-#endif
- }
-}
-
/*
* Taken the code from ExitOneClient() for this and placed it here.
* - avalon
*/
-void remove_client_from_list(aClient *cptr)
+void remove_client_from_list(struct Client *cptr)
{
- checklist();
if (cptr->prev)
cptr->prev->next = cptr->next;
- else
- {
- client = cptr->next;
- client->prev = NULL;
+ else {
+ GlobalClientList = cptr->next;
+ GlobalClientList->prev = 0;
}
if (cptr->next)
cptr->next->prev = cptr->prev;
- if (IsUser(cptr) && cptr->user)
- {
+
+ cptr->next = cptr->prev = 0;
+
+ if (IsUser(cptr) && cptr->user) {
add_history(cptr, 0);
off_history(cptr);
}
- if (cptr->user)
- free_user(cptr->user, cptr);
- if (cptr->serv)
- {
- if (cptr->serv->user)
- free_user(cptr->serv->user, cptr);
+ if (cptr->user) {
+ free_user(cptr->user);
+ cptr->user = 0;
+ }
+
+ if (cptr->serv) {
+ if (cptr->serv->user) {
+ free_user(cptr->serv->user);
+ cptr->serv->user = 0;
+ }
if (cptr->serv->client_list)
- RunFree(cptr->serv->client_list);
- RunFree(cptr->serv->last_error_msg);
- RunFree(cptr->serv);
-#ifdef DEBUGMODE
- servs.inuse--;
+ MyFree(cptr->serv->client_list);
+ MyFree(cptr->serv->last_error_msg);
+ MyFree(cptr->serv);
+#ifdef DEBUGMODE
+ --servs.inuse;
#endif
}
-#ifdef DEBUGMODE
- if (cptr->fd == -2)
- cloc.inuse--;
+#ifdef DEBUGMODE
+ if (cptr->local)
+ --cloc.inuse;
else
- crem.inuse--;
+ --crem.inuse;
#endif
free_client(cptr);
- return;
}
/*
* in this file, shouldnt they ? after all, this is list.c, isn't it ?
* -avalon
*/
-void add_client_to_list(aClient *cptr)
+void add_client_to_list(struct Client *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.
+ * XXX - don't always count on the above, things change
*/
- cptr->next = client;
- client = cptr;
+ cptr->prev = 0;
+ cptr->next = GlobalClientList;
+ GlobalClientList = cptr;
if (cptr->next)
cptr->next->prev = cptr;
- return;
}
/*
* Look for ptr in the linked listed pointed to by link.
*/
-Link *find_user_link(Link *lp, aClient *ptr)
+struct SLink *find_user_link(struct SLink *lp, struct Client *ptr)
{
if (ptr)
while (lp)
{
if (lp->value.cptr == ptr)
- return (lp);
+ return (lp);
lp = lp->next;
}
return NULL;
}
-Link *make_link(void)
+struct SLink *make_link(void)
{
- Reg1 Link *lp;
+ struct SLink *lp;
- lp = (Link *)RunMalloc(sizeof(Link));
-#ifdef DEBUGMODE
+ lp = (struct SLink*) MyMalloc(sizeof(struct SLink));
+ assert(0 != lp);
+#ifdef DEBUGMODE
links.inuse++;
#endif
return lp;
}
-void free_link(Link *lp)
+void free_link(struct SLink *lp)
{
- RunFree(lp);
-#ifdef DEBUGMODE
+ MyFree(lp);
+#ifdef DEBUGMODE
links.inuse--;
#endif
}
-Dlink *add_dlink(Dlink **lpp, aClient *cp)
+struct DLink *add_dlink(struct DLink **lpp, struct Client *cp)
{
- register Dlink *lp;
- lp = (Dlink *)RunMalloc(sizeof(Dlink));
+ struct DLink* lp = (struct DLink*) MyMalloc(sizeof(struct DLink));
+ assert(0 != lp);
lp->value.cptr = cp;
- lp->prev = NULL;
+ lp->prev = 0;
if ((lp->next = *lpp))
lp->next->prev = lp;
*lpp = lp;
return lp;
}
-void remove_dlink(Dlink **lpp, Dlink *lp)
+void remove_dlink(struct DLink **lpp, struct DLink *lp)
{
- if (lp->prev)
- {
+ assert(0 != lpp);
+ assert(0 != lp);
+
+ if (lp->prev) {
if ((lp->prev->next = lp->next))
lp->next->prev = lp->prev;
}
else if ((*lpp = lp->next))
lp->next->prev = NULL;
- RunFree(lp);
+ MyFree(lp);
}
-aConfClass *make_class(void)
+struct ConfClass *make_class(void)
{
- Reg1 aConfClass *tmp;
+ struct ConfClass *tmp;
- tmp = (aConfClass *) RunMalloc(sizeof(aConfClass));
-#ifdef DEBUGMODE
+ tmp = (struct ConfClass*) MyMalloc(sizeof(struct ConfClass));
+ assert(0 != tmp);
+#ifdef DEBUGMODE
classs.inuse++;
#endif
return tmp;
}
-void free_class(aConfClass * tmp)
+void free_class(struct ConfClass * tmp)
{
- RunFree(tmp);
-#ifdef DEBUGMODE
+ MyFree(tmp);
+#ifdef DEBUGMODE
classs.inuse--;
#endif
}
-aConfItem *make_conf(void)
-{
- Reg1 aConfItem *aconf;
-
- aconf = (struct ConfItem *)RunMalloc(sizeof(aConfItem));
-#ifdef DEBUGMODE
- aconfs.inuse++;
-#endif
- memset(&aconf->ipnum, 0, 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;
- aconf->confClass = NULL;
- return (aconf);
-}
-
-void delist_conf(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(aConfItem *aconf)
-{
- del_queries((char *)aconf);
- RunFree(aconf->host);
- if (aconf->passwd)
- memset(aconf->passwd, 0, strlen(aconf->passwd));
- RunFree(aconf->passwd);
- RunFree(aconf->name);
- RunFree(aconf);
-#ifdef DEBUGMODE
- aconfs.inuse--;
-#endif
- return;
-}
-
-aGline *make_gline(int is_ipmask, char *host, char *reason,
- char *name, time_t expire)
-{
- Reg4 aGline *agline;
-#ifdef BADCHAN
- int gtype=0;
- if(*host == '#' || *host == '&' || *host == '+')
- gtype=1; /* BAD CHANNEL GLINE */
-#endif
-
- agline = (struct Gline *)RunMalloc(sizeof(aGline)); /* alloc memory */
- DupString(agline->host, host); /* copy vital information */
- DupString(agline->reason, reason);
- DupString(agline->name, name);
- agline->expire = expire;
- agline->gflags = GLINE_ACTIVE; /* gline is active */
- if (is_ipmask)
- SetGlineIsIpMask(agline);
-
-#ifdef BADCHAN
- if(gtype)
- { agline->next = badchan; /* link it into the list */
- return (badchan = agline);
- }
-#endif
- agline->next = gline; /* link it into the list */
- return (gline = agline);
-}
-
-aGline *find_gline(aClient *cptr, 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? */
- /* Added a check against the user's IP address as well -Kev */
- if ((GlineIsIpMask(agline) ?
- match(agline->host, inetntoa(cptr->ip)) :
- match(agline->host, cptr->sockhost)) == 0 &&
- match(agline->name, cptr->user->username) == 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 *agline, aGline *pgline)
-{
- if (pgline)
- pgline->next = agline->next; /* squeeze agline out */
- else
- {
-#ifdef BADCHAN
- if(*agline->host =='#' || *agline->host == '&' || *agline->host == '+')
- {
- badchan = agline->next;
- }
- else
-#endif
- gline = agline->next;
- }
-
- RunFree(agline->host); /* and free up the memory */
- RunFree(agline->reason);
- RunFree(agline->name);
- RunFree(agline);
-}
-
-#ifdef BADCHAN
-int bad_channel(char *name)
-{ aGline *agline;
-
- agline=badchan;
- while(agline)
- {
- if ((agline->gflags&GLINE_ACTIVE) && (agline->expire >TStime()) &&
- !mmatch(agline->host,name))
- { return 1;
- }
- agline=agline->next;
- }
- return 0;
-}
-#endif
-
-#ifdef DEBUGMODE
-void send_listinfo(aClient *cptr, char *name)
+#ifdef DEBUGMODE
+void send_listinfo(struct Client *cptr, char *name)
{
int inuse = 0, mem = 0, tmp = 0;
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));
+ tmp = users.inuse * sizeof(struct User));
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));
+ tmp = servs.inuse * sizeof(struct Server));
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));
+ tmp = links.inuse * sizeof(struct SLink));
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(aConfClass));
+ tmp = classs.inuse * sizeof(struct ConfClass));
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));
+ me.name, RPL_STATSDEBUG, name, GlobalConfCount,
+ tmp = GlobalConfCount * sizeof(struct ConfItem));
mem += tmp;
- inuse += aconfs.inuse,
+ inuse += GlobalConfCount,
sendto_one(cptr, ":%s %d %s :Totals: inuse %d %d",
me.name, RPL_STATSDEBUG, name, inuse, mem);
}