+2000-09-17 Thomas Helvey <helveytw@home.com>
+ * ircd/class.c: encapsulate class list
+ * include/class.h: clean up classes
+ * * fixup code that depended on changes
+
2000-09-17 Thomas Helvey <helveytw@home.com>
* ircd/s_conf.c: add me to local conf
* include/s_conf.h: move CONF_ME macro to chkconf.c
/*
* Structures
*/
-struct ConfClass {
+struct ConnectionClass {
unsigned int conClass;
unsigned int conFreq;
unsigned int pingFreq;
unsigned int maxLinks;
unsigned int maxSendq;
unsigned int links;
- struct ConfClass *next;
+ struct ConnectionClass *next;
};
/*
#define ConfPingFreq(x) ((x)->confClass->pingFreq)
#define ConfSendq(x) ((x)->confClass->maxSendq)
-#define FirstClass() classes
-#define NextClass(x) ((x)->next)
-
-#define MarkDelete(x) do { MaxLinks(x) = (unsigned int)-1; } while(0)
-#define IsMarkedDelete(x) (MaxLinks(x) == (unsigned int)-1)
-
/*
* Proto types
*/
-extern struct ConfClass *find_class(unsigned int cclass);
-extern struct ConfClass *make_class(void);
-extern void free_class(struct ConfClass * tmp);
-extern unsigned int get_con_freq(struct ConfClass * clptr);
+extern void init_class(void);
+
+extern const struct ConnectionClass* get_class_list(void);
+extern void class_mark_delete(void);
+extern void class_delete_marked(void);
+
+extern struct ConnectionClass *find_class(unsigned int cclass);
+extern struct ConnectionClass *make_class(void);
+extern void free_class(struct ConnectionClass * tmp);
+extern unsigned int get_con_freq(struct ConnectionClass * clptr);
extern unsigned int get_client_ping(struct Client *acptr);
extern unsigned int get_conf_class(const struct ConfItem *aconf);
extern unsigned int get_conf_ping(const struct ConfItem *aconf);
extern unsigned int get_client_class(struct Client *acptr);
extern void add_class(unsigned int conclass, unsigned int ping,
- unsigned int confreq, unsigned int maxli, unsigned int sendq);
+ unsigned int confreq, unsigned int maxli, unsigned int sendq);
extern void check_class(void);
-extern void initclass(void);
extern void report_classes(struct Client *sptr);
extern unsigned int get_sendq(struct Client* cptr);
-extern struct ConfClass *classes;
-
+extern void class_send_meminfo(struct Client* cptr);
#endif /* INCLUDED_class_h */
unsigned short int port;
time_t hold; /* Hold until this time (calendar time) */
int dns_pending; /* a dns request is pending */
- struct ConfClass* confClass; /* Class of connection */
+ struct ConnectionClass* confClass; /* Class of connection */
};
struct ServerConf {
int dns_pending;
int connected;
time_t hold;
- struct ConfClass* confClass;
+ struct ConnectionClass* confClass;
};
/*
../include/ircd_defs.h ../include/dbuf.h ../include/ircd_handler.h \
../include/ircd.h ../config/config.h ../config/setup.h \
../include/struct.h ../include/numnicks.h ../include/ircd_alloc.h \
- ../include/fda.h ../include/s_bsd.h ../include/s_debug.h \
- ../include/s_user.h ../include/send.h
+ ../include/fda.h ../include/s_debug.h ../include/s_user.h \
+ ../include/send.h
channel.o: channel.c ../include/channel.h ../config/config.h \
../config/setup.h ../include/ircd_defs.h ../include/client.h \
../include/dbuf.h ../include/ircd_handler.h ../include/hash.h \
../include/struct.h ../include/ircd_reply.h ../include/list.h \
../include/numeric.h ../include/s_conf.h ../include/s_debug.h \
../include/send.h
+client.o: client.c ../include/client.h ../include/ircd_defs.h \
+ ../include/dbuf.h ../include/ircd_handler.h ../include/class.h \
+ ../include/ircd.h ../config/config.h ../config/setup.h \
+ ../include/struct.h ../include/ircd_reply.h ../include/list.h \
+ ../include/numeric.h ../include/s_conf.h ../include/s_debug.h \
+ ../include/send.h
crule.o: crule.c ../include/crule.h ../include/client.h \
../include/ircd_defs.h ../include/dbuf.h ../include/ircd_handler.h \
../include/ircd.h ../config/config.h ../config/setup.h \
static char *getfield(char *newline);
static int validate(struct ConfItem *top);
static struct ConfItem *chk_initconf(void);
-static struct ConfClass *get_class(int cn, int ism);
+static struct ConnectionClass *get_class(int cn, int ism);
static int numclasses = 0, *classarr = (int *)NULL, debugflag = 0;
static char *chk_configfile = CPATH;
return ctop;
}
-static struct ConfClass *get_class(int cn, int ism)
+static struct ConnectionClass *get_class(int cn, int ism)
{
- static struct ConfClass cls;
+ static struct ConnectionClass cls;
if (ism == 1)
{
cls.conClass = (unsigned int)-1;
#include "class.h"
#include "client.h"
#include "ircd.h"
+#include "ircd_alloc.h"
#include "ircd_reply.h"
#include "list.h"
#include "numeric.h"
#include "s_conf.h"
#include "s_debug.h"
#include "send.h"
-#include "struct.h"
#include <assert.h>
#define BAD_PING ((unsigned int)-2)
#define BAD_CLIENT_CLASS ((unsigned int)-3)
-struct ConfClass *classes;
+static struct ConnectionClass* connClassList;
+static unsigned int connClassAllocCount;
+
+const struct ConnectionClass* get_class_list(void)
+{
+ return connClassList;
+}
+
+struct ConnectionClass* make_class(void)
+{
+ struct ConnectionClass *tmp;
+
+ tmp = (struct ConnectionClass*) MyMalloc(sizeof(struct ConnectionClass));
+ assert(0 != tmp);
+ ++connClassAllocCount;
+ return tmp;
+}
+
+void free_class(struct ConnectionClass* tmp)
+{
+ if (tmp) {
+ MyFree(tmp);
+ --connClassAllocCount;
+ }
+}
+
+/*
+ * init_class - initialize the class list
+ */
+void init_class(void)
+{
+ connClassList = (struct ConnectionClass*) make_class();
+
+ ConClass(connClassList) = 0;
+ ConFreq(connClassList) = CONNECTFREQUENCY;
+ PingFreq(connClassList) = PINGFREQUENCY;
+ MaxLinks(connClassList) = MAXIMUM_LINKS;
+ MaxSendq(connClassList) = DEFAULTMAXSENDQLENGTH;
+ Links(connClassList) = 0;
+ connClassList->next = 0;
+}
+
+/*
+ * class_mark_delete - mark classes for delete
+ * We don't delete the class table, rather mark all entries
+ * for deletion. The table is cleaned up by class_delete_marked(). - avalon
+ * XXX - This destroys data
+ */
+void class_mark_delete(void)
+{
+ struct ConnectionClass* p;
+ assert(0 != connClassList);
+
+ for (p = connClassList->next; p; p = p->next)
+ p->maxLinks = BAD_CONF_CLASS;
+}
+
+/*
+ * check_class
+ * delete classes marked for deletion
+ * XXX - memory leak, no one deletes classes that become unused
+ * later
+ */
+void class_delete_marked(void)
+{
+ struct ConnectionClass* cl;
+ struct ConnectionClass* prev;
+
+ Debug((DEBUG_DEBUG, "Class check:"));
+
+ for (prev = cl = connClassList; cl; cl = prev->next) {
+ Debug((DEBUG_DEBUG, "Class %d : CF: %d PF: %d ML: %d LI: %d SQ: %d",
+ ConClass(cl), ConFreq(cl), PingFreq(cl), MaxLinks(cl), Links(cl), MaxSendq(cl)));
+ /*
+ * unlink marked classes, delete unreferenced ones
+ */
+ if (BAD_CONF_CLASS == cl->maxLinks) {
+ prev->next = cl->next;
+ if (0 == cl->links)
+ free_class(cl);
+ }
+ else
+ prev = cl;
+ }
+}
unsigned int get_conf_class(const struct ConfItem* aconf)
{
unsigned int get_client_class(struct Client *acptr)
{
struct SLink *tmp;
- struct ConfClass *cl;
+ struct ConnectionClass *cl;
unsigned int retc = BAD_CLIENT_CLASS;
if (acptr && !IsMe(acptr) && (acptr->confs))
return (ping);
}
-unsigned int get_con_freq(struct ConfClass * clptr)
+unsigned int get_con_freq(struct ConnectionClass * clptr)
{
if (clptr)
return (ConFreq(clptr));
* immeadiately after the first one (class 0).
*/
void add_class(unsigned int conClass, unsigned int ping, unsigned int confreq,
- unsigned int maxli, unsigned int sendq)
+ unsigned int maxli, unsigned int sendq)
{
- struct ConfClass *t, *p;
+ struct ConnectionClass* t;
+ struct ConnectionClass* p;
t = find_class(conClass);
- if ((t == classes) && (conClass != 0))
+ if ((t == connClassList) && (conClass != 0))
{
- p = (struct ConfClass *) make_class();
- NextClass(p) = NextClass(t);
- NextClass(t) = p;
+ p = (struct ConnectionClass *) make_class();
+ p->next = t->next;
+ t->next = p;
}
else
p = t;
- Debug((DEBUG_DEBUG, "Add Class %u: p %p t %p - cf: %u pf: %u ml: %u sq: %d",
- conClass, p, t, confreq, ping, maxli, sendq));
+ Debug((DEBUG_DEBUG, "Add Class %u: cf: %u pf: %u ml: %u sq: %d",
+ conClass, confreq, ping, maxli, sendq));
ConClass(p) = conClass;
ConFreq(p) = confreq;
PingFreq(p) = ping;
Links(p) = 0;
}
-struct ConfClass *find_class(unsigned int cclass)
+struct ConnectionClass* find_class(unsigned int cclass)
{
- struct ConfClass *cltmp;
+ struct ConnectionClass *cltmp;
- for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp))
+ for (cltmp = connClassList; cltmp; cltmp = cltmp->next) {
if (ConClass(cltmp) == cclass)
return cltmp;
- return classes;
-}
-
-void check_class(void)
-{
- struct ConfClass *cltmp, *cltmp2;
-
- Debug((DEBUG_DEBUG, "Class check:"));
-
- for (cltmp2 = cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp2))
- {
- Debug((DEBUG_DEBUG,
- "Class %d : CF: %d PF: %d ML: %d LI: %d SQ: %d",
- ConClass(cltmp), ConFreq(cltmp), PingFreq(cltmp),
- MaxLinks(cltmp), Links(cltmp), MaxSendq(cltmp)));
- if (IsMarkedDelete(cltmp))
- {
- NextClass(cltmp2) = NextClass(cltmp);
- if (Links(cltmp) == 0)
- free_class(cltmp);
- }
- else
- cltmp2 = cltmp;
}
-}
-
-void initclass(void)
-{
- classes = (struct ConfClass *) make_class();
-
- ConClass(FirstClass()) = 0;
- ConFreq(FirstClass()) = CONNECTFREQUENCY;
- PingFreq(FirstClass()) = PINGFREQUENCY;
- MaxLinks(FirstClass()) = MAXIMUM_LINKS;
- MaxSendq(FirstClass()) = DEFAULTMAXSENDQLENGTH;
- Links(FirstClass()) = 0;
- NextClass(FirstClass()) = NULL;
+ return connClassList;
}
void report_classes(struct Client *sptr)
{
- struct ConfClass *cltmp;
+ struct ConnectionClass *cltmp;
- for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp))
+ for (cltmp = connClassList; cltmp; cltmp = cltmp->next)
send_reply(sptr, RPL_STATSYLINE, 'Y', ConClass(cltmp), PingFreq(cltmp),
ConFreq(cltmp), MaxLinks(cltmp), MaxSendq(cltmp));
}
else if (cptr->confs) {
struct SLink* tmp;
- struct ConfClass* cl;
+ struct ConnectionClass* cl;
for (tmp = cptr->confs; tmp; tmp = tmp->next) {
if (!tmp->value.aconf || !(cl = tmp->value.aconf->confClass))
return DEFAULTMAXSENDQLENGTH;
}
+void class_send_meminfo(struct Client* cptr)
+{
+ send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Classes: inuse: %d(%d)",
+ connClassAllocCount, connClassAllocCount * sizeof(struct ConnectionClass));
+}
+
+
#define BAD_PING ((unsigned int)-2)
+/*
+ * client_get_ping
+ * returns shortest ping time in attached server or client conf
+ * classes or PINGFREQUENCY
+ */
unsigned int client_get_ping(const struct Client* acptr)
{
unsigned int ping = 0;
#define BAD_CONF_CLASS ((unsigned int)-1)
#define BAD_CLIENT_CLASS ((unsigned int)-3)
-unsigned int get_conf_class(struct ConfItem *aconf)
-{
- if ((aconf) && (aconf->confClass))
- return (ConfClass(aconf));
-
- Debug((DEBUG_DEBUG, "No Class For %s", (aconf) ? aconf->name : "*No Conf*"));
-
- return (BAD_CONF_CLASS);
-
-}
-
-static unsigned int get_conf_ping(struct ConfItem *aconf)
-{
- if ((aconf) && (aconf->confClass))
- return (ConfPingFreq(aconf));
-
- Debug((DEBUG_DEBUG, "No Ping For %s", (aconf) ? aconf->name : "*No Conf*"));
-
- return (BAD_PING);
-}
-
unsigned int get_client_class(struct Client *acptr)
{
struct SLink *tmp;
- struct ConfClass *cl;
+ struct ConnectionClass *cl;
unsigned int retc = BAD_CLIENT_CLASS;
if (acptr && !IsMe(acptr) && (acptr->confs))
return (retc);
}
-unsigned int get_con_freq(struct ConfClass * clptr)
-{
- if (clptr)
- return (ConFreq(clptr));
- else
- return (CONNECTFREQUENCY);
-}
-
-/*
- * When adding a class, check to see if it is already present first.
- * if so, then update the information for that class, rather than create
- * a new entry for it and later delete the old entry.
- * if no present entry is found, then create a new one and add it in
- * immeadiately after the first one (class 0).
- */
-void add_class(unsigned int conClass, unsigned int ping, unsigned int confreq,
- unsigned int maxli, unsigned int sendq)
-{
- struct ConfClass *t, *p;
-
- t = find_class(conClass);
- if ((t == classes) && (conClass != 0))
- {
- p = (struct ConfClass *) make_class();
- NextClass(p) = NextClass(t);
- NextClass(t) = p;
- }
- else
- p = t;
- Debug((DEBUG_DEBUG, "Add Class %u: p %p t %p - cf: %u pf: %u ml: %u sq: %d",
- conClass, p, t, confreq, ping, maxli, sendq));
- ConClass(p) = conClass;
- ConFreq(p) = confreq;
- PingFreq(p) = ping;
- MaxLinks(p) = maxli;
- MaxSendq(p) = (sendq > 0) ? sendq : DEFAULTMAXSENDQLENGTH;
- if (p != t)
- Links(p) = 0;
-}
-
-struct ConfClass *find_class(unsigned int cclass)
-{
- struct ConfClass *cltmp;
-
- for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp))
- if (ConClass(cltmp) == cclass)
- return cltmp;
- return classes;
-}
-
-void check_class(void)
-{
- struct ConfClass *cltmp, *cltmp2;
-
- Debug((DEBUG_DEBUG, "Class check:"));
-
- for (cltmp2 = cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp2))
- {
- Debug((DEBUG_DEBUG,
- "Class %d : CF: %d PF: %d ML: %d LI: %d SQ: %d",
- ConClass(cltmp), ConFreq(cltmp), PingFreq(cltmp),
- MaxLinks(cltmp), Links(cltmp), MaxSendq(cltmp)));
- if (IsMarkedDelete(cltmp))
- {
- NextClass(cltmp2) = NextClass(cltmp);
- if (Links(cltmp) == 0)
- free_class(cltmp);
- }
- else
- cltmp2 = cltmp;
- }
-}
-
-void initclass(void)
-{
- classes = (struct ConfClass *) make_class();
-
- ConClass(FirstClass()) = 0;
- ConFreq(FirstClass()) = CONNECTFREQUENCY;
- PingFreq(FirstClass()) = PINGFREQUENCY;
- MaxLinks(FirstClass()) = MAXIMUM_LINKS;
- MaxSendq(FirstClass()) = DEFAULTMAXSENDQLENGTH;
- Links(FirstClass()) = 0;
- NextClass(FirstClass()) = NULL;
-}
-
-void report_classes(struct Client *sptr)
-{
- struct ConfClass *cltmp;
-
- for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp))
- send_reply(sptr, RPL_STATSYLINE, 'Y', ConClass(cltmp), PingFreq(cltmp),
- ConFreq(cltmp), MaxLinks(cltmp), MaxSendq(cltmp));
-}
unsigned int get_sendq(struct Client *cptr)
{
else if (cptr->confs) {
struct SLink* tmp;
- struct ConfClass* cl;
+ struct ConnectionClass* cl;
for (tmp = cptr->confs; tmp; tmp = tmp->next) {
if (!tmp->value.aconf || !(cl = tmp->value.aconf->confClass))
int connecting;
int confrq;
time_t next = 0;
- struct ConfClass* cltmp;
+ struct ConnectionClass* cltmp;
struct ConfItem* con_conf = 0;
struct Jupe* ajupe;
unsigned int con_class = 0;
initload();
init_list();
init_hash();
- initclass();
+ init_class();
initwhowas();
initmsgtree();
initstats();
hAddClient(&me);
- check_class();
write_pidfile();
init_counters();
*/
#include "list.h"
-#include "class.h"
#include "client.h"
#include "ircd.h"
#include "ircd_alloc.h"
#ifdef DEBUGMODE
static struct liststats {
int inuse;
-} cloc, crem, users, servs, links, classs;
+} cloc, crem, users, servs, links;
#endif
static unsigned int localClientAllocCount;
memset(&users, 0, sizeof(users));
memset(&servs, 0, sizeof(servs));
memset(&links, 0, sizeof(links));
- memset(&classs, 0, sizeof(classs));
#endif
}
MyFree(lp);
}
-struct ConfClass *make_class(void)
-{
- struct ConfClass *tmp;
-
- tmp = (struct ConfClass*) MyMalloc(sizeof(struct ConfClass));
- assert(0 != tmp);
-#ifdef DEBUGMODE
- classs.inuse++;
-#endif
- return tmp;
-}
-
-void free_class(struct ConfClass * tmp)
-{
- MyFree(tmp);
-#ifdef DEBUGMODE
- classs.inuse--;
-#endif
-}
-
#ifdef DEBUGMODE
void send_listinfo(struct Client *cptr, char *name)
{
links.inuse, tmp = links.inuse * sizeof(struct SLink));
mem += tmp;
inuse += links.inuse;
- send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Classes: inuse: %d(%d)",
- classs.inuse, tmp = classs.inuse * sizeof(struct ConfClass));
- mem += tmp;
- inuse += classs.inuse;
send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Confs: inuse: %d(%d)",
GlobalConfCount, tmp = GlobalConfCount * sizeof(struct ConfItem));
mem += tmp;
* a wild card based search to list it.
*/
send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO, "Connection SendQ "
- "SendM SendKBytes RcveM RcveKBytes :Open since");
+ "SendM SendKBytes RcveM RcveKBytes :Open since");
for (i = 0; i <= HighestFd; i++)
{
if (!(acptr = LocalClientArray[i]))
/* Skip all that do not match the specific query */
if (!(doall || wilds) && 0 != ircd_strcmp(name, acptr->name))
continue;
- send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
- "%s %u %u %u %u %u :%Tu", (*acptr->name) ? acptr->name : "<unregistered>",
- (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
- (int)acptr->sendK, (int)acptr->receiveM,
- (int)acptr->receiveK, CurrentTime - acptr->firsttime);
+ send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
+ "%s %u %u %u %u %u :%Tu", (*acptr->name) ? acptr->name : "<unregistered>",
+ (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
+ (int)acptr->sendK, (int)acptr->receiveM,
+ (int)acptr->receiveK, CurrentTime - acptr->firsttime);
}
break;
}
(wilds && !mmatch(host, aconf->host) &&
(!user || !mmatch(user, aconf->name))))
{
- send_reply(sptr, RPL_STATSKLINE,
- (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host,
- aconf->passwd, aconf->name, aconf->port,
- get_conf_class(aconf));
+ send_reply(sptr, RPL_STATSKLINE,
+ (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host,
+ aconf->passwd, aconf->name, aconf->port,
+ get_conf_class(aconf));
if (--count == 0)
break;
}
(wilds && (!mmatch(host, aconf->host) ||
!mmatch(host, aconf->name))))
{
- send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name,
- aconf->port, get_conf_class(aconf));
+ send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name,
+ aconf->port, get_conf_class(aconf));
if (--count == 0)
break;
}
case 'M':
#if !defined(NDEBUG)
send_reply(sptr, RPL_STATMEMTOT, fda_get_byte_count(),
- fda_get_block_count());
+ fda_get_block_count());
#endif
#if 0
case 'm':
for (mptr = msgtab; mptr->cmd; mptr++)
if (mptr->count)
- send_reply(sptr, RPL_STATSCOMMANDS, mptr->cmd, mptr->count,
- mptr->bytes);
+ send_reply(sptr, RPL_STATSCOMMANDS, mptr->cmd, mptr->count,
+ mptr->bytes);
break;
case 'o':
case 'O':
nowr = CurrentTime - me.since;
send_reply(sptr, RPL_STATSUPTIME, nowr / 86400, (nowr / 3600) % 24,
- (nowr / 60) % 60, nowr % 60);
+ (nowr / 60) % 60, nowr % 60);
send_reply(sptr, RPL_STATSCONN, max_connection_count, max_client_count);
break;
}
case 'v':
- {
- struct ConfClass *cltmp;
-
- for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp)) {
- if (Links(cltmp) > 0)
- send_reply(sptr,RPL_TRACECLASS, ConClass(cltmp), Links(cltmp));
- }
- break;
- }
+ {
+ const struct ConnectionClass* cl = get_class_list();
+
+ for ( ; cl; cl = cl->next) {
+ if (Links(cl) > 0)
+ send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl));
+ }
+ }
+ break;
case 'W':
case 'w':
calc_load(sptr);
case 'X':
case 'x':
#ifdef DEBUGMODE
+ class_send_meminfo(sptr);
send_listinfo(sptr, parv[0]);
#endif
break;
default:
stat = '*';
while (*infotext)
- sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, *infotext++);
+ sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, *infotext++);
break;
}
send_reply(sptr, RPL_ENDOFSTATS, stat);
* a wild card based search to list it.
*/
send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO, "Connection SendQ "
- "SendM SendKBytes RcveM RcveKBytes :Open since");
+ "SendM SendKBytes RcveM RcveKBytes :Open since");
for (i = 0; i <= HighestFd; i++)
{
if (!(acptr = LocalClientArray[i]))
continue;
/* Don't show invisible people to unauthorized people when using
* wildcards -- Is this still needed now /stats is oper only ?
- * Not here, because ms_stats is specifically a remote command,
- * thus the check was removed. -Ghostwolf */
+ * Not here, because ms_stats is specifically a remote command,
+ * thus the check was removed. -Ghostwolf */
/* Only show the ones that match the given mask - if any */
if (!doall && wilds && match(name, acptr->name))
continue;
/* Skip all that do not match the specific query */
if (!(doall || wilds) && 0 != ircd_strcmp(name, acptr->name))
continue;
- send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
- "%s %u %u %u %u %u :%Tu", acptr->name,
- (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
- (int)acptr->sendK, (int)acptr->receiveM,
- (int)acptr->receiveK, CurrentTime - acptr->firsttime);
+ send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
+ "%s %u %u %u %u %u :%Tu", acptr->name,
+ (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
+ (int)acptr->sendK, (int)acptr->receiveM,
+ (int)acptr->receiveK, CurrentTime - acptr->firsttime);
}
break;
}
(wilds && !mmatch(host, aconf->host) &&
(!user || !mmatch(user, aconf->name))))
{
- send_reply(sptr, RPL_STATSKLINE,
- (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host,
- aconf->passwd, aconf->name, aconf->port,
- get_conf_class(aconf));
+ send_reply(sptr, RPL_STATSKLINE,
+ (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host,
+ aconf->passwd, aconf->name, aconf->port,
+ get_conf_class(aconf));
if (--count == 0)
break;
}
(wilds && (!mmatch(host, aconf->host) ||
!mmatch(host, aconf->name))))
{
- send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name,
- aconf->port, get_conf_class(aconf));
+ send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name,
+ aconf->port, get_conf_class(aconf));
if (--count == 0)
break;
}
case 'M':
#if !defined(NDEBUG)
send_reply(sptr, RPL_STATMEMTOT, fda_get_byte_count(),
- fda_get_block_count());
+ fda_get_block_count());
#endif
#if 0
case 'm':
for (mptr = msgtab; mptr->cmd; mptr++)
if (mptr->count)
- send_reply(sptr, RPL_STATSCOMMANDS, mptr->cmd, mptr->count,
- mptr->bytes);
+ send_reply(sptr, RPL_STATSCOMMANDS, mptr->cmd, mptr->count,
+ mptr->bytes);
break;
case 'o':
case 'O':
nowr = CurrentTime - me.since;
send_reply(sptr, RPL_STATSUPTIME, nowr / 86400, (nowr / 3600) % 24,
- (nowr / 60) % 60, nowr % 60);
+ (nowr / 60) % 60, nowr % 60);
send_reply(sptr, RPL_STATSCONN, max_connection_count, max_client_count);
break;
}
case 'v':
- {
- struct ConfClass *cltmp;
-
- for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp)) {
- if (Links(cltmp) > 0)
- send_reply(sptr,RPL_TRACECLASS, ConClass(cltmp), Links(cltmp));
- }
- break;
- }
+ {
+ const struct ConnectionClass* cl = get_class_list();
+
+ for ( ; cl; cl = cl->next) {
+ if (Links(cl) > 0)
+ send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl));
+ }
+ }
+ break;
case 'W':
case 'w':
case 'X':
case 'x':
#ifdef DEBUGMODE
+ class_send_meminfo(sptr);
send_listinfo(sptr, parv[0]);
#endif
break;
* a wild card based search to list it.
*/
send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO, "Connection SendQ "
- "SendM SendKBytes RcveM RcveKBytes :Open since");
+ "SendM SendKBytes RcveM RcveKBytes :Open since");
for (i = 0; i <= HighestFd; i++)
{
if (!(acptr = LocalClientArray[i]))
/* Skip all that do not match the specific query */
if (!(doall || wilds) && 0 != ircd_strcmp(name, acptr->name))
continue;
- send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
- "%s %u %u %u %u %u :%Tu", acptr->name,
- (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
- (int)acptr->sendK, (int)acptr->receiveM,
- (int)acptr->receiveK, CurrentTime - acptr->firsttime);
+ send_reply(sptr, SND_EXPLICIT | RPL_STATSLINKINFO,
+ "%s %u %u %u %u %u :%Tu", acptr->name,
+ (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
+ (int)acptr->sendK, (int)acptr->receiveM,
+ (int)acptr->receiveK, CurrentTime - acptr->firsttime);
}
break;
}
(wilds && !mmatch(host, aconf->host) &&
(!user || !mmatch(user, aconf->name))))
{
- send_reply(sptr, RPL_STATSKLINE,
- (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host,
- aconf->passwd, aconf->name, aconf->port,
- get_conf_class(aconf));
+ send_reply(sptr, RPL_STATSKLINE,
+ (aconf->status & CONF_KILL) ? 'K' : 'k', aconf->host,
+ aconf->passwd, aconf->name, aconf->port,
+ get_conf_class(aconf));
if (--count == 0)
break;
}
(wilds && (!mmatch(host, aconf->host) ||
!mmatch(host, aconf->name))))
{
- send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name,
- aconf->port, get_conf_class(aconf));
+ send_reply(sptr, RPL_STATSILINE, 'I', aconf->host, aconf->name,
+ aconf->port, get_conf_class(aconf));
if (--count == 0)
break;
}
case 'M':
#if !defined(NDEBUG)
send_reply(sptr, RPL_STATMEMTOT, fda_get_byte_count(),
- fda_get_block_count());
+ fda_get_block_count());
#endif
#if 0
case 'm':
for (mptr = msgtab; mptr->cmd; mptr++)
if (mptr->count)
- send_reply(sptr, RPL_STATSCOMMANDS, mptr->cmd, mptr->count,
- mptr->bytes);
+ send_reply(sptr, RPL_STATSCOMMANDS, mptr->cmd, mptr->count,
+ mptr->bytes);
break;
case 'o':
case 'O':
nowr = CurrentTime - me.since;
send_reply(sptr, RPL_STATSUPTIME, nowr / 86400, (nowr / 3600) % 24,
- (nowr / 60) % 60, nowr % 60);
+ (nowr / 60) % 60, nowr % 60);
send_reply(sptr, RPL_STATSCONN, max_connection_count, max_client_count);
break;
}
case 'v':
- {
- struct ConfClass *cltmp;
-
- for (cltmp = FirstClass(); cltmp; cltmp = NextClass(cltmp)) {
- if (Links(cltmp) > 0)
- send_reply(sptr,RPL_TRACECLASS, ConClass(cltmp), Links(cltmp));
- }
- break;
- }
- case 'W':
- case 'w':
- calc_load(sptr);
- break;
- case 'X':
- case 'x':
-#ifdef DEBUGMODE
- send_listinfo(sptr, parv[0]);
-#endif
- break;
- case 'Y':
- case 'y':
- report_classes(sptr);
- break;
- case 'Z':
- case 'z':
- count_memory(sptr, parv[0]);
- break;
- default:
- stat = '*';
- while (*infotext)
- sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, *infotext++);
- break;
- }
- send_reply(sptr, RPL_ENDOFSTATS, stat);
- return 0;
-}
-
-#if 0
-/*
- * m_stats
- *
- * parv[0] = sender prefix
- * parv[1] = statistics selector (defaults to Message frequency)
- * parv[2] = target server (current server defaulted, if omitted)
- * And 'stats l' and 'stats' L:
- * parv[3] = server mask ("*" defaulted, if omitted)
- * Or for stats p,P:
- * parv[3] = port mask (returns p-lines when its port is matched by this)
- * Or for stats k,K,i and I:
- * parv[3] = [user@]host.name (returns which K/I-lines match this)
- * or [user@]host.mask (returns which K/I-lines are mmatched by this)
- * (defaults to old reply if ommitted, when local or Oper)
- * A remote mask (something containing wildcards) is only
- * allowed for IRC Operators.
- * Or for stats M:
- * parv[3] = time param
- * parv[4] = time param
- * (see report_memleak_stats() in runmalloc.c for details)
- *
- * This function is getting really ugly. -Ghostwolf
- */
-int m_stats(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
-{
- static char Sformat[] = ":%s %d %s Connection SendQ SendM SendKBytes "
- "RcveM RcveKBytes :Open since";
- static char Lformat[] = ":%s %d %s %s %u %u %u %u %u :" TIME_T_FMT;
- struct Message *mptr;
- struct Client *acptr;
- struct Gline* gline;
- struct ConfItem *aconf;
- char stat = parc > 1 ? parv[1][0] : '\0';
- int i;
-
-/* m_stats is so obnoxiously full of special cases that the different
- * hunt_server() possiblites were becoming very messy. It now uses a
- * switch() so as to be easier to read and update as params change.
- * -Ghostwolf
- */
- switch (stat)
- {
- /* open to all, standard # of params */
- case 'U':
- case 'u':
- {
- if (hunt_server(0, cptr, sptr, "%s%s " TOK_STATS " %s :%s", 2, parc, parv) /* XXX DEAD */
- != HUNTED_ISME)
- return 0;
- break;
- }
-
- /* open to all, varying # of params */
- case 'k':
- case 'K':
- case 'i':
- case 'I':
- case 'p':
- case 'P':
- {
- if (parc > 3)
- {
- if (hunt_server(0, cptr, sptr, "%s%s " TOK_STATS " %s %s :%s", 2, parc, parv) /* XXX DEAD */
- != HUNTED_ISME)
- return 0;
- }
- else
- {
- if (hunt_server(0, cptr, sptr, "%s%s " TOK_STATS " %s :%s", 2, parc, parv) /* XXX DEAD */
- != HUNTED_ISME)
- return 0;
- }
- break;
- }
-
- /* oper only, varying # of params */
- case 'l':
- case 'L':
- case 'M':
- {
- if (parc == 4)
- {
- if (hunt_server(1, cptr, sptr, "%s%s " TOK_STATS " %s %s :%s", 2, parc, parv) /* XXX DEAD */
- != HUNTED_ISME)
- return 0;
- }
- else if (parc > 4)
- {
- if (hunt_server(1, cptr, sptr, "%s%s " TOK_STATS " %s %s %s :%s", 2, parc, /* XXX DEAD */
- parv) != HUNTED_ISME)
- return 0;
- }
- else if (hunt_server(1, cptr, sptr, "%s%s " TOK_STATS " %s :%s", 2, parc, parv) /* XXX DEAD */
- != HUNTED_ISME)
- return 0;
- break;
- }
-
- /* oper only, standard # of params */
- default:
- {
- if (hunt_server(1, cptr, sptr, "%s%s " TOK_STATS " %s :%s", 2, parc, parv) /* XXX DEAD */
- != HUNTED_ISME)
- return 0;
- break;
- }
- }
-
- switch (stat)
- {
- case 'L':
- case 'l':
- {
- int doall = 0, wilds = 0;
- char *name = "*";
- if (parc > 3 && *parv[3])
- {
- char *p;
- name = parv[3];
- wilds = (*name == '*' || *name == '?');
- for (p = name + 1; *p; ++p)
- if ((*p == '*' || *p == '?') && p[-1] != '\\')
- {
- wilds = 1;
- break;
- }
- }
- else
- doall = 1;
- /*
- * Send info about connections which match, or all if the
- * mask matches me.name. Only restrictions are on those who
- * are invisible not being visible to 'foreigners' who use
- * a wild card based search to list it.
- */
- sendto_one(sptr, Sformat, me.name, RPL_STATSLINKINFO, parv[0]); /* XXX DEAD */
- for (i = 0; i <= HighestFd; i++)
- {
- if (!(acptr = LocalClientArray[i]))
- continue;
- /* Don't return clients when this is a request for `all' */
- if (doall && IsUser(acptr))
- continue;
- /* Don't show invisible people to unauthorized people when using
- * wildcards -- Is this still needed now /stats is oper only ? */
- if (IsInvisible(acptr) && (doall || wilds) &&
- !(MyConnect(sptr) && IsOper(sptr)) &&
- !IsAnOper(acptr) && (acptr != sptr))
- continue;
- /* Only show the ones that match the given mask - if any */
- if (!doall && wilds && match(name, acptr->name))
- continue;
- /* Skip all that do not match the specific query */
- if (!(doall || wilds) && 0 != ircd_strcmp(name, acptr->name))
- continue;
- sendto_one(sptr, Lformat, me.name, RPL_STATSLINKINFO, parv[0], /* XXX DEAD */
- acptr->name,
- (int)DBufLength(&acptr->sendQ), (int)acptr->sendM,
- (int)acptr->sendK, (int)acptr->receiveM, (int)acptr->receiveK,
- CurrentTime - acptr->firsttime);
- }
- break;
- }
- case 'C':
- case 'c':
- report_configured_links(sptr, CONF_SERVER);
- break;
- case 'G':
- case 'g': /* send glines */
- gline_remove_expired(TStime());
- for (gline = GlobalGlineList; gline; gline = gline->next) {
- sendto_one(sptr, rpl_str(RPL_STATSGLINE), me.name, /* XXX DEAD */
- sptr->name, 'G', gline->name, gline->host,
- gline->expire, gline->reason);
- }
- break;
- case 'H':
- case 'h':
- report_configured_links(sptr, CONF_HUB | CONF_LEAF);
- break;
- case 'I':
- case 'i':
- case 'K':
- case 'k': /* display CONF_IPKILL as well
- as CONF_KILL -Kev */
- {
- int wilds, count;
- char *user, *host, *p;
- int conf_status = (stat == 'k' || stat == 'K') ? CONF_KLINE : CONF_CLIENT;
- if ((MyUser(sptr) || IsOper(sptr)) && parc < 4)
- {
- report_configured_links(sptr, conf_status);
- break;
- }
- if (parc < 4 || *parv[3] == '\0')
- return need_more_params(sptr,
- (conf_status & CONF_KLINE) ? "STATS K" : "STATS I");
-
- wilds = 0;
- for (p = parv[3]; *p; p++)
- {
- if (*p == '\\')
- {
- if (!*++p)
- break;
- continue;
- }
- if (*p == '?' || *p == '*')
- {
- wilds = 1;
- break;
- }
- }
- if (!(MyConnect(sptr) || IsOper(sptr)))
{
- wilds = 0;
- count = 3;
- }
- else
- count = 1000;
-
- if (conf_status == CONF_CLIENT)
- {
- user = 0; /* Not used, but to avoid compiler warning. */
-
- host = parv[3];
- }
- else
- {
- if ((host = strchr(parv[3], '@')))
- {
- user = parv[3];
- *host++ = 0;;
- }
- else
- {
- user = 0;
- host = parv[3];
- }
- }
- for (aconf = GlobalConfList; aconf; aconf = aconf->next)
- {
- if ((aconf->status & conf_status))
- {
- if (conf_status == CONF_KLINE)
- {
- if ((!wilds && ((user || aconf->host[1]) &&
- !match(aconf->host, host) &&
- (!user || !match(aconf->name, user)))) ||
- (wilds && !mmatch(host, aconf->host) &&
- (!user || !mmatch(user, aconf->name))))
- {
- sendto_one(sptr, rpl_str(RPL_STATSKLINE), me.name, /* XXX DEAD */
- sptr->name, 'K', aconf->host, aconf->passwd, aconf->name,
- aconf->port, get_conf_class(aconf));
- if (--count == 0)
- break;
- }
- }
- else if (conf_status == CONF_CLIENT)
- {
- if ((!wilds && (!match(aconf->host, host) ||
- !match(aconf->name, host))) ||
- (wilds && (!mmatch(host, aconf->host) ||
- !mmatch(host, aconf->name))))
- {
- sendto_one(sptr, rpl_str(RPL_STATSILINE), me.name, /* XXX DEAD */
- sptr->name, 'I', aconf->host, aconf->name,
- aconf->port, get_conf_class(aconf));
- if (--count == 0)
- break;
- }
- }
+ const struct ConnectionClass* cl = get_class_list();
+
+ for ( ; cl; cl = cl->next) {
+ if (Links(cl) > 0)
+ send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl));
}
}
break;
- }
- case 'M':
-#if !defined(NDEBUG)
- sendto_one(sptr, rpl_str(RPL_STATMEMTOT), /* XXX DEAD */
- me.name, parv[0], fda_get_byte_count(), fda_get_block_count());
-#endif
-
-#if 0
-#ifdef MEMSIZESTATS
- sendto_one(sptr, rpl_str(RPL_STATMEMTOT), /* XXX DEAD */
- me.name, parv[0], get_mem_size(), get_alloc_cnt());
-#endif
-#ifdef MEMLEAKSTATS
- report_memleak_stats(sptr, parc, parv);
-#endif
-#if !defined(MEMSIZESTATS) && !defined(MEMLEAKSTATS)
- sendto_one(sptr, ":%s NOTICE %s :stats M : Memory allocation monitoring " /* XXX DEAD */
- "is not enabled on this server", me.name, parv[0]);
-#endif
-#endif /* 0 */
- break;
- case 'm':
- for (mptr = msgtab; mptr->cmd; mptr++)
- if (mptr->count)
- sendto_one(sptr, rpl_str(RPL_STATSCOMMANDS), /* XXX DEAD */
- me.name, parv[0], mptr->cmd, mptr->count, mptr->bytes);
- break;
- case 'o':
- case 'O':
- report_configured_links(sptr, CONF_OPS);
- break;
- case 'p':
- case 'P':
- /*
- * show listener ports
- * show hidden ports to opers, if there are more than 3 parameters,
- * interpret the fourth parameter as the port number, limit non-local
- * or non-oper results to 8 ports.
- */
- show_ports(sptr, IsOper(sptr), (parc > 3) ? atoi(parv[3]) : 0,
- (MyUser(sptr) || IsOper(sptr)) ? 100 : 8);
- break;
- case 'R':
- case 'r':
-#ifdef DEBUGMODE
- send_usage(sptr, parv[0]);
-#endif
- break;
- case 'D':
- report_crule_list(sptr, CRULE_ALL);
- break;
- case 'd':
- report_crule_list(sptr, CRULE_MASK);
- break;
- case 't':
- tstats(sptr, parv[0]);
- break;
- case 'T':
- report_motd_list(sptr);
- break;
- case 'U':
- report_configured_links(sptr, CONF_UWORLD);
- break;
- case 'u':
- {
- time_t nowr;
-
- nowr = CurrentTime - me.since;
- sendto_one(sptr, rpl_str(RPL_STATSUPTIME), me.name, parv[0], /* XXX DEAD */
- nowr / 86400, (nowr / 3600) % 24, (nowr / 60) % 60, nowr % 60);
- sendto_one(sptr, rpl_str(RPL_STATSCONN), me.name, parv[0], /* XXX DEAD */
- max_connection_count, max_client_count);
- break;
- }
case 'W':
case 'w':
calc_load(sptr);
case 'X':
case 'x':
#ifdef DEBUGMODE
+ class_send_meminfo(sptr);
send_listinfo(sptr, parv[0]);
#endif
break;
break;
default:
stat = '*';
+ while (*infotext)
+ sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, *infotext++);
break;
}
- sendto_one(sptr, rpl_str(RPL_ENDOFSTATS), me.name, parv[0], stat); /* XXX DEAD */
+ send_reply(sptr, RPL_ENDOFSTATS, stat);
return 0;
}
-#endif /* 0 */
-
{
int i;
struct Client *acptr;
- struct ConfClass *cltmp;
- char *tname;
- int doall, link_s[MAXCONNECTIONS], link_u[MAXCONNECTIONS];
- int cnt = 0, wilds, dow;
+ const struct ConnectionClass* cl;
+ char* tname;
+ int doall;
+ int link_s[MAXCONNECTIONS];
+ int link_u[MAXCONNECTIONS];
+ int cnt = 0;
+ int wilds;
+ int dow;
if (parc < 2 || BadPtr(parv[1])) {
/* just "TRACE" without parameters. Must be from local client */
me.serv->by : "*", "*", me.name, 0, 0);
return 0;
}
- for (cltmp = FirstClass(); doall && cltmp; cltmp = NextClass(cltmp))
- if (Links(cltmp) > 0)
- send_reply(sptr, RPL_TRACECLASS, ConClass(cltmp), Links(cltmp));
+ if (doall) {
+ for (cl = get_class_list(); cl; cl = cl->next) {
+ if (Links(cl) > 0)
+ send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl));
+ }
+ }
return 0;
}
{
int i;
struct Client *acptr;
- struct ConfClass *cltmp;
+ const struct ConnectionClass* cl;
char *tname;
- int doall, link_s[MAXCONNECTIONS], link_u[MAXCONNECTIONS];
- int cnt = 0, wilds, dow;
+ int doall;
+ int link_s[MAXCONNECTIONS];
+ int link_u[MAXCONNECTIONS];
+ int cnt = 0;
+ int wilds;
+ int dow;
if (parc < 2 || BadPtr(parv[1])) {
/* just "TRACE" without parameters. Must be from local client */
me.serv->by : "*", "*", me.name, 0, 0);
return 0;
}
- for (cltmp = FirstClass(); doall && cltmp; cltmp = NextClass(cltmp))
- if (Links(cltmp) > 0)
- send_reply(sptr, RPL_TRACECLASS, ConClass(cltmp), Links(cltmp));
+ if (doall) {
+ for (cl = get_class_list(); cl; cl = cl->next) {
+ if (Links(cl) > 0)
+ send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl));
+ }
+ }
return 0;
}
*/
int mo_trace(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
- int i;
- struct Client *acptr;
- struct ConfClass *cltmp;
- char *tname;
- int doall, link_s[MAXCONNECTIONS], link_u[MAXCONNECTIONS];
- int cnt = 0, wilds, dow;
+ int i;
+ struct Client* acptr;
+ const struct ConnectionClass* cl;
+ char* tname;
+ int doall;
+ int link_s[MAXCONNECTIONS];
+ int link_u[MAXCONNECTIONS];
+ int cnt = 0;
+ int wilds;
+ int dow;
if (parc < 2 || BadPtr(parv[1])) {
/* just "TRACE" without parameters. Must be from local client */
me.serv->by : "*", "*", me.name, 0, 0);
return 0;
}
- for (cltmp = FirstClass(); doall && cltmp; cltmp = NextClass(cltmp))
- if (Links(cltmp) > 0)
- send_reply(sptr, RPL_TRACECLASS, ConClass(cltmp), Links(cltmp));
- return 0;
-}
-
-
-#if 0
-/*
- * m_trace
- *
- * parv[0] = sender prefix
- * parv[1] = nick or servername
- * parv[2] = 'target' servername
- */
-int m_trace(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
-{
- int i;
- struct Client *acptr;
- struct ConfClass *cltmp;
- char *tname;
- int doall, link_s[MAXCONNECTIONS], link_u[MAXCONNECTIONS];
- int cnt = 0, wilds, dow;
-
- if (parc < 2 || BadPtr(parv[1]))
- {
- /* just "TRACE" without parameters. Must be from local client */
- parc = 1;
- acptr = &me;
- tname = me.name;
- i = HUNTED_ISME;
- }
- else if (parc < 3 || BadPtr(parv[2]))
- {
- /* No target specified. Make one before propagating. */
- parc = 2;
- tname = parv[1];
- if ((acptr = find_match_server(parv[1])) ||
- ((acptr = FindClient(parv[1])) && !MyUser(acptr)))
- {
- if (IsUser(acptr))
- parv[2] = acptr->user->server->name;
- else
- parv[2] = acptr->name;
- parc = 3;
- parv[3] = 0;
- if ((i = hunt_server(IsServer(acptr), cptr, sptr, /* XXX DEAD */
- "%s%s " TOK_TRACE " %s :%s", 2, parc, parv)) == HUNTED_NOSUCH)
- return 0;
- }
- else
- i = HUNTED_ISME;
- }
- else
- {
- /* Got "TRACE <tname> :<target>" */
- parc = 3;
- if (MyUser(sptr) || Protocol(cptr) < 10)
- acptr = find_match_server(parv[2]);
- else
- acptr = FindNServer(parv[2]);
- if ((i = hunt_server(0, cptr, sptr, /* XXX DEAD */
- "%s%s " TOK_TRACE " %s :%s", 2, parc, parv)) == HUNTED_NOSUCH)
- return 0;
- tname = parv[1];
- }
-
- if (i == HUNTED_PASS)
- {
- if (!acptr)
- acptr = next_client(GlobalClientList, tname);
- else
- acptr = acptr->from;
- sendto_one(sptr, rpl_str(RPL_TRACELINK), me.name, parv[0], /* XXX DEAD */
-#ifndef GODMODE
- version, debugmode, tname, acptr ? acptr->from->name : "<No_match>");
-#else /* GODMODE */
- version, debugmode, tname, acptr ? acptr->from->name : "<No_match>",
- (acptr && acptr->from->serv) ? acptr->from->serv->timestamp : 0);
-#endif /* GODMODE */
- return 0;
- }
-
- doall = (parv[1] && (parc > 1)) ? !match(tname, me.name) : TRUE;
- wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?');
- dow = wilds || doall;
-
- /* Don't give (long) remote listings to lusers */
- if (dow && !MyConnect(sptr) && !IsAnOper(sptr))
- return 0;
-
- for (i = 0; i < MAXCONNECTIONS; i++)
- link_s[i] = 0, link_u[i] = 0;
-
- if (doall)
- {
- for (acptr = GlobalClientList; acptr; acptr = acptr->next) {
- if (IsUser(acptr))
- link_u[acptr->from->fd]++;
- else if (IsServer(acptr))
- link_s[acptr->from->fd]++;
- }
- }
-
- /* report all direct connections */
-
- for (i = 0; i <= HighestFd; i++)
- {
- const char* name;
- unsigned int conClass;
-
- if (!(acptr = LocalClientArray[i])) /* Local Connection? */
- continue;
- if (IsInvisible(acptr) && dow && !(MyConnect(sptr) && IsOper(sptr)) &&
- !IsAnOper(acptr) && (acptr != sptr))
- continue;
- if (!doall && wilds && match(tname, acptr->name))
- continue;
- if (!dow && 0 != ircd_strcmp(tname, acptr->name))
- continue;
- conClass = get_client_class(acptr);
-
- switch (acptr->status)
- {
- case STAT_CONNECTING:
- sendto_one(sptr, rpl_str(RPL_TRACECONNECTING), /* XXX DEAD */
- me.name, parv[0], conClass, name);
- cnt++;
- break;
- case STAT_HANDSHAKE:
- sendto_one(sptr, rpl_str(RPL_TRACEHANDSHAKE), /* XXX DEAD */
- me.name, parv[0], conClass, name);
- cnt++;
- break;
- case STAT_ME:
- break;
- case STAT_UNKNOWN:
- case STAT_UNKNOWN_USER:
- case STAT_UNKNOWN_SERVER:
- sendto_one(sptr, rpl_str(RPL_TRACEUNKNOWN), /* XXX DEAD */
- me.name, parv[0], conClass, name);
- cnt++;
- break;
- case STAT_USER:
- /* Only opers see users if there is a wildcard
- but anyone can see all the opers. */
- if ((IsAnOper(sptr) && (MyUser(sptr) ||
- !(dow && IsInvisible(acptr)))) || !dow || IsAnOper(acptr))
- {
- if (IsAnOper(acptr))
- sendto_one(sptr, rpl_str(RPL_TRACEOPERATOR), /* XXX DEAD */
- me.name, parv[0], conClass, name, CurrentTime - acptr->lasttime);
- else
- sendto_one(sptr, rpl_str(RPL_TRACEUSER), /* XXX DEAD */
- me.name, parv[0], conClass, name, CurrentTime - acptr->lasttime);
- cnt++;
- }
- break;
- /*
- * Connection is a server
- *
- * Serv <class> <nS> <nC> <name> <ConnBy> <last> <age>
- *
- * class Class the server is in
- * nS Number of servers reached via this link
- * nC Number of clients reached via this link
- * name Name of the server linked
- * ConnBy Who established this link
- * last Seconds since we got something from this link
- * age Seconds this link has been alive
- *
- * Additional comments etc...... -Cym-<cym@acrux.net>
- */
-
- case STAT_SERVER:
- if (acptr->serv->user)
- sendto_one(sptr, rpl_str(RPL_TRACESERVER), /* XXX DEAD */
- me.name, parv[0], conClass, link_s[i],
- link_u[i], name, (*acptr->serv->by) ? acptr->serv->by : "*",
- acptr->serv->user->username, acptr->serv->user->host,
- CurrentTime - acptr->lasttime,
- CurrentTime - acptr->serv->timestamp);
- else
- sendto_one(sptr, rpl_str(RPL_TRACESERVER), /* XXX DEAD */
- me.name, parv[0], conClass, link_s[i],
- link_u[i], name, (*acptr->serv->by) ? acptr->serv->by : "*", "*",
- me.name, CurrentTime - acptr->lasttime,
- CurrentTime - acptr->serv->timestamp);
- cnt++;
- break;
- default: /* We actually shouldn't come here, -msa */
- sendto_one(sptr, rpl_str(RPL_TRACENEWTYPE), me.name, parv[0], name); /* XXX DEAD */
- cnt++;
- break;
+ if (doall) {
+ for (cl = get_class_list(); cl; cl = cl->next) {
+ if (Links(cl) > 0)
+ send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl));
}
}
- /*
- * Add these lines to summarize the above which can get rather long
- * and messy when done remotely - Avalon
- */
- if (!IsAnOper(sptr) || !cnt)
- {
- if (!cnt)
- /* let the user have some idea that its at the end of the trace */
- sendto_one(sptr, rpl_str(RPL_TRACESERVER), /* XXX DEAD */
- me.name, parv[0], 0, link_s[me.fd],
- link_u[me.fd], "<No_match>", *(me.serv->by) ?
- me.serv->by : "*", "*", me.name, 0, 0);
- return 0;
- }
- for (cltmp = FirstClass(); doall && cltmp; cltmp = NextClass(cltmp))
- if (Links(cltmp) > 0)
- sendto_one(sptr, rpl_str(RPL_TRACECLASS), me.name, /* XXX DEAD */
- parv[0], ConClass(cltmp), Links(cltmp));
return 0;
}
-#endif /* 0 */
+
if (aconf)
free_conf(aconf);
fbclose(file);
- check_class();
nextping = nextconnect = CurrentTime;
return 1;
}
{
struct ConfItem** tmp = &GlobalConfList;
struct ConfItem* tmp2;
- struct ConfClass* cltmp;
struct Client* acptr;
struct MotdItem* temp;
int i;
conf_erase_motd_list(&motdConfList);
conf_erase_crule_list();
- /*
- * We don't delete the class table, rather mark all entries
- * for deletion. The table is cleaned up by check_class(). - avalon
- */
- for (cltmp = NextClass(FirstClass()); cltmp; cltmp = NextClass(cltmp))
- MarkDelete(cltmp);
-
/*
* delete the juped nicks list
*/
if (sig != 2)
flush_resolver_cache();
+ class_mark_delete();
mark_listeners_closing();
- if (!read_configuration_file()) /* This calls check_class(), */
- check_class(); /* unless it fails */
+ read_configuration_file();
close_listeners();
+ class_delete_marked(); /* unless it fails */
/*
* Flush out deleted I and P lines although still in use.
struct SLink *link;
struct Channel *chptr;
struct ConfItem *aconf;
- struct ConfClass *cltmp;
+ const struct ConnectionClass* cltmp;
struct Membership* member;
int lc = 0, /* local clients */
com += sizeof(struct ConfItem);
}
- for (cltmp = classes; cltmp; cltmp = cltmp->next)
+ for (cltmp = get_class_list(); cltmp; cltmp = cltmp->next)
cl++;
send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
com);
send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG, ":Classes %d(%zu)", cl,
- cl * sizeof(struct ConfClass));
+ cl * sizeof(struct ConnectionClass));
send_reply(cptr, SND_EXPLICIT | RPL_STATSDEBUG,
":Channels %d(%zu) Bans %d(%zu)", ch, chm, chb, chbm);
rm = cres_mem(cptr);
tot =
- totww + totch + totcl + com + cl * sizeof(struct ConfClass) + dbufs_allocated +
+ totww + totch + totcl + com + cl * sizeof(struct ConnectionClass) + dbufs_allocated +
rm;
tot += sizeof(void *) * HASHSIZE * 3;
* Evaluate rules for new user mode
* Stop users making themselves operators too easily:
*/
- if (!(setflags & FLAGS_OPER) && IsOper(sptr) && !IsServer(cptr))
- ClearOper(sptr);
- if (!(setflags & FLAGS_LOCOP) && IsLocOp(sptr) && !IsServer(cptr))
- ClearLocOp(sptr);
+ if (!IsServer(cptr)) {
+ if (!(setflags & FLAGS_OPER) && IsOper(sptr))
+ ClearOper(sptr);
+ if (!(setflags & FLAGS_LOCOP) && IsLocOp(sptr))
+ ClearLocOp(sptr);
+ /*
+ * new umode; servers can set it, local users cannot;
+ * prevents users from /kick'ing or /mode -o'ing
+ */
+ if (!(setflags & FLAGS_CHSERV))
+ ClearChannelService(sptr);
#ifdef WALLOPS_OPER_ONLY
- /*
- * only send wallops to opers
- */
- if (!IsAnOper(sptr) && !(setflags & FLAGS_WALLOP) && !IsServer(cptr))
- ClearWallops(sptr);
+ /*
+ * only send wallops to opers
+ */
+ if (!IsAnOper(sptr) && !(setflags & FLAGS_WALLOP))
+ ClearWallops(sptr);
#endif
- if ((setflags & (FLAGS_OPER | FLAGS_LOCOP)) && !IsAnOper(sptr) &&
- MyConnect(sptr))
- det_confs_butmask(sptr, CONF_CLIENT & ~CONF_OPS);
- /*
- * new umode; servers can set it, local users cannot;
- * prevents users from /kick'ing or /mode -o'ing
- */
- if (!(setflags & FLAGS_CHSERV) && !IsServer(cptr))
- ClearChannelService(sptr);
+ }
+ if (MyConnect(sptr)) {
+ if ((setflags & (FLAGS_OPER | FLAGS_LOCOP)) && !IsAnOper(sptr))
+ det_confs_butmask(sptr, CONF_CLIENT & ~CONF_OPS);
+
+ if (tmpmask != sptr->snomask)
+ set_snomask(sptr, tmpmask, SNO_SET);
+ if (sptr->snomask && snomask_given)
+ send_reply(sptr, RPL_SNOMASK, sptr->snomask, sptr->snomask);
+ }
/*
* Compare new flags with old flags and send string which
* will cause servers to update correctly.
++UserStats.inv_clients;
send_umode_out(cptr, sptr, setflags);
- if (MyConnect(sptr)) {
- if (tmpmask != sptr->snomask)
- set_snomask(sptr, tmpmask, SNO_SET);
- if (sptr->snomask && snomask_given)
- send_reply(sptr, RPL_SNOMASK, sptr->snomask, sptr->snomask);
- }
-
return 0;
}